1234.56 vs 1234,56
While working at Just Eat Takeaway.com developing a multilingual, multi-currency, multi-whatever-you-want app we released our first version to be used in a local restaurant in the Netherlands.
A couple of days later our product owner from the Netherlands contacted our product manager in Israel and told him that he used the catalog feature on our app and couldn’t enter the comma (,) character in the price field.
The decimal separator is a period (.), not a comma, well, at least I thought so.
My journey to numbers-localization and cross-browser support begins.
Browsers define localization differently.
“Localization is the process of adapting internationalized software for a specific region or language by translating text and adding locale-specific components”
Each browser adds a shadow-dom element to the input and displays the text. Then it manipulates the value and saves it under “valueAsNumer” and “value” properties.
If we enter “1–8” for example or any invalid number, the browser will update the shadow-dom element with the value but will not update the “value/valueAsNumber” properties until we don't enter a valid number.
How does the browser define the locale?
- Chrome - by the browser’s language.
- Firefox - by the “lang” attribute.
<input type=”number” step="0.01" lang="nl"/>
Our product-owner used Chrome set to English so his locale was EN and not NL, so he couldn’t enter a comma as a decimal separator.
But there are more differences between the browsers:
- Visual differences: Height of the input, border-radius, visibility of the increase/decrease arrows, different focus design.
- Behavior differences: In Chrome, you can’t enter non-numeric characters but in FF you can. In Chrome the validation happens after the form submission, but in FF it is immediate.
The visual differences can be easily solved using CSS-reset.
The behavior differences are more complicated:
- Why can I enter a dot but not a comma?
- Why can I enter the minus sign wherever I want in the number?
- Why do I need to specify the “step” attribute to enter a decimal value?
What about mobile browsers?
Mobile browsers are a whole different story because we don’t have a physical keyboard but only an on-screen keyboard — what is the difference, you ask?
Every key on our physical keyboard is mapped to a key-code, the numbers 0–9 mapped to key-codes 48–57 respectively, Latin letters are 65–90, etc…
Knowing that we can check whether the value is a numeric value, including special characters as the minus sign or decimal separator, and restrict everything else, right? NOPE! In mobile keyboards, all of the keys are mapped to 0 or 8 or some other values (depends on the keyboard) so what can we do?
Keyboards layouts to the rescue!
Every keyboard can have a different layout depending on its purpose:
Entering a phone number, a date or a URL are just some examples of different layouts that make our experience better.
Adding the “inputmode” attribute
<input step="0.01" inputmode="decimal"/>
will open a numeric keyboard with the decimal separator — so the user can’t enter non-numeric characters.
- Provide a unified solution for localization.
- Allow decimals, negatives, action keys, and numeric values.
- Restrict every non-numeric character.
- Preserve the native HTML input validation.
- Support numeric layout for mobile.
Am I as a web-developer need to take all of these things into consideration every time I write a numeric-input field?
Well, yes, but I can make your life a little bit easier with my
custom numeric input directive:
The solution is vanilla, but the library is built with Angular.
Sync browsers’ behavior and localization on numeric inputs. Install with NPM: npm i @ng-dl/numeric-input Override…
PRs and feature requests are welcome!
Thank you for reading my first article!
Hope you liked it!
Feel free to leave feedback or questions in the comments.