Open Bug 1398528 Opened 7 years ago Updated 3 months ago

HTML <input type=number> should not allow users to type in characters that are not part of a number

Categories

(Core :: DOM: Core & HTML, defect, P3)

57 Branch
defect

Tracking

()

Tracking Status
firefox57 --- wontfix

People

(Reporter: isurunix, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: dev-doc-needed)

Attachments

(1 file)

Attached image ff-bug.png
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
Build ID: 20170909100226

Steps to reproduce:

1. Go to w3schools HTML5 number input type test page (https://www.w3schools.com/html/tryit.asp?filename=tryhtml_input_number)
2. Type in a letter in the input field instead of a number


Actual results:

Input field accepts non numeric characters


Expected results:

Input field with type 'number' should not accept non numeric values
OS: Unspecified → Linux
Hardware: Unspecified → x86_64
Component: Untriaged → Layout: Form Controls
Product: Firefox → Core
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0

confirming using MDN docs  https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number

Seems like a valid bug for me per spec:
"User agents must not allow the user to set the value to a non-empty string that is not a valid floating-point number."
https://html.spec.whatwg.org/multipage/input.html#number-state-(type%3Dnumber)

Google Chrome works as expected (ignores typing letters)
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Linux → All
Hardware: x86_64 → All
Summary: HTML5 input type number is not working → HTML5 input type number is not working (should ignore typing letters)
jwatt: can you take a quick look here? It seems we correctly set the control state to indicate bad input, but we don't do that until after a user gesture (e.g., arrow or enter key) forces validation. After the first validation happens, we indicate bad input for any key pressed while the control is in focus.
Flags: needinfo?(jwatt)
Priority: -- → P3
(In reply to j.j. from comment #1)
> Seems like a valid bug for me per spec:
> "User agents must not allow the user to set the value to a non-empty string
> that is not a valid floating-point number."

You're reading too much into the spec text. The specification (and WHATWG/W3C specification is general) do not dictate UI/UX. When the spec says that the value cannot be set to a non-numeric value, it is referring to the internal value of the control, not its visual appearance.

Note that different implementations behave in different ways, with different trade-offs.

We behave in the way Jet describes in comment 2.

Safari behaves similarly to Firefox, but doesn't even indicate that the input is invalid.

IE behaves similarly to Firefox, but clears the control without explanation if the input is invalid.

And Chrome, as you say, ignores non-numeric characters...in general. It does not ignore ".", "," and "e", so it is possible to type in input like "e.,", in which case Chrome gives no indication that the input is invalid.
Flags: needinfo?(jwatt)
We could probably add some input character blocking, but we would need to be more clever about it that simply blocking the exponent character, decimal and thousands separators that are used in English. We would need to query ICUUtils to check if each input character is a local specific digit, separator or exponent character. (In fact it's actually more complicated than that since we try to implement heuristics to recognize if input is valid in the browser local, OS local or site local, which can all be different.)

It's not clear to me that it's a good idea to implement character blocking though. Waiting until the user has typed their input and then flagging it as invalid with the tooltip message "Please input a number" seems reasonable to me, and if I recall correctly is what shorlander suggested.

If anyone thinks we should implement some sort of character blocking I suggest you get shorlander involved to get UX to decide what our behavior should be.
This is not a regression, BTW (I can reproduce in a Firefox 54 nightly build, for example).  So, this doesn't meet the urgency threshold for 57 --> setting status for that release to wontfix.
Summary: HTML5 input type number is not working (should ignore typing letters) → HTML <input type=number> should not allow users to type in characters that are not part of a number
Blocks: 1437641
Adding dev-doc-needed, as any further action here may affect what we say in the docs for <input type="number">
Keywords: dev-doc-needed
No longer blocks: 1437641
See Also: → 1437641

(In reply to Jonathan Watt [:jwatt] from comment #4)

We could probably add some input character blocking, but we would need to be
more clever about it that simply blocking the exponent character, decimal
and thousands separators that are used in English. We would need to query
ICUUtils to check if each input character is a local specific digit,
separator or exponent character. (In fact it's actually more complicated
than that since we try to implement heuristics to recognize if input is
valid in the browser local, OS local or site local, which can all be
different.)

Hi, Jonathan.
I understand it is not easy. But for making a custom validation routine it is neccesary to know WHAT the user did wrong. If the value of the input is deleted as soon as the user inputs a wrong value I cannot find out what went wrong.

It's not clear to me that it's a good idea to implement character blocking
though. Waiting until the user has typed their input and then flagging it as
invalid with the tooltip message "Please input a number" seems reasonable to
me, and if I recall correctly is what shorlander suggested.

This is what I was afraid of. This means AFAICS that it will be very hard (if not impossible) to create a custom validation when we use a number input. No innovation in design, just the standard, browser delivered validation. Please tell me if I'm wrong on this.

If anyone thinks we should implement some sort of character blocking I
suggest you get shorlander involved to get UX to decide what our behavior
should be.

I do not know who 'shorlander' is. But I do know that this is a major issue which causes me ATM to scrap the number input alltogether.

But perhaps I'm missing something, maybe someone can shed a light on this and can tell me how I can read the value back after Firefox deleted it.

So if someone can inform me how I can get the value of, say 13.87 on keyup I can resolve this issue. (The dot is not allowed in the Netherlands as decimal separation so the whole value is immediately deleted because of this. BUT some people here input numbers with a dot as decimal separation. Conundrum.)

Thanks for your time.

I solved it in another way.

I captured the input on keypress, as well as the last key that was pressed. Then on keyup I check if the value is empty on keyup. If so, I checked if the last key was a dot or a comma and created a respective error so the user can take appropriate action.

Kind regards,
Jan-Paul Kleijn

Correction, I captured the input on keyDOWN instead of keyPRESS. Keypress does not register backspace or delete.

Kind regards,
Jan-Paul Kleijn

See Also: → 1578181
See Also: 1578181
Component: Layout: Form Controls → DOM: Core & HTML

Hi,
I think this issue should be resolved as soon as possible.
Right now we're still forced to code javascript events to ensure that the user do not enter a "not number" character sequence, and this behaviour even invalidates the existence of an input[type=number].
Chrome and Edge works correctly.

At a bare minimum, Firefox should ignore leading and trailing white space. Firefox will mark a number with a leading or trailing space as invalid, which would be confusing if the user copied and pasted a number and didn't notice the white space.

Could we not simply make a bare bones implementation where it sets the :invalid/:error pseudoselectors as active and prevents all that isn't numbers, full stops and commas?

Problem with current implementation is one can't tell the difference between blank and invalid input. At the moment if the user types "111111" then "a", then value changes from "111111" to "". If you have "float labels" the text overlaps because the label now things the input is empty. I don't think "" should mean invalid, because we can't tell if its invalid text or blank.

There are ways to tell whether it's empty vs. invalid (such as checking input.validity.valid, or input.matches(":invalid").

Severity: normal → S3

If this isn't going to be fixed, then the MDN docs here need to be updated to show that FireFox isn't supported. I have submitted a request to have this changed.

I can see that the value that is a float must not match the displayed value per spec.
My personal opinion on the matter: The problem rather is that the current implementation even though right is just not practical. The majority of users expect a type="number" input to only accept valid numbers and delimiters. Only a minority will be ok with the current implementation. Most will have to implement the wanted behavior manually every time.
We are building a web component library and just our own experience showed that neither our users nor our developers expected the input to accept for example alphabetic input. Also none of our components that were input type=number needed to accept alphabetic values. I can personally barely see a use case for the current behavior and other browsers feel more intuitive in that regard.

This being just my personal opinion and experience. Is there any discussion currently going on to change this behavior?
If not I think that my team will have to provide some monkeypatch if there is none already. In case this behavior is up for discussion maybe we can help with that as well.

(In reply to thecodemonk from comment #34)

If this isn't going to be fixed, then the MDN docs here need to be updated to show that FireFox isn't supported. I have submitted a request to have this changed.

(This request seems to have been https://github.com/mdn/browser-compat-data/issues/18050 which was closed no-change, essentially for reasons described above in comment 3.)

(In reply to chrissigrilus from comment #35)

I can personally barely see a use case for the current behavior

The current permissive behavior isn't really a "use-case"; it's more that the space-of-use-cases is sparsely distributed around lots of invalid input. If we were to add validity checking to attempt to prevent invalid input from being typed, then it's likely our validity-checking will be incomplete, or will prevent valid input from some locale, or both.

Put another way: we're in the situation we are right now because proper user-typing-restrictions here are unspecified and would be quite complex to design and implement robustly, especially in light of variation between locales in number formatting.

See comment 4 and https://learn.microsoft.com/en-us/globalization/locale/number-formatting for simple examples of the complexity here, for folks unfamiliar with internationalized number formatting differences, plus https://unicode.org/reports/tr35/tr35-numbers.html#23-number-symbols

other browsers feel more intuitive in that regard.

From some brief testing on my end to check the state-of-things in other browsers, I found:
(1) WebKit/Safari continues to allow users to type arbitrary text into input type=number fields (similar to Firefox). e.g. I can just type "banana" into an <input type="number"> field there. Are you seeing something different?

(2) Chromium has some character-blocking restrictions (e.g. I can't type "banana"), but they seem fairly incomplete and also possibly over-reaching (though maybe the overreach is just locale-specific strictness).

  • RE incompleteness: Chrome allow the letter e, as well as -+ or +-. They let me type ++, +-, 1+2-7, ++e, but not e++ and not 1+2-7+5. I suspect this is all a way of allowing expressions like -5e+10, but of course it allows a variety of bogus input to be typed, as noted above. They also have some input-blocking rules around the period character, . -- e.g. .3 is allowed, and so is .++ and .e, but e. is forbidden.
  • RE possible-overreach: Chrome on my machine seems to forbid the comma character , entirely in number fields, despite that being the proper decimal separator for German users. (Maybe German-localized Chrome allows that and forbids the period character instead? I'm not sure.)

If not I think that my team will have to provide some monkeypatch if there is none already. In case this behavior is up for discussion maybe we can help with that as well.

Can you elaborate on what you're having to handle, and what part of it is Firefox-specific (and isn't also-needed-for-WebKit)? (Do you also need to exclude e.g. bogus non-numeric values like e, ., -, or -+.e that users can type in Chromium)?

Also: note that the required flag might help you here.[1] That triggers client-side validation to be sure that the browser has actually been able to parse a number from what you provided, according to your locale. (Though obviously if you don't want to strictly require a value to be entered into your number field, then required won't be the tool that you want to reach for.)

[1] e.g. if I load data:text/html,<form><input type="number" required><input type="submit"> and type in "abc" and press submit, I get a prompt telling me that I need to enter a number into that field.

IMO, this is a poor user experience. I spent a bit of time trying to come up with a workaround, and the best I could do was a keydown event handler that screened out input apart from numbers, decimal points and control characters.

But one thing I could not handle was multiple decimal points. If you type "0.." then the value is simply "". I'd ideally like to have this control behave like it does in Chrome, which is to only allow numeric input, but this doesn't seem to be possible.

The Chrome behavior is exactly what I'd expect.

(In reply to scott.schafer from comment #37)

the best I could do was a keydown event handler that screened out input apart from numbers, decimal points and control characters.

That sort of thing might be the best practice here for the time being, combined with submit-time validation-checking (either by using the required attribute to pop up a browser tooltip and block form-submission, or by your own validation, e.g. checking for empty value.

But one thing I could not handle was multiple decimal points. If you type "0.." then the value is simply "". I'd ideally like to have this control behave like it does in Chrome [...]The Chrome behavior is exactly what I'd expect.

Be aware, Chrome does seem to prevent users from typing 0.., but they allow lots of other similar things that also produce a value of "". See the examples in comment 36 (stuff like .e and 1+2-7 and +-).

See Also: → 1851408
Duplicate of this bug: 1851408
See Also: 1851408
Duplicate of this bug: 1867746
You need to log in before you can comment on or make changes to this bug.