Last time I tested what a number input accepts. A reader asked for a cleaner split: what happens when the value is typed, versus set from script? This is that test, in one browser.
Setup: Chrome 155, a plain <input type="number" step="any">. "Typed" means per-character key events sent by a browser automation tool, which is not the same as a person on a keyboard. "Set" means input.value = "..." from script. For each case I read four properties: value, valueAsNumber, validity.badInput and checkValidity().
| String | Typed | Set from script |
|---|---|---|
1e3 |
"1e3", 1000, badInput false, valid | same |
.5 |
".5", 0.5, false, valid | same |
abc |
"", null, false, valid | same |
1e |
"", null, badInput true, invalid | "", null, false, valid |
- |
"", null, true, invalid | "", null, false, valid |
1e400 |
"", null, true, invalid | "", null, false, valid |
1,5 |
"15", 15, false, valid | "", null, false, valid |
+5 |
"5", 5, false, valid | "", null, false, valid |
5. |
"5", 5, false, valid | "", null, false, valid |
0x10 |
"010", 10, false, valid | "", null, false, valid |
What stands out
An empty value can mean two things. Typed 1e and set 1e both leave value as an empty string. Only the typed one sets badInput and fails checkValidity(). If your code only checks value === "", it cannot tell "the user typed nothing" from "the user typed something the control could not parse".
Setting from script skips the typing filter. When keys are typed, the browser dropped the comma in 1,5 and the x in 0x10, so the field ended up holding 15 and 010. A scripted value just rejects the whole string. A test that sets values from script will not show you what a typist ends up with.
Typed abc was valid and empty. The letters never entered the field, so there was nothing to flag.
What I would do with this
- Check
validity.badInputas well asvaluewhen you need to tell empty from unparseable. - If you write tests, type the input through your test runner instead of assigning
value, at least for the cases you care about. - Keep the control's parsing separate from your own business rule.
1e3is a valid number to the control, and you may not want it in an order quantity field.
Not tested
Firefox and Safari, mobile keyboards, real human typing, pasted text, and locale settings. The typed column comes from automation key events, so treat it as a lead to check in your own browsers.
Related: the first test, What an input type=number really accepts.
Top comments (0)