Search code examples
jquerytwitter-bootstrapknockout.jsinternet-explorer-10

Bootstrap form-control class conflicting with Knockout databind


I'm experiencing this weird bug with IE10 and it doesn't happen in Chrome or Firefox.

The bug is that when I use form-control from Bootstrap combine on a pair of parent-child select elements with Knockout data binding, the child select takes forever to refresh. But if you mouse over the child element, it refreshes right away.

Here's the JS to reproduce it.

Try browse this link with IE10 and change the value in the first select, the second select will not refresh unless you wait for a long time or mouse over to the second select.

But if I do not use form-control class for select elements, the problem goes away like in this link.

HTML

<label for="cats">Categories</label>
<select id="cats" data-bind="options: availableCats, optionsText: 'name', value: selectedCat, event: {change: populateItems}" class="xform-control"></select>
<label for="items">Items</label>
<select id="items" data-bind="options: availableItems, optionsText: 'name', value: selectedItem" class="xform-control

JS

$(document).ready(function () {
    var BaseVM = function () {
        var that = {};
        return that;
    };

    var TestVM = function () {
        var that = BaseVM();

        that.availableCats = ko.observableArray([{
            name: '--'
        }, {
            name: 'pork'
        }, {
            name: 'ham'
        }]);
        that.selectedCat = ko.observable(null);
        that.availableItems = ko.observableArray([]);
        that.selectedItem = ko.observable(null);

        that.populateItems = function () {
            that.availableItems([]);

            if (that.selectedCat().name === 'pork') {
                that.availableItems([{
                    name: 'chop'
                }]);
            } else if (that.selectedCat().name === 'ham') {
                that.availableItems([{
                    name: 'spam'
                }]);
            }
        };

        return that;
    };

    var vm = TestVM();
    ko.applyBindings(vm);
});

Solution

  • This problem is an IE10 redrawing issue.

    Another person had a similar issue.

    Unfortunately, the solution is not ideal and very hacky.

    You will need to add this code at the bottom of your populateItems function after all of your update logic:

    $('#items').hide(0, function(){$(this).show()});
    

    This will give IE10 a nudge to redraw the select element.

    Here is your fiddle, updated with the working solution.