Among the many great features introduced with HTML5 there are the new types added for the <input> elements: these are color, date, datetime-local, email, month, number, range, search, tel, time, url, week. If you're into web design you most certainly know how painful it was to properly support these types by adding drop-down lists, inline calendars and other client-side validation scripts to force the user to insert these kind of values: as of today most of the trouble is gone thanks to these new types, because the web browser will take care of that with a built-in set of good-looking (and standardized) controls.
Suprisingly enough, one of the most simple cases - the number type - still has some nasty issues if you need to use decimal values. According to W3C specifications, you need to also add the step attribute to support that. For example, if you want to support two decimal numbers, you can do the following:
1 |
<input type="number" step="0.01"> |
That's it, right? Sadly, it's not, unless you want to restrict your website audience to en-US (or to Mozilla Firefox) users only. That's because the input type="number" with decimal steps is only supported with the dot separator in most browsers: the sole exception comes from Mozilla Firefox, which allows commas to be used if the HTML5 is properly localized - for example, using
<body lang="it">.
Here's the current status of this issue (by browser type), as shown in this GitHub thread:
Input | Firefox | Chrome | IE | Edge | Safari |
---|---|---|---|---|---|
123 | ✔ | ✔ | ✔ | ✔ | ✔ |
123.45 (with . region) |
✔ | ✔ | ✔ | ✔ | ✔ |
123,45 (with . region) |
✔ | ||||
123.45 (with , region) |
✔ | ||||
123,45 (with , region) |
✔ | ✔ | ✔ | ✔ | ✔ |
123,456.78 | ✔ | ||||
123.456,78 | ✔ | ||||
10e-1 | ✔ | ✔ | ✔ | ✔ | ✔ |
This cripples the
<input type="number">to the point that it cannot be used anytime we need to support an international and/or multilanguage scenario. Whenever you need to do that, the best thing you can do is to revert to a simple
<input type="text">and validate the user input using JavaScript.
Here's a decent script you can use, which is loosely based from this StackOverflow thread:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// client-side validation of numeric inputs, optionally replacing separator sign(s). $("input.number").on("keydown", function (e) { // allow function keys and decimal separators if ( // backspace, delete, tab, escape, enter, comma and . $.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 188, 190]) !== -1 || // Ctrl/cmd+A, Ctrl/cmd+C, Ctrl/cmd+X ($.inArray(e.keyCode, [65, 67, 88]) !== -1 && (e.ctrlKey === true || e.metaKey === true)) || // home, end, left, right (e.keyCode >= 35 && e.keyCode <= 39)) { /* // optional: replace commas with dots in real-time (for en-US locals) if (e.keyCode === 188) { e.preventDefault(); $(this).val($(this).val() + "."); } // optional: replace decimal points (num pad) and dots with commas in real-time (for EU locals) if (e.keyCode === 110 || e.keyCode === 190) { e.preventDefault(); $(this).val($(this).val() + ","); } */ return; } // block any non-number if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { e.preventDefault(); } }); |
Place it at the end of your HTML code (or inside a
$(function() {})call), then assign the number class to any input you want to validate this way. If you want, you can also uncomment the optional lines to replace commas with dots (or vice versa).
UPDATE: I created a JSFiddle with the above code if you want to test it online.
That's it for now: happy coding!