How to fix IE select issue when dynamically changing options How to fix IE select issue when dynamically changing options angularjs angularjs

How to fix IE select issue when dynamically changing options


I experienced the same issue the other night and after throwing everything I could think of at it I've come to the conclusion that IE just doesn't want to handle updating filters when using selects.

My solution is to change your selects to look like this:

 <select class="selectList" ng-repeat="currId in selectedIds" ng-model="selectedIds[$index]"  ng-options="currOption.id as currOption.value for currOption in myObj | myfilter:selectedIds:$index" data-ng-change="fixIE()"></select>

They now have a class and an ng-change on them. Then in your controller do this fun little bit of code:

$scope.fixIE = function(){    //code to check if IE so the other browsers don't get this ugly hack.    var selectLists = document.querySelectorAll(".selectList");    for(var x = 0;x  < selectLists.length; x++){        selectLists[x].parentNode.insertBefore(selectLists[x], selectLists[x]);    }       };

What it does is rip the elements out of the DOM and replace them into the same location. Here's a working fiddle jsFiddle

Some of the other solutions I tried that didn't involve javascript were things like toggling the display/visibility of the select. Having their zIndex's moved. The only thing that for sure fixed it was this piece of code.


I have the fix.

We have to add and remove options list to trigger the rendering in IE8.

http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html


/** * Fix for IE select menus getting stuck when their underlying list changes. * Original code: http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html *  * Set the `ie-select-fix` attribute to the model expression that should trigger the list to re-render. *  * @example <select ng-model="modelValue" ie-select-fix="itemList" ng-options="item.label for item in itemList"> */app.directive('ieSelectFix', ['$document',        function($document) {            return {                restrict: 'A',                require: 'ngModel',                link: function(scope, element, attributes, ngModelCtrl) {                    var isIE = $document[0] && $document[0].attachEvent;                    if (!isIE) return;                    var control = element[0];                    //to fix IE8 issue with parent and detail controller, we need to depend on the parent controller                    scope.$watch(attributes.ieSelectFix, function() {                        // setTimeout is needed starting from angular 1.3+                        setTimeout(function() {                            //this will add and remove the options to trigger the rendering in IE8                            var option = document.createElement("option");                            control.add(option,null);                            control.remove(control.options.length-1);                        }, 0);                    });                }            }        }    ]);


I've finally come up with a solution that works for my needs. Basically what appears to be happening is that the text for the option at the selected index is pointing to the old string that used to be in that place. I believe changing this text updates the strings and/or references. I did something like this:

angular.forEach($("select"), function (currSelect) {     currSelect.options[currSelect.selectedIndex].text += " ";});

Here is the updated fiddle: http://jsfiddle.net/H48sP/35/

In my app, I have a directive where these selects are, and so I do element.find("select") instead of $("select") to limit the scope of the element selecting. The text is forced to refresh and so displays correctly after all the digest cycles run.

If you have run into this same issue, you may need to add a $timeout like in the fiddle, and/or you may need to later remove the extra space that was added to the option text if that becomes a problem.