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

Modifying ng-options list fails to render in IE 10 (and 9) when contained in transcluded content #2809

Closed
ekaufman opened this issue May 28, 2013 · 20 comments

Comments

@ekaufman
Copy link

If you use a SELECT with ng-options underneath any directive that performs transclusion, and then modify the list used by ng-options, IE 9-10 will not automatically redraw the SELECT box to reflect the updated options unless the size of the list also happens to change.

Example:

    <div ng-switch on="dummy">
        <div ng-switch-default>
            My List: <select ng-model="listSelected" 
                       ng-options="item.value as item.name for item in childList">
                     </select>
        </div>
    </div>

If I swap out childList for another list of equal length, the browser still shows the previous options in the select until I click on it (and in IE9 even after clicking on it).

This fiddle demonstrates the issue in an ng-switch, and also in a custom-directive, and shows how when not in directive the problem doesn't occur. The parent list drives changes to the child list, in IE you'll see that the child list doesn't redraw with the new options except in the third example which is the one that doesn't transclude. Other browsers work as expected.
http://jsfiddle.net/redwood7/BGq3s/embedded/result/

Here's what I've tracked down so far; there is a weird side effect when you cloneNode() a SELECT in IE. IE won't redraw the cloned SELECT unless you either add/remove options from it, or hide()/show() it, or click it, or do something else that forces it to redraw. This fiddle demonstrates this problem completely outside of angular:
http://jsfiddle.net/redwood7/kHWxL/embedded/result/

The reason this relates to transclude in Angular is because directives that transclude use cloneNode() to copy the transcluded content. So, a SELECT with ng-options in that transcluded content end up having the problem. And ng-options re-uses existing OPTIONs instead of removing and recreating them, so if your lists are equal length IE never redraws.

One workaround is to have a custom directive that inserts/removes a dummy option when IE. Another is to ng-repeat to create options. I'm hoping this is something that can be fixed in ng-options. Perhaps in IE make it recreate the OPTIONs instead of re-using them.

I've also posted this topic to the mailing list with some additional fiddles showing workarounds:
https://groups.google.com/forum/#!topic/angular/20SJvpwpt2o/discussion

@btford btford closed this as completed Aug 24, 2013
@btford
Copy link
Contributor

btford commented Aug 24, 2013

As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months.

Please try the newest versions of Angular (1.0.8 and 1.2.0-rc.1), and if the issue persists, comment below so we can discuss it.

Thanks!

@ekaufman
Copy link
Author

It still still occurs in both 1.0.8 and 1.2.0rc1.

1.0.8: http://jsfiddle.net/redwood7/HbQCE/
1.2.0rc1: http://jsfiddle.net/redwood7/9cfms/

@btford
Copy link
Contributor

btford commented Aug 28, 2013

Thanks for verifying. :)

@btford btford reopened this Aug 28, 2013
@linkswapnil
Copy link

i'm using 1.2.0-rc.2 and still facing this issue

@peduarte
Copy link

Yeah, me too.
It's preeeeeeeeeeeetty annoying.
I have not managed to solve it, tried many different possible solutions and nada.

Can some one please enlighten me?

@grekier
Copy link

grekier commented Feb 14, 2014

Still there in 1.2.11 so +1 for fixing the issue.

@scottkilker
Copy link

Any update on this issue? It's still happening in 1.2.14.

@maenu
Copy link

maenu commented Mar 14, 2014

I just ran into this issue and it costed me hours. I finally found a dirty hack that works around the issue (tested on IE9) see here. It works by inserting and removing a dummy option to the DOM. To force the repainting of the whole select I added and removed a class after having forced the calculation of the width. The fiddle was started from a stackoverflow question and uses the approach from another stackoverflow question to force the repainting.

Unfortunately, it seems not to be working always.

There are not enough curse words to express my hatred for IE...

@yuyinitos
Copy link

Thanks maenu, finally a solution that works 👍

@Narretz Narretz added this to the 1.3.0 milestone Jun 23, 2014
@Loher
Copy link

Loher commented Jul 22, 2014

Hi, I just ran into this issue as well and I found another dirty hack.

.directive('fixCrappyIeSelect', function () {
   return {
        restrict: 'A',
        scope: {
            options: '=fixCrappyIeSelect'
        },
        controller: ['$scope', '$element', function ($scope, $element) {
            $scope.$watch('options', function () {
                $element.hide();
                $element.show();
            });
        }]
    };
});

Just hide() and show() the select element force IE to redraw the select box.

Hope this will help until a real fix will be released.

@petebacondarwin
Copy link
Contributor

@petebacondarwin
Copy link
Contributor

@mzgol you are a master of this sort of thing. Do you have any ideas what we can do here?

@petebacondarwin
Copy link
Contributor

I have moved it 1.4.x but if the fix is possible we could try to backport it to 1.3.x

@evilaliv3
Copy link

we are experiencing exactly the same issue on GlobaLeaks!

@mgol
Copy link
Member

mgol commented Feb 3, 2016

The jsFiddle doesn't work for me in IE so I recreated this locally (esp. that the global controller declaration style is no longer supported) but I can't reproduce it with 1.5.0-rc.2, either on IE 10 or IE 9 on Windows 7 (checked via BrowserStack):
http://jsbin.com/koruxi/. I've also tried with Angular 1.4.9 & 1.3.20 on IE 9 and it works as well.

What I did: I changed the "Parent List" select values from A to B, in all 3 cases the child lists updated.

Does anyone have a full reproducible test case? Please put it on jsbin or plunker, not jsfiddle as jsfiddle seems broken in IE.

@mgol
Copy link
Member

mgol commented Feb 3, 2016

What we've encountered in jQuery is that IE (all versions, fixed in Edge) don't always respect setting the selected property on an option so we have custom hooks that just access the selectedIndex property to make it behave:
https://github.com/jquery/jquery/blob/9cb89bf91d034ec7166d9215e2f80fa765292975/src/attributes/prop.js#L83-L109

It might be that this selecting fixes also some other issues, we can try sth like that. But I need a reproducible test case first. :)

Note, though, that we've had problems with IE 11 as well so if this problem appears only in IE<11 it might be unrelated.

@mgol
Copy link
Member

mgol commented Feb 3, 2016

This is a related article: https://brooknovak.wordpress.com/2009/08/23/ies-clonenode-doesnt-actually-clone/

@petebacondarwin This is a description of just one tiny problem, IE has loads of them, especially versions older than 9. This particular problem has been fixed in IE 9 so it's not an issue for us.

@ekaufman
Copy link
Author

ekaufman commented Feb 3, 2016

The fix put in for #9621 has fixed this issue as well.

Here's the bug reproducible in 1.3.2:
http://jsbin.com/voveja

And fixed in 1.3.3:
http://jsbin.com/jupolo

So it's fixed in 1.3.3+ see #10042
and also 1.2.27+ 16833d0

@gkalpak
Copy link
Member

gkalpak commented May 13, 2016

@ninad-d, what versions of Angular have you tried ? Can you check with the latest snapshot ?
If the problem still persists, please open a new issue (referencing this one if you think it might be relevant).

@ninad-d
Copy link

ninad-d commented May 19, 2016

@gkalpak I have opened up a separate issue. Kindly refer my latest update over there.

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