Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

input validation error with type number and IE #10981

Open
SlippySken opened this issue Feb 5, 2015 · 16 comments
Open

input validation error with type number and IE #10981

SlippySken opened this issue Feb 5, 2015 · 16 comments

Comments

@SlippySken
Copy link

Hello there,

I have a problem with an input field, which only should accept numbers. In FF and Chrome everything is fine, but with IE something is wrong.
If I enter '123asd' an error message appears. But if I enter 'asd123' no error message appears.
Here a plnkr :).

http://plnkr.co/edit/9qsIf2mGnkbFIJ8bb0MW?p=preview

@matsko
Copy link
Contributor

matsko commented Feb 5, 2015

Which version(s) of IE is this problem showing up on?

@matsko
Copy link
Contributor

matsko commented Feb 5, 2015

Older versions of IE don't have support for things like type="number": http://caniuse.com/#feat=form-validation

This should however be emulated properly in Angular if this is the case.

@SlippySken
Copy link
Author

I'm using IE 11 :(

@matsko
Copy link
Contributor

matsko commented Feb 5, 2015

This is definitely an issue. @petebacondarwin @caitp @Narretz @shahata can one of you look into this please?

@petebacondarwin
Copy link
Contributor

The problem is down to the way that IE parses the value of number input boxes. I think that it is naively using parseFloat or maybe parseInt. These methods have the following annoying behaviour:

parseFloat('30', 10)
30
parseFloat('30a', 10)
30
parseFloat('a30', 10)
NaN

I reckon that IE just parses the number and assigns the empty string to the value if it gets NaN.

So if the value of the text input goes from an empty string to a string that starts with a non-number then IE doesn't trigger a change event, since as far as it is concerned the value has not changed (it was empty before and is empty now).

Ironically, because of the way it is parsing for a number, if the value of the input starts with a number followed by letters, then IE does think that it is a number.

@petebacondarwin
Copy link
Contributor

Actually, let me qualify this a bit further. The "value sanitization" rules I described above are actually part of the spec and it is what is implemented by most modern browsers, including IE and Chrome.

It seems that the real problem is that IE is not triggering an ngModel update in the case described above. In Chrome we get a "input" event occurring even though the element value is still empty.

@petebacondarwin
Copy link
Contributor

It gets more complicated!

So for one reason or another, we don't listen to the "input" event in IE<=11. What we do listen to instead is the "keydown" event. This does get triggered but unlike the handler for "input", which just calls the listener function directly, the handler for "keydown" calls deferListener which has an additional check of whether the input element has changed or not. If not then we don't actually call listener at all.

Hmm. So either we need to work out whether we can listen to input for IE11, or we remove the check of whether the value has changed, or we find some other way (perhaps by running validation, whether or not the input element value has changed...)

@petebacondarwin
Copy link
Contributor

I think we need the deferListener to cope with async updates to the value that are triggered by a keydown.

@Narretz
Copy link
Contributor

Narretz commented Feb 6, 2015

This sounds like the same issue as this: #7070, although @caitp came to a different conclusion as it seems.

The problem is not a missing input event, but that IE does not set badInput correctly.

IE 11:
0a: input value is 0a, badInput is undefined
a0: input valie is '', badInput is undefined

Firefox:
0a: input value is '', badInput is true
a0: input value is '', badInput is true

So in the case of 0a our secondary mechanism of checking number validity works, but with a0, we have no way of checking the validity because no value is reported and badInput isn't set.

@petebacondarwin
Copy link
Contributor

@Narretz - thanks for that link. Yes I think @caitp is right here that badInput is not set correctly in IE.

Here is a plunker to see what events are happening: http://plnkr.co/edit/el58Dle0EGR2U2mbGWuN?p=preview

But even if this were fixed, we would not get to the badInputChecker $parser in IE since, in deferListener we are checking the value of the element against its previous value before running the listener.

You can see this is the case if you consider these two ways of getting to "asd123":

  • Clear the input (valid but empty); then type asd123 - At no point does the before parser run as the value never changes from empty
  • Enter 123 (valid); then move to the start of the input and type asd (invalid) - Now the before parser does run because the input value changed from 123 to empty.

@petebacondarwin
Copy link
Contributor

I agree with putting in the IceBox until the IE11 bug is fixed. Does this happen with IE12?

@Narretz
Copy link
Contributor

Narretz commented Feb 8, 2015

I think you need Windows 10 to test IE12, so I cannot say. The issue is still open on connect.microsoft: https://connect.microsoft.com/IE/feedback/details/850187/html5-constraint-validation-is-broken-in-ie11-for-input-type-number

Should we close the other issue? This here has more info.

@Narretz
Copy link
Contributor

Narretz commented Feb 10, 2015

I got my hand ony Windows 10 + IE 11 and this is still broken in the normal IE (Trident) engine, but it works with the new EdgeHTML engine which is default in the new Spartan browser. I'm not sure if IE12 will have EdgeHtml as standard engine when released.

@zendu
Copy link

zendu commented Dec 21, 2017

Is there any workaround? Will adding ngPattern validation work?

@bbortt
Copy link

bbortt commented Feb 19, 2018

Although this issue is already closed..

@zendu ngPattern validation would work but has not the very same behaviour. You could still input alphabetic characters but the validation would fail. I personally used a (change) listener and dropped the event if the given input didn't match ^\d{0,}$ which equals any integer. Adapt the regex to match any floating values. Might not be the very best solution but works :)

@chce
Copy link

chce commented Aug 7, 2018

This issue is still open, bbortt

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants