There are lots of questions like this on StackOverflow, but none of them captures all of my requirements in the same solution. Any help appreciated.
The problem
In my React app, I need a text box with the following characteristics:
- It only allows digits to be entered - no minus signs, decimal places, letters, or anything besides just the digits 0-9.
- It automatically brings up the number keypad on iOS and Android
- I can further restrict the numbers that should be entered, e.g. only allow 4 digits
- Leading zeroes are automatically trimmed, e.g. if a user types 02 it should correct to just 2
- It allows an empty textbox, and can differentiate between empty and a value of 0
Current code
https://codepen.io/micahrl/pen/RwGeLmo
This code allows typing non-digits, and will just interpret the value as NaN. For instance, the user can type 2f
or asdf
and the page will say You typed: NaN
.
Additionally, while the page loads initially with an empty text box, the user cannot type something and then delete it back to empty. Attempting to delete all text in the input box places a 0
in the box.
Finally, this code doesn't reliably trim leading zeroes, which causes me particular problems because I want to restrict the number to four digits. Typing 01
will not truncate the leading zero; on some browsers, typing 01111
will result in 1111
, which is good enough, while on others, typing 01111
will result in 0111
, which is a problem.
What I've tried
Because I have set type="number"
on the input element, if there is ever a non-number added to the text box, event.target.value
in setNumWrapper
will be an empty string. This means I can't differentiate between a true empty string (where the user has deleted all text) and invalid input (where the user has typed a non-number, like asdf
).
I could set type="text"
on the input element, except that I think I need to set it to number
to get the number keypad on mobile OSes like iOS and Android.