-
Notifications
You must be signed in to change notification settings - Fork 27.5k
IE10 fires input event when a placeholder is defined so that form element is in dirty instead of pristine state #2614
Comments
This fix works, but is far from good. Is this a browser bug, or a Angular/jQuery bug? |
Can be reproduced: http://jsfiddle.net/eY62X/1/ |
👍 |
Looks like it's fixed in IE11, and is browser related. |
I just tested it in IE and its not fixed... |
may be related to #5025 ? |
Better sniff code:
|
lol :) nice one @jamie-pate! |
BUMP. This really needs to be fixed by the angular team. |
Angular isn't necessarily capable of fixing bugs in IE, @WalterWeidner. How would you propose fixing it? Do we say "oh, the text value is identical to the value of the placeholder attribute, therefore it must not be a real value lets just ignore it"? Because that approach seems like it would cause much worse problems. I'll submit a fix for it but honestly I expect any fix for this is going to cause more regressions than the fix was worth |
The fix would be to sniff for this problem and not use the input event just like for IE9. (as mentioned at the top of the thread) We all wish that ie10 had actually ended the constant stream of ie workarounds but It seems like they will continue to be needed (though at least the fire hose seems to have been reduced to a garden hose) |
I agree that it is an IE problem but I think it would be better for it to be accounted for in angular code rather than in every single user's module configuration. This way the code will be less likely to break when we switch to future versions of angular. |
The issue with sniffing this is, the event (at least on IE10 standards mode) is not triggered synchronously, and I can't seem to get it to trigger before DOMContentLoaded/onload. So the issue here is that by the time we need to use the sniffed value, it's unavailable (unless text inputs are in templates imported by asynchronous directives). Further, we have no way of knowing that the input event was triggered by a placeholder, as the input event doesn't give us any feedback about what caused it. So it's probably a lost cause to try to deal with this. There are so many problems with the entire issue that it's honestly probably not even worth trying. IE10 is still a big chunk of the browser market, but it's on a steep decline, while IE11 is on the rise. This kind of works, but I have no guarantees that it doesn't break other browsers, and it relies on the UA string so we have no guarantee that it will even fix the issue in every possible configuration of IE. if (msie && event && event.type === 'input' && !value && value === lastValue &&
element.prop('placeholder')) {
return;
} in the listener. |
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
This is probably "good enough", who wants to dogfood this patch and see if it breaks anything |
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
Hi Caitlin I have done some testing on this one and have noticed that the input event fires even though the placeholder attribute has not changed (if the input receives focus and then looses focus the input event fires). An additional conditional check seems to solve the issue, as per line below: if (msie && (event || noevent).type === 'input' && (element[0].placeholder !== placeholder || |
Well originally I was also testing that value === lastValue (which kind of sucks, having to track that). But if it's necessary, that could be done too... Maybe there's a smarter way to do this without relying on hacks though. |
Agreed, hopefully there is a more elegant way to cater for the specific use case. |
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes angular#2614 Closes angular#5960
hey @caitp would that fix land in 1.2.15? |
Still needs to be reviewed, it's probably become a tad bitrotten by now |
This seems to affect IE 11 (tested on Windows 8.1) as well. |
…holder change Certain versions of IE inexplicably trigger an input event in response to a placeholder being set. It is not possible to sniff for this behaviour nicely as the event is not triggered if the element is not attached to the document, and the event triggers asynchronously so it is not possible to accomplish this without deferring DOM compilation and slowing down load times. Closes #2614 Closes #5960
@caitp will this be fixed in 1.2.x branch as well? |
@deezahyn this was merged into 1.2 and 1.3. There's also a bug report on IE about this behaviour, so perhaps there will eventually be a fix for it. Unfortunately, placeholder change isn't the only time IE sends input events inappropriately. It will also send an input event if you so much as click on a form control with a placeholder :( So this fix doesn't totally make IE behave normally =( |
oops my bad, thought it was only for 1.3.x tag. Will now test 👍 Thanks for the fix @caitp |
|
Sorry to resurface this issue, but this bug still seems to be present for textareas. I'm using AngularJS 1.2.22 and testing in IE 11 on Windows 7. |
This issue seams to still be present (input type='text' with placeholder) in IE11 and AngularJS 1.3.2. I haven't tested on IE10 yet. Following hack (coffee script) based on initial @jupiterplanet solution works for me: .config ($provide) ->
$provide.decorator '$sniffer', ['$delegate', ($sniffer) ->
userAgent = navigator.userAgent.toLowerCase()
msie = parseInt((/msie (\d+)/.exec(userAgent) ? [])[1], 10)
if isNaN(msie)
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(userAgent) ? [])[1], 10)
_hasEvent = $sniffer.hasEvent
$sniffer.hasEvent = (event) ->
if event is 'input' and msie >= 10
return false
_hasEvent.call this, event
return $sniffer
] |
For others who are coming across this issue when using textareas , it appears to have been fixed as of 1.3.6. Plunker (open in IE): http://plnkr.co/edit/LDZX0GFvq1zchiVGehCU?p=preview When opened with IE 11.0.9600.17416, change the Angular version in the plunker between 1.3.5 and 1.3.6 and you'll see the form no longer getting set to dirty as of 1.3.6. |
Input elements in AngularJS can be in pristine state meaning that the input element's value hasn't been modified yet by the user. In this case error messages can be hidden although validation fails because the input field is empty.
AngularJS uses different measures to determine if the value in an input element has changed. It listens to the input event for all browsers supporting this event with the exception of IE9 as this browser does not implement this event correctly.
However, as it turns out IE10 also has implementations faults. If a placeholder is defined on an input element IE10 fires this event when the placeholder is set during DOM loading and when it is removed when the user clicks into the input field so that error messages which depend on the pristine condition are displayed although the user has not yet modified the input's value.
Open the following plunk with IE10 to see this behavior:
http://plnkr.co/LqlkhtIPPEwgP0znR7vz
Click into the e-mail input field and the error message displays although the input's value has not changed yet.
In all other browsers (Chrome, IE9, Firefox) the error message is not displayed.
A workaround is to not use the input event just like for IE9.
The text was updated successfully, but these errors were encountered: