Search code examples
javascriptinternet-explorer-10internet-explorer-11jquery-select2

Select2 3.5.2 mousedown jumps to top of list in IE10 & IE11


Using Select2 v3.5.2 to create a dynamic option list. The input allows users to select from the list, type to search through options and if the option doesn't exist it is created. The function which created this data is called within an angular controller. (ui-select was not used for this particular input as I did not see how to implement the search + custom input when this was implemented)

var dataQuant = {results: []};
for (var key in response.defaultQuantities) {
    var objQuant = response.defaultQuantities[key];         
    dataQuant.results.push({id:key, text:key + 'otherText'});
}


$('.customClass').select2({
    createSearchChoice:function(term, data) {                 
        if ($(data).filter(function() {return this.text.localeCompare(term)===0; }).length===0) {
            return {id:term, text:term};
        }
    },
    matcher: function(term, text) {
        return text.toUpperCase().indexOf(term.toUpperCase())==0;
    },
    data: dataQuant,
    dropdownCssClass: "customClass2",
    selectOnBlur: true,
    initSelection : function (element, callback) {
        var data = {id: response.defaultQuantity , text: response.defaultQuantity};
        callback(data);
    }
});

$('.customClass').on('change',function(){
    var newQuantityData = $('.customClass').select2('data');
    if ($scope.formData["quantity"] != newQuantityData.id){             
        $scope.formData["quantity"] = newQuantityData.id;
        $scope.updateFunction();  
    }
});

This works perfectly fine in chrome/firefox/opera/safari & IE9 and below. In IE10 and 11 any options seen initially can be clicked and work fine. Any options in the option list hidden initially (user has to scroll to) mousedown jumps back up to the top of the option list. If the mouse is held down and you then scroll back down the options when released the correct option is selected.

After some searching I have found that within the select.js under // single postprocessResults: function (data, initial, noHighlightUpdate) { the culprit was

if (initial === true && selected >= 0) {
    this.highlight(selected);
} else {
    this.highlight(0);
}

All other browsers have the 'initial' value as true passed into the function. IE10/11 has an object passed in which fails at the if statement resulting in the first option being highlighted. I'm not sure why an object is being passed in rather than true/false which it seems is what it's expecting. Anyone with more understanding of Select2 able to weigh in?

EDIT:

After removing this.highlight(0) I have now found that custom inputs that didn't exist before are not selected, so clicking the enter key does not select them. For now I'm just going to add a conditional to ignore this line if in IE.


Solution

  • Using and seems to function correctly in all browsers.

    Changing

    if (initial === true && selected >= 0) {
        this.highlight(selected);
    } else {
        this.highlight(0);
    }
    

    to

    if (initial === true && selected >= 0) {
        this.highlight(selected);
    } else {
        var docMode = document.documentMode,
        hasDocumentMode = (docMode !== undefined), 
        isIE10 = (docMode === 10),
        isIE11 = (docMode === 11);
    
        if(hasDocumentMode && (isIE11 || isIE10)){                       
            if(initial.target.value == data.results[0].id || data.results.length == 1){
                this.highlight(0);
            }
        }else{
            this.highlight(0);                           
        }
    }
    

    Option list no longer jumps to the top in IE 10/11, but still allows users to enter custom values and the 'enter' key selects the typed values.