Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

AngularJS binding does not update when IE's clear button is clicked #11193

Open
dprothero opened this issue Feb 26, 2015 · 25 comments · May be fixed by #14772
Open

AngularJS binding does not update when IE's clear button is clicked #11193

dprothero opened this issue Feb 26, 2015 · 25 comments · May be fixed by #14772

Comments

@dprothero
Copy link

IE has an "X" in each text input that will clear the input. However, when clicking this button, while it clears the textbox, it does not update the Angular model that the input is bound to.

<input type="text" ng-model="name" />

See http://jsfiddle.net/p5x1zwr9/ for an example of the behavior.

See http://youtu.be/LFaEwliTzpQ for a video of the behavior.

I am using IE 11.

This actually worked in AngularJS versions prior to 1.3.6 so this may be a new Angular bug.

@tspaeth
Copy link

tspaeth commented Feb 26, 2015

Looks like a bit related to #7297?

@Narretz
Copy link
Contributor

Narretz commented Feb 26, 2015

This should never have worked, as IE11 is not sending the change event when ESC is hit / the x is clicked. What is the last version you have seen this working?

@vitaly-t
Copy link

I researched it, and it would appear that the only usable solution is to remove the "X" using CSS, which is quite easy. Example: http://stackoverflow.com/questions/14007655/remove-ie10s-clear-field-x-button-on-certain-inputs

@dprothero
Copy link
Author

It works in 1.3.5. See: http://jsfiddle.net/p5x1zwr9/2/

@Narretz
Copy link
Contributor

Narretz commented Feb 26, 2015

Weird.
In 1.3.5: ESC ❌ Click ✅
In 1.3.6: ESC ✅ : Click ❌

Probably caused by 55d9db5

Still, IE is not doing the right thing here.

@Tim91084
Copy link

I'm using this directive to resolve the issue.. Albeit I only tested in a later version of angular (1.4.5)

angular
    .module('yourModule')
    .directive('input', FixIEClearButton);

FixIEClearButton.$inject = ['$timeout', '$sniffer'];

function FixIEClearButton($timeout, $sniffer) {
    var directive = {
        restrict: 'E',
        require: '?ngModel',
        link: Link,
        controller: function () { }
    };

    return directive;

    function Link(scope, elem, attr, controller) {
        var type = elem[0].type;
        //ie11 doesn't seem to support the input event, at least according to angular
        if (type !== 'text' || !controller || $sniffer.hasEvent('input')) {
            return;
        }

        elem.on("mouseup", function (event) {
            var oldValue = elem.val();
            if (oldValue == "") {
                return;
            }

            $timeout(function () {
                var newValue = elem.val();
                if (newValue !== oldValue) {
                    elem.val(oldValue);
                    elem.triggerHandler('keydown');
                    elem.val(newValue);
                    elem.triggerHandler('focus');
                }
            }, 0, false);
        });

        scope.$on('$destroy', destroy);
        elem.on('$destroy', destroy);

        function destroy() {
            elem.off('mouseup');
        }
    }
}

@vitaly-t
Copy link

This couldn't have worked, because IE does provide the necessary event. The only way to make it work is via a hack/workaround: either hide it with CSS or taping into mouse events to sneak-pick the current text in the control, like in the example shown just before.

I do believe AngularJS never had any hacks for this, so it couldn't have worked.

@Tim91084
Copy link

I think IE does provide the event, but for some reason (55d9db5) angular doesn't use it. Since angular isn't using the input event, the clear button event (which is the input event) is not captured. I wonder if you may also be able to solve this by using ng-model-options -> updateOn, and setting that to 'input'... gonna give it a try now..

@vitaly-t
Copy link

@Tim91084 speculating on this isn't gonna help the issue, IE doesn't provide the event in question, and that's certain.

@Tim91084
Copy link

@vitaly-t it does provide the event, check it out.

http://plnkr.co/edit/meNPDdS6EibG7g2S6lJx?p=preview

@vitaly-t
Copy link

@Tim91084 the event IE fails to provide is change, because the input content changes, but no event is provided. In your example you're catching event input, which works differently.

@Tim91084
Copy link

@vitaly-t not sure how change got into the picture. The default event in recent versions of angular for a text input is input (not change). This is true except in the case of IE, where the default event is keydown. Since the event fired when the clear button is clicked is input, but angular is listening for keydown, the model value does not update. This, I believe, is the root cause of this issue.

@Narretz
Copy link
Contributor

Narretz commented Oct 27, 2015

Interesting. There's a reason why IE doesn't use the default events but
maybe it doesn't apply for IE11. Does IE10 add the clear button?
Am 27.10.2015 23:19 schrieb "Timothy MacIntyre" notifications@github.com:

