The goal: To find a cross-platform solution for displaying numeric keyboards on mobile touch-based devices, with a minimum of hacks.
The problem:
I have a regular web application using data input forms, containing primarily numeric data. When a user interacts with my site on a mobile device, I would like to display a numeric virtual keypad as most standard keyboards require a second press to switch from alphas to numbers. I know that i can trigger different keyboard by setting the "type" attribute of input element:
type=number
:
This works great under iOS/Safari. I am unsure about other browsers on the platform.
On Android, this does not consistently raise the correct keyboard on various browsers and often results in unwanted elevator buttons on the input. I have yet to find a clean way to turn these off in CSS.
type=tel
:
This almost works on iOS/Safari, but the telephone keyboard lacks a decimal button.
Seems to work great across multiple android browsers, without any extraneous UI elements added to the page.
My current solution is hacky and simplistic. Based on a class that I'm already using for numeric validation, I replace each text element that should contain a number with a new input that is either a number
or a tel
type based on the detected OS/browser.
var isAndroid = navigator.userAgent.match(/android/i) ? true : false;
var isIOS = navigator.userAgent.match(/(ipod|ipad|iphone)/i) ? true : false;
if (isAndroid || isIOS) {
var useNumberType = (isIOS ? true : false); //iOS uses type=number, everyone else uses type=tel
jQuery("input.num").each(function () {
var type = (useNumberType ? "number" : "tel");
var html = this.outerHTML;
html = html.replace(/(type=\"?)text(\"?)/, "$1" + type + "$2");
this.outerHTML = html;
});
}
I would prefer to not use browser detection and to not change out the inputs on the fly at run time. I could possibly introduce an http module on the server side that did basically the same thing, but that is not substantially better. I'm shocked that there isn't a CSS call for this.
Is there a better way to get a numeric keyboard with a decimal button, that works on all or most touch-based mobile devices without adding weird UI elements to the page?
-------------- update
I don't think there is a way to do what I really want to do, which is to setup a single input style or type that will work well across desktop browsers and all major mobile touch-based platforms. I settled on changing the type of the input through a direct DOM call rather through jQuery instead of rewriting the entire input via outerHTML. I suspect there isn't much difference in effect, but the code is a little cleaner. Since I'm not changing input types on the desktop, I shouldn't have to worry about IE's read only restriction on the attribute.
Ideally, I'd probably handle this on the server side so everything got sent to the browser in the format desired for the device making the request. But for now the new code looks more like this:
var isAndroid = navigator.userAgent.match(/android/i) || navigator.platform.match(/android/i) ? true : false;
var isIOS = navigator.userAgent.match(/(ipod|ipad|iphone)/i) ? true : false;
if (isAndroid || isIOS) {
var useNumberType = (isIOS ? true : false); //iOS uses type=number, everyone else uses type=tel
jQuery("input.num").each(function () {
var type = (useNumberType ? "number" : "tel");
if (this.type == "text") {
this.type = type;
}
});
}