Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best settings for HTML <input type="number">, for mobile devices

I've been reading many other questions, like these[1][2][3] for example, but the problem still persists.

I need to find the "cleanest" way to have a HTML input for mobile devices and which respects all these three rules:

  1. suitable mainly for numbers, integer or float

  2. shows the numeric keypad on mobile devices, on Chrome for Android and Safari for iOS, with no strange extra keys

    enter image description here

  3. fully respects the HTML5 rules, tested by W3C validator


What have I tried?

I've been across these solutions, which neither of them cumulatively respect those three above rules.

Solution 1

<input type="text" pattern="\d*" />

enter image description here

This solution despite working in iOS and fulfilling HTML rules tested by W3C validator, presents in Chrome Android the full keypad with the QWERTY keyboard.

Solution 2

<input type="number" pattern="\d*" />

This solution works on both systems iOS and Android Chrome, showing the number keypad on both systems, but it throws an HTML validation error with W3C validator:

Attribute pattern is only allowed when the input type is email, password, search, tel, text, or url.

Solution 3

<input type="number" />

This solution passes the W3C HTML test, it shows nice on Chrome, but on iOS keypad it presents several unwanted keys

enter image description here

Solution 4

I see many developers using this solution

<input type="tel" />

But in Android Chrome it doesn't allow dot symbols . (thus no floats), and the keys have letters, which is superfluous

chrome input type="tel"

like image 508
João Pimentel Ferreira Avatar asked Aug 02 '18 19:08

João Pimentel Ferreira


4 Answers

For your specific task I have the extraordinary solution: we take the best solution with type="text" and pattern and then add the JavaScript which corrects the type attribute. We do it to pass through W3 validator.

The solution

// iOS detection from: stackoverflow.com/a/9039885 with explanation about MSStream
if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
{
    var inputs = document.querySelectorAll('input[type="number"]');
    for(var i = inputs.length; i--;)
        inputs[i].setAttribute('pattern', '\\d*');
}
<input type="number" />

My solution respects all your three rules (W3 validator inclusive).

But I have to mention that in this case(with pattern) on iOS we do not have the possibility to put float numbers with numeric keypad because on iOS we do not have any keypad with numbers including points. On Android we have this possibility. If you want to have numeric keypad with float numbers then you have to write for iOS extra solution like follows:

 <input type="number" />
like image 118
Bharata Avatar answered Nov 03 '22 14:11

Bharata


There is yet another option: <input type="text" inputmode="numeric" pattern="[0-9]*">

Why the GOV.UK Design System team changed the input type for numbers is definitely worth a read.

Note that if you still want to go the <input type="number"> route there is a nice solution to point 4 - Scrolling - Turn Off Number Input Spinners.

Each solution seems to have some drawbacks and I think the best fit will depend on the type of data you're trying to collect, passport number vs someone's age vs number of items.

The drawbacks to this solution that I have found are:

  • the input value is now text rather than a number so you may need to do additional parsing in JS.
  • on desktop browsers the input will accept alphabetical characters, the form will be invalid but you'll need to handle this and show relevant user feedback (might be automatic if using a framework)
  • it's only supported by modern mobile browsers, e.g. Safari on iOS 12.2 (2019 ish) (see spec)
like image 3
Simon Ness Avatar answered Nov 03 '22 12:11

Simon Ness


As mentioned in the comments, because there is no straight forward way to accomplish this, the best work around is to always use an input type="number" with an if statement that if the device is an iOS device then the code will add the proper pattern attribute to the type.

like image 1
James Avatar answered Nov 03 '22 14:11

James


I came across this problem and the following two solutions seem to be the best ways to answer this question

The first solution is very simple and works on both Android and IOS. This solution will have a up and down button on desktop and only a numeric keyboard on both Android and IOS;

<form action="" method="">
<input pattern="[0-9]*"/>
</form>

The only issue with this solution is that, a user will not be able to enter , (commas) or . (periods), since they will not show up on the keyboard. If you alter the pattern, the above will no longer function on IOS.

The second solution is not supported by all browsers, however seems to work on all modern browsers including safari 15.1.

<input inputmode="numeric" pattern="[0-9]*" type="text"/>

To see what browsers support inputmode click here

Good Luck

like image 1
Web Dev Avatar answered Nov 03 '22 12:11

Web Dev