@vitaly-t https://github.com/vitaly-t not sure how change got into the
picture. The default event in recent versions of angular for a text input
is input' (notchange). This is true except in the case of IE, where the
default event iskeyup. Since the event fired when the clear button is
clicked isinput, but angular is listening forkeyup`, the model value does
not update. This, I believe, is the root cause of this issue.


Reply to this email directly or view it on GitHub
#11193 (comment)
.

@jbedard
Copy link
Contributor

jbedard commented Oct 27, 2015

Angular also listens to the change event (in every browser). But the input event is too buggy in IE so key events are used instead (IE 9-11, I assume Edge fixed the input event issues since no one has complained about them yet in angular...).

@ilyaivanov
Copy link

This was introduced at 1.3.6 version. You can check this predicate change.
If you change back to

if (event == 'input' && msie == 9) return false;

Clear button would update model state immediately.

Comment states next:

// IE10+ implements 'input' event but it erroneously fires under various situations,
// e.g. when placeholder changes, or a form is focused.

cpuy pushed a commit to bonitasoft/bonita-portal-js that referenced this issue Feb 1, 2016
…ield but doesn't refresh the search

See angular/angular.js#11193
Cross is hidden for search box on IE

Fixes [BS-14705](https://bonitasoft.atlassian.net/browse/BS-14705)
velcrin pushed a commit to bonitasoft/bonita-portal-js that referenced this issue Feb 4, 2016
…ield but doesn't refresh the search

See angular/angular.js#11193
Cross is hidden for search box on IE

Fixes [BS-14705](https://bonitasoft.atlassian.net/browse/BS-14705)
velcrin pushed a commit to bonitasoft/bonita-portal-js that referenced this issue Feb 4, 2016
…ield but doesn't refresh the search

See angular/angular.js#11193
Cross is hidden for search box on IE

Fixes [BS-14705](https://bonitasoft.atlassian.net/browse/BS-14705)
@murph1329
Copy link

murph1329 commented Jun 10, 2016

The following is still an issue, even in the latest version of AngularJS, and it was created by v1.3.6. As mentioned above.

It is my opinion that this issue be escalated as it could lead to data loss for IE users.

NOTE: the following defect can only be duplicated in IE (I'm using IE11)
Below are two runs of the same test using different Angular versions. One using 1.3.5 and the other is using 1.3.6.


Details:
Browser: IE11
AngularJS: v1.3.5

JSBin Sample:
http://jsbin.com/zeqanudeqi/1/edit?html,js,output

Steps to reproduce:
Edit any cell in "ID" column (do not press enter or any table navigation key)
After edit immediately click on "filter" textbox
Type text into "filter" textbox

EXPECTED RESULT: {{ctrl.filter}} should correspond to item in "filter" textbox
PASS


Details:
Browser: IE11
AngularJS: v1.3.6

JSBin Sample:
http://jsbin.com/ceduyapiwe/1/edit?html,js,output

Steps to reproduce:
Edit any cell in "ID" column (do not press enter or any table navigation key)
After edit immediately click on "filter" textbox
Type text into "filter" textbox

EXPECTED RESULT: {{ctrl.filter}} should correspond to item in "filter" textbox
DEFECT: model is not updated

@wesleycho
Copy link
Contributor

It should be noted that this is fixed in Edge. I'm not sure this can be fixed for IE though without introducing other bugs that have broader impact. IMO this should probably be closed due to the browser itself being broken, and workarounds being inadequate in the library itself.

@murph1329
Copy link

Interesting response. In my opinion this was working fine in 1.3.5 and 1.3.6 created a new defect, regardless of how many defects you think it solved it introduced another.

It really makes me question the AngularJS framework. I'm not sure what the other bugs are you speak of but I call in to question if their severity is greater than that of an issue that leads to data loss for a browser that dominates enterprise use.

@wesleycho
Copy link
Contributor

Unexpected running of parsers & validators could be far more severe than an edge case from incorrect browser eventing.

If there is a suitable workaround through event object sniffing to differentiate when the input events are fired on IE10 & 11, it would be worth doing so, but if the browser flat out does the wrong thing, it can be impossible to hack around it.

@gkalpak
Copy link
Member

gkalpak commented Jun 14, 2016

If there is a reasonable fix for this (e.g. listening to one more event on IEs), I think it is worth fixing this.
It is obviously a browser issue, but I agree that it can have severe impact on functionality and we should try to work around the browser's problematic behavior.
(It's not like this will be the first time we are working around IE's "eccentric" behavior 😃)

PR anyone ? 😛

@wesleycho
Copy link
Contributor

Just did a search, and found a potentially promising avenue, but it might degrade performance of the handler slightly - http://stackoverflow.com/a/25693273 suggests that we could cache the old value, and on change, pull the new value and compare. If they are the same and we are in IE, we could just exit the handler, which should be sufficient to avoid the excess $parser/$validator firing problem.

@wesleycho
Copy link
Contributor

Actually, I have an idea how to implement this - I'll open a PR shortly. Will we be able to write a test for this though?

@wesleycho wesleycho linked a pull request Jun 14, 2016 that will close this issue
@blemaire
Copy link

blemaire commented Jun 8, 2018

Any updates on this problem? thanks

@gkalpak
Copy link
Member

gkalpak commented Jun 8, 2018

See #14772 (comment).

@Splaktar
Copy link
Member

Splaktar commented Aug 29, 2018

I just wanted to note that this affects AngularJS Material as well (angular/material#10872). My recommendation is to hide the -ms-clear buttons. Then if you still need a clear button, you can add your own icon button that will work across browsers.

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

Successfully merging a pull request may close this issue.