Thomas Fuchs
Hi, I'm Thomas Fuchs. I'm the author of Zepto.js, of script.aculo.us, and I'm a Ruby on Rails core alumnus. With Amy Hoy I'm building cheerful software, like Noko Time Tracking and Every Time Zone and write books like Retinafy.me.
   Want me to speak at your conference? Contact me!

Handling numerical input in mobile web apps or “A sad tale of two keyboards”

August 30th, 2013

“[These phones] have these keyboards that are there whether or not you need them to be there. And they all have these control buttons that are fixed in plastic and are the same for every application. Well, every application wants a slightly different user interface, a slightly optimized set of buttons, just for it.”
—Steve Jobs, iPhone introduction Keynote, January 9, 2007

I agree with Steve Jobs. However, the state of keyboard customization in mobile web apps is sad.

For our new mobile web app for Freckle Time Tracking I’m looking into ways to have the least possible amount of taps for the user to enter her time. In order to that, I want to tell HTML input fields which keyboard to open. Sounds simple? Read on.

The iPhone and Android phones support various keyboards, among them keyboards specialized in entering text (the “default” keyboard), entering numbers (a keypad with some extra buttons like a comma and a decimal separator) and a phone keypad (which has stuff like “ABC” on the 1 key and a # key).

Now what I’d really like to do is show the user the keyboard that is part of the default keyboard but shows up when you hit the “123” key—a horizontal row of numerical keys like on a real hardware keyboard. The reason for this is that people in Freckle should be able to enter stuff like “15m” for 15 minutes of time, just like they’re used from the “desktop” web version.

Let’s have a look at the available ways to select which keyboard should be shown:

The type attribute

The type attribute can be set to “number” to allow numerical input. (I won’t go into the “tel” type).

image1

Now this actually works nicely on iPhone because I get the default keyboard, but it’s already switched to the screen that you get when you press the “123” key. The best thing is that users can switch back to the QWERTY part and can freely enter whatever they want. That’s exactly what I need because I want the keyboard to emphasize numerical input and expect it as default, but allow other things as well—that is until you try to set the content via JavaScript. If you try to set the value of a type="number" input field to something like “2:00”, no dice. The value is (silently!) not set. Note that adding a novalidate attribute doesn’t change this either.

On Android, it’s yet a different story—I get a specialized keypad with numbers only (and a few special characters). Unfortunately, that doesn’t work for my use case as the user can’t switch from the specialized keypad to the default keyboard.

The pattern attribute

According to Apple’s documentation, setting the pattern attribute to [0-9]* or \d* is “equivalent to using type=number”. Except that these are dirty lies, it actually does something very different—show just a numeric keypad without the possibility of changing back to the default text entry keyboard.

Image2

There’s a second problem, perhaps even more serious—there is no API to either know if there is a keyboard displayed currently nor to determine the visible viewport of the mobile web page (the visible content area of the mobile browser minus any space taken up by any keyboard shown). This prevents me from adding my own row of keys that could provide the extra functionality I need (notwithstanding complex issues with browsers losing input field focus when tapping these keys; this can be worked around).

Additionally, the Safari HTML Reference documentation was last updated about two years ago in 2011 and still sports screenshots from the original iPhone. It’s overdue for an update.

Alas, I can’t make this work correctly on either iOS or Android, and will have to default to the normal keyboard and perhaps try to add some of my own buttons, guesstimating the keyboard size and position.

Why is this so hard? Why can’t we have nice things? Mobile web apps seem to be treated as a second-class citizen by both Apple and Google. All I want is to make the user have to work less and be able to use my web app quicker—and be more awesome.

Dear Apple and Google: please allow me to do that.