Angular.js: input validation error with type number and IE

Created on 5 Feb 2015  路  16Comments  路  Source: angular/angular.js

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

Known Issue IE11 forms broken expected use bug

Most helpful comment

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 :)

All 16 comments

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

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.

I'm using IE 11 :(

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

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.

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.

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...)

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

This sounds like the same issue as this: https://github.com/angular/angular.js/issues/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.

@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.

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

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.

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.

Is there any workaround? Will adding ngPattern validation work?

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 :)

This issue is still open, bbortt

Was this page helpful?
0 / 5 - 0 ratings