Unable to select item in Select2 drop down











up vote
24
down vote

favorite
8












I am working on an app that uses Select2 (version 3.5.1). The HTML to setup this drop down / autocomplete field looks like this:



<input id="mySelect" class="form-control" type="hidden">


The form-control class in this snippet comes from Bootstrap. I am initializing this field from JavaScript using the following:



function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});


When my select field loads, it successfully renders. Once I type at least the fifth character, it successfully pulls items from the server and lists them as options. However, if I try to select one of them, nothing happens. The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.



In addition, I noticed that nothing is highlighted when I put my mouse over an item or attempt to navigate the list of options with the arrow keys.



What am I doing wrong?










share|improve this question




















  • 2




    You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
    – Dylan Corriveau
    Sep 29 '14 at 13:59












  • That's a problem with the snippet (I fixed it). However, that did not fix the issue.
    – user70192
    Sep 29 '14 at 14:36










  • @user70192 can you provide us a live example using JSFiddle ?
    – pomeh
    Sep 29 '14 at 14:38















up vote
24
down vote

favorite
8












I am working on an app that uses Select2 (version 3.5.1). The HTML to setup this drop down / autocomplete field looks like this:



<input id="mySelect" class="form-control" type="hidden">


The form-control class in this snippet comes from Bootstrap. I am initializing this field from JavaScript using the following:



function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});


When my select field loads, it successfully renders. Once I type at least the fifth character, it successfully pulls items from the server and lists them as options. However, if I try to select one of them, nothing happens. The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.



In addition, I noticed that nothing is highlighted when I put my mouse over an item or attempt to navigate the list of options with the arrow keys.



What am I doing wrong?










share|improve this question




















  • 2




    You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
    – Dylan Corriveau
    Sep 29 '14 at 13:59












  • That's a problem with the snippet (I fixed it). However, that did not fix the issue.
    – user70192
    Sep 29 '14 at 14:36










  • @user70192 can you provide us a live example using JSFiddle ?
    – pomeh
    Sep 29 '14 at 14:38













up vote
24
down vote

favorite
8









up vote
24
down vote

favorite
8






8





I am working on an app that uses Select2 (version 3.5.1). The HTML to setup this drop down / autocomplete field looks like this:



<input id="mySelect" class="form-control" type="hidden">


The form-control class in this snippet comes from Bootstrap. I am initializing this field from JavaScript using the following:



function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});


When my select field loads, it successfully renders. Once I type at least the fifth character, it successfully pulls items from the server and lists them as options. However, if I try to select one of them, nothing happens. The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.



In addition, I noticed that nothing is highlighted when I put my mouse over an item or attempt to navigate the list of options with the arrow keys.



What am I doing wrong?










share|improve this question















I am working on an app that uses Select2 (version 3.5.1). The HTML to setup this drop down / autocomplete field looks like this:



<input id="mySelect" class="form-control" type="hidden">


The form-control class in this snippet comes from Bootstrap. I am initializing this field from JavaScript using the following:



function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});


When my select field loads, it successfully renders. Once I type at least the fifth character, it successfully pulls items from the server and lists them as options. However, if I try to select one of them, nothing happens. The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.



In addition, I noticed that nothing is highlighted when I put my mouse over an item or attempt to navigate the list of options with the arrow keys.



What am I doing wrong?







javascript html jquery-select2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 29 '14 at 14:35

























asked Sep 27 '14 at 11:57









user70192

2,80540117201




2,80540117201








  • 2




    You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
    – Dylan Corriveau
    Sep 29 '14 at 13:59












  • That's a problem with the snippet (I fixed it). However, that did not fix the issue.
    – user70192
    Sep 29 '14 at 14:36










  • @user70192 can you provide us a live example using JSFiddle ?
    – pomeh
    Sep 29 '14 at 14:38














  • 2




    You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
    – Dylan Corriveau
    Sep 29 '14 at 13:59












  • That's a problem with the snippet (I fixed it). However, that did not fix the issue.
    – user70192
    Sep 29 '14 at 14:36










  • @user70192 can you provide us a live example using JSFiddle ?
    – pomeh
    Sep 29 '14 at 14:38








2




2




You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
– Dylan Corriveau
Sep 29 '14 at 13:59






You seem to be missing a quote on the mySelect section. Is that in your source? try adding it in and see if it helps
– Dylan Corriveau
Sep 29 '14 at 13:59














That's a problem with the snippet (I fixed it). However, that did not fix the issue.
– user70192
Sep 29 '14 at 14:36




That's a problem with the snippet (I fixed it). However, that did not fix the issue.
– user70192
Sep 29 '14 at 14:36












@user70192 can you provide us a live example using JSFiddle ?
– pomeh
Sep 29 '14 at 14:38




@user70192 can you provide us a live example using JSFiddle ?
– pomeh
Sep 29 '14 at 14:38












4 Answers
4






active

oldest

votes

















up vote
43
down vote



accepted
+500










What is happening:



By default, results of the object you are returning in ajax.results should be an array in this structure [{id:1,text:"a"},{id:2,text:"b"}, ...].



  results: function (data, page) {
var array = data.results; //depends on your JSON
return { results: array };
}





In Select2.js it actually states:



* @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
* The expected format is an object containing the following keys:
* results array of objects that will be used as choices
* more (optional) boolean indicating whether there are more results available
* Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}





Reading the source code, we can see that ajax.results is called on AJAX success:



   success: function (data) {
// TODO - replace query.page with query so users have access to term, page, etc.
// added query as third paramter to keep backwards compatibility
var results = options.results(data, query.page, query);
query.callback(results);
}





So ajax.results is really just a function for you to format your data into the appropriate structure ( e.g. [{id:a,text:"a"},{id:b,text:"b"}, ...]) before the data is passed to query.callback:



 callback: this.bind(function (data) {

// ignore a response if the select2 has been closed before it was received
if (!self.opened()) return;


self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
self.postprocessResults(data, false, false);

if (data.more===true) {
more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
} else {
more.remove();
}
self.positionDropdown();
self.resultsPage = page;
self.context = data.context;
this.opts.element.trigger({ type: "select2-loaded", items: data });
})});





And what query.callback eventually does is to set the logic up properly so that everything works fine when you choose one of the items and trigger .selectChoice.



selectChoice: function (choice) {

var selected = this.container.find(".select2-search-choice-focus");
if (selected.length && choice && choice[0] == selected[0]) {

} else {
if (selected.length) {
this.opts.element.trigger("choice-deselected", selected);
}
selected.removeClass("select2-search-choice-focus");
if (choice && choice.length) {
this.close();
choice.addClass("select2-search-choice-focus");
this.opts.element.trigger("choice-selected", choice);
}
}
}





So if there is some misconfiguration (e.g. results is not in the correct structure) that causes the class .select2-search-choice-focus not to be added to the DOM element before .selectChoice is called, this is what happens:




The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.






Solutions



There are many solutions to this. One of them is, of course, do some array keys manipulation in ajax.results.



  results: function (data, page) {
//data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
var array = data.results;
var i = 0;
while(i < array.length){
array[i]["id"] = array[i]['ItemId'];
array[i]["text"] = array[i]['ItemText'];
delete array[i]["ItemId"];
delete array[i]["ItemText"];
i++;
}
return { results: array };
}


But you may ask: why must the id be "id" and the text be "text" in the array?



[{id:1,text:"a"},{id:2,text:"b"}] 


Can the array be in this structure instead?



[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]


The answer is yes. You just need to overwrite the id and text functions with your own functions.





Here are the original functions for .selecte2 in Select2.js:



    id: function (e) { return e == undefined ? null : e.id; },
text: function (e) {
if (e && this.data && this.data.text) {
if ($.isFunction(this.data.text)) {
return this.data.text(e);
} else {
return e[this.data.text];
}
} else {
return e.text;
}
},





To overwrite them, just add your own functions inside the object you are passing to .selecte2:



$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText }
......
});




Updates



What else is happening :




However, the text of the selected item does not appear in the field after the list closes.




This means .selectChoice has been successfully executed. Now the problem lies in .updateSelection. In the source code:



   updateSelection: function (data) {

var container=this.selection.find(".select2-chosen"), formatted, cssClass;

this.selection.data("select2-data", data);

container.empty();
if (data !== null) {
formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
}
if (formatted !== undefined) {
container.append(formatted);
}
cssClass=this.opts.formatSelectionCssClass(data, container);
if (cssClass !== undefined) {
container.addClass(cssClass);
}

this.selection.removeClass("select2-default");

if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
this.container.addClass("select2-allowclear");
}
}





From here we can see that, before the corresponding string of text is placed into the input, it would call formatSelection.



formatSelection: function (data, container, escapeMarkup) {
return data ? escapeMarkup(this.text(data)) : undefined;
},


Update: Solution



Previously I thought this.text(data) can be overwritten by having text: funcion(item){ ... } in the parameters, but sadly it doesn't work that way.



Therefore to render the text properly in the field, you should overwrite formatSelection by doing



$('#mySelect').select2({
id: function (item) { return item.ItemId },
formatSelection: function (item) { return item.ItemText }
//......
});


instead of trying to overwrite text (which should supposedly have the same effect but this way of overwriting is not yet supported/implemented in the library)



$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText } //this will not work.
//......
});





share|improve this answer























  • This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
    – user70192
    Sep 29 '14 at 17:02










  • @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
    – Danillo Corvalan
    Sep 29 '14 at 20:34






  • 2




    Endless answer...
    – dani24
    Feb 15 '16 at 14:02






  • 1




    sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
    – Tobias Weichart
    Aug 9 '16 at 6:55






  • 1




    Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
    – HPWD
    Apr 24 at 0:31


















up vote
8
down vote













The issue you are facing is that select2 wants all your results to have an id property. If they don't you need to initialise with an id function which returns the id from each result.



It will not allow you to select a result unless you satisfy one of these. So in the case of your example :



function getItemFormat(item) {
var format = '<div>' + item.ItemName + '</div>';
return format;
}

$(function() {
$('#mySelect').select2({
minimumInputLength: 5,
placeholder: 'Search for an item',
allowClear: true,
id: function(item) { return item.ItemId; }, /* <-- ADDED FUNCTION */
ajax: {
url: '/api/getItems',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
return { results: data, id: 'ItemId', text: 'ItemText' };
}
},
formatResult: getItemFormat,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
});





share|improve this answer




























    up vote
    2
    down vote













    You need to provide an ID that returns from your API like @itsmejodie said.
    The other problem is that you have to provide select2 formatResult and formatSelection functions, once you have it loaded from Ajax but you can't put html on that. e.g.:



    function format (item) { 
    return item.name;
    }

    $(function() {
    $('#mySelect').select2({
    minimumInputLength: 2,
    placeholder: 'Search for an item',
    allowClear: true,
    ajax: {
    url: '/api/getItems',
    dataType: 'jsonp',
    quietMillis: 250,
    data: function (term, page) {
    return {
    query: term
    };
    },
    results: function (data, page) {
    return { results: data };
    }
    },
    formatResult: format,
    formatSelection: format
    });
    });





    share|improve this answer




























      up vote
      0
      down vote













      For version 4 of Select2 use



      processResults: function (data) { 


      instead of



      results: function (data) {





      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26074414%2funable-to-select-item-in-select2-drop-down%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        43
        down vote



        accepted
        +500










        What is happening:



        By default, results of the object you are returning in ajax.results should be an array in this structure [{id:1,text:"a"},{id:2,text:"b"}, ...].



          results: function (data, page) {
        var array = data.results; //depends on your JSON
        return { results: array };
        }





        In Select2.js it actually states:



        * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
        * The expected format is an object containing the following keys:
        * results array of objects that will be used as choices
        * more (optional) boolean indicating whether there are more results available
        * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}





        Reading the source code, we can see that ajax.results is called on AJAX success:



           success: function (data) {
        // TODO - replace query.page with query so users have access to term, page, etc.
        // added query as third paramter to keep backwards compatibility
        var results = options.results(data, query.page, query);
        query.callback(results);
        }





        So ajax.results is really just a function for you to format your data into the appropriate structure ( e.g. [{id:a,text:"a"},{id:b,text:"b"}, ...]) before the data is passed to query.callback:



         callback: this.bind(function (data) {

        // ignore a response if the select2 has been closed before it was received
        if (!self.opened()) return;


        self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
        self.postprocessResults(data, false, false);

        if (data.more===true) {
        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
        } else {
        more.remove();
        }
        self.positionDropdown();
        self.resultsPage = page;
        self.context = data.context;
        this.opts.element.trigger({ type: "select2-loaded", items: data });
        })});





        And what query.callback eventually does is to set the logic up properly so that everything works fine when you choose one of the items and trigger .selectChoice.



        selectChoice: function (choice) {

        var selected = this.container.find(".select2-search-choice-focus");
        if (selected.length && choice && choice[0] == selected[0]) {

        } else {
        if (selected.length) {
        this.opts.element.trigger("choice-deselected", selected);
        }
        selected.removeClass("select2-search-choice-focus");
        if (choice && choice.length) {
        this.close();
        choice.addClass("select2-search-choice-focus");
        this.opts.element.trigger("choice-selected", choice);
        }
        }
        }





        So if there is some misconfiguration (e.g. results is not in the correct structure) that causes the class .select2-search-choice-focus not to be added to the DOM element before .selectChoice is called, this is what happens:




        The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.






        Solutions



        There are many solutions to this. One of them is, of course, do some array keys manipulation in ajax.results.



          results: function (data, page) {
        //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
        var array = data.results;
        var i = 0;
        while(i < array.length){
        array[i]["id"] = array[i]['ItemId'];
        array[i]["text"] = array[i]['ItemText'];
        delete array[i]["ItemId"];
        delete array[i]["ItemText"];
        i++;
        }
        return { results: array };
        }


        But you may ask: why must the id be "id" and the text be "text" in the array?



        [{id:1,text:"a"},{id:2,text:"b"}] 


        Can the array be in this structure instead?



        [{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]


        The answer is yes. You just need to overwrite the id and text functions with your own functions.





        Here are the original functions for .selecte2 in Select2.js:



            id: function (e) { return e == undefined ? null : e.id; },
        text: function (e) {
        if (e && this.data && this.data.text) {
        if ($.isFunction(this.data.text)) {
        return this.data.text(e);
        } else {
        return e[this.data.text];
        }
        } else {
        return e.text;
        }
        },





        To overwrite them, just add your own functions inside the object you are passing to .selecte2:



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText }
        ......
        });




        Updates



        What else is happening :




        However, the text of the selected item does not appear in the field after the list closes.




        This means .selectChoice has been successfully executed. Now the problem lies in .updateSelection. In the source code:



           updateSelection: function (data) {

        var container=this.selection.find(".select2-chosen"), formatted, cssClass;

        this.selection.data("select2-data", data);

        container.empty();
        if (data !== null) {
        formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
        }
        if (formatted !== undefined) {
        container.append(formatted);
        }
        cssClass=this.opts.formatSelectionCssClass(data, container);
        if (cssClass !== undefined) {
        container.addClass(cssClass);
        }

        this.selection.removeClass("select2-default");

        if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
        this.container.addClass("select2-allowclear");
        }
        }





        From here we can see that, before the corresponding string of text is placed into the input, it would call formatSelection.



        formatSelection: function (data, container, escapeMarkup) {
        return data ? escapeMarkup(this.text(data)) : undefined;
        },


        Update: Solution



        Previously I thought this.text(data) can be overwritten by having text: funcion(item){ ... } in the parameters, but sadly it doesn't work that way.



        Therefore to render the text properly in the field, you should overwrite formatSelection by doing



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        formatSelection: function (item) { return item.ItemText }
        //......
        });


        instead of trying to overwrite text (which should supposedly have the same effect but this way of overwriting is not yet supported/implemented in the library)



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText } //this will not work.
        //......
        });





        share|improve this answer























        • This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
          – user70192
          Sep 29 '14 at 17:02










        • @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
          – Danillo Corvalan
          Sep 29 '14 at 20:34






        • 2




          Endless answer...
          – dani24
          Feb 15 '16 at 14:02






        • 1




          sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
          – Tobias Weichart
          Aug 9 '16 at 6:55






        • 1




          Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
          – HPWD
          Apr 24 at 0:31















        up vote
        43
        down vote



        accepted
        +500










        What is happening:



        By default, results of the object you are returning in ajax.results should be an array in this structure [{id:1,text:"a"},{id:2,text:"b"}, ...].



          results: function (data, page) {
        var array = data.results; //depends on your JSON
        return { results: array };
        }





        In Select2.js it actually states:



        * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
        * The expected format is an object containing the following keys:
        * results array of objects that will be used as choices
        * more (optional) boolean indicating whether there are more results available
        * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}





        Reading the source code, we can see that ajax.results is called on AJAX success:



           success: function (data) {
        // TODO - replace query.page with query so users have access to term, page, etc.
        // added query as third paramter to keep backwards compatibility
        var results = options.results(data, query.page, query);
        query.callback(results);
        }





        So ajax.results is really just a function for you to format your data into the appropriate structure ( e.g. [{id:a,text:"a"},{id:b,text:"b"}, ...]) before the data is passed to query.callback:



         callback: this.bind(function (data) {

        // ignore a response if the select2 has been closed before it was received
        if (!self.opened()) return;


        self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
        self.postprocessResults(data, false, false);

        if (data.more===true) {
        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
        } else {
        more.remove();
        }
        self.positionDropdown();
        self.resultsPage = page;
        self.context = data.context;
        this.opts.element.trigger({ type: "select2-loaded", items: data });
        })});





        And what query.callback eventually does is to set the logic up properly so that everything works fine when you choose one of the items and trigger .selectChoice.



        selectChoice: function (choice) {

        var selected = this.container.find(".select2-search-choice-focus");
        if (selected.length && choice && choice[0] == selected[0]) {

        } else {
        if (selected.length) {
        this.opts.element.trigger("choice-deselected", selected);
        }
        selected.removeClass("select2-search-choice-focus");
        if (choice && choice.length) {
        this.close();
        choice.addClass("select2-search-choice-focus");
        this.opts.element.trigger("choice-selected", choice);
        }
        }
        }





        So if there is some misconfiguration (e.g. results is not in the correct structure) that causes the class .select2-search-choice-focus not to be added to the DOM element before .selectChoice is called, this is what happens:




        The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.






        Solutions



        There are many solutions to this. One of them is, of course, do some array keys manipulation in ajax.results.



          results: function (data, page) {
        //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
        var array = data.results;
        var i = 0;
        while(i < array.length){
        array[i]["id"] = array[i]['ItemId'];
        array[i]["text"] = array[i]['ItemText'];
        delete array[i]["ItemId"];
        delete array[i]["ItemText"];
        i++;
        }
        return { results: array };
        }


        But you may ask: why must the id be "id" and the text be "text" in the array?



        [{id:1,text:"a"},{id:2,text:"b"}] 


        Can the array be in this structure instead?



        [{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]


        The answer is yes. You just need to overwrite the id and text functions with your own functions.





        Here are the original functions for .selecte2 in Select2.js:



            id: function (e) { return e == undefined ? null : e.id; },
        text: function (e) {
        if (e && this.data && this.data.text) {
        if ($.isFunction(this.data.text)) {
        return this.data.text(e);
        } else {
        return e[this.data.text];
        }
        } else {
        return e.text;
        }
        },





        To overwrite them, just add your own functions inside the object you are passing to .selecte2:



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText }
        ......
        });




        Updates



        What else is happening :




        However, the text of the selected item does not appear in the field after the list closes.




        This means .selectChoice has been successfully executed. Now the problem lies in .updateSelection. In the source code:



           updateSelection: function (data) {

        var container=this.selection.find(".select2-chosen"), formatted, cssClass;

        this.selection.data("select2-data", data);

        container.empty();
        if (data !== null) {
        formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
        }
        if (formatted !== undefined) {
        container.append(formatted);
        }
        cssClass=this.opts.formatSelectionCssClass(data, container);
        if (cssClass !== undefined) {
        container.addClass(cssClass);
        }

        this.selection.removeClass("select2-default");

        if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
        this.container.addClass("select2-allowclear");
        }
        }





        From here we can see that, before the corresponding string of text is placed into the input, it would call formatSelection.



        formatSelection: function (data, container, escapeMarkup) {
        return data ? escapeMarkup(this.text(data)) : undefined;
        },


        Update: Solution



        Previously I thought this.text(data) can be overwritten by having text: funcion(item){ ... } in the parameters, but sadly it doesn't work that way.



        Therefore to render the text properly in the field, you should overwrite formatSelection by doing



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        formatSelection: function (item) { return item.ItemText }
        //......
        });


        instead of trying to overwrite text (which should supposedly have the same effect but this way of overwriting is not yet supported/implemented in the library)



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText } //this will not work.
        //......
        });





        share|improve this answer























        • This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
          – user70192
          Sep 29 '14 at 17:02










        • @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
          – Danillo Corvalan
          Sep 29 '14 at 20:34






        • 2




          Endless answer...
          – dani24
          Feb 15 '16 at 14:02






        • 1




          sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
          – Tobias Weichart
          Aug 9 '16 at 6:55






        • 1




          Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
          – HPWD
          Apr 24 at 0:31













        up vote
        43
        down vote



        accepted
        +500







        up vote
        43
        down vote



        accepted
        +500




        +500




        What is happening:



        By default, results of the object you are returning in ajax.results should be an array in this structure [{id:1,text:"a"},{id:2,text:"b"}, ...].



          results: function (data, page) {
        var array = data.results; //depends on your JSON
        return { results: array };
        }





        In Select2.js it actually states:



        * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
        * The expected format is an object containing the following keys:
        * results array of objects that will be used as choices
        * more (optional) boolean indicating whether there are more results available
        * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}





        Reading the source code, we can see that ajax.results is called on AJAX success:



           success: function (data) {
        // TODO - replace query.page with query so users have access to term, page, etc.
        // added query as third paramter to keep backwards compatibility
        var results = options.results(data, query.page, query);
        query.callback(results);
        }





        So ajax.results is really just a function for you to format your data into the appropriate structure ( e.g. [{id:a,text:"a"},{id:b,text:"b"}, ...]) before the data is passed to query.callback:



         callback: this.bind(function (data) {

        // ignore a response if the select2 has been closed before it was received
        if (!self.opened()) return;


        self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
        self.postprocessResults(data, false, false);

        if (data.more===true) {
        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
        } else {
        more.remove();
        }
        self.positionDropdown();
        self.resultsPage = page;
        self.context = data.context;
        this.opts.element.trigger({ type: "select2-loaded", items: data });
        })});





        And what query.callback eventually does is to set the logic up properly so that everything works fine when you choose one of the items and trigger .selectChoice.



        selectChoice: function (choice) {

        var selected = this.container.find(".select2-search-choice-focus");
        if (selected.length && choice && choice[0] == selected[0]) {

        } else {
        if (selected.length) {
        this.opts.element.trigger("choice-deselected", selected);
        }
        selected.removeClass("select2-search-choice-focus");
        if (choice && choice.length) {
        this.close();
        choice.addClass("select2-search-choice-focus");
        this.opts.element.trigger("choice-selected", choice);
        }
        }
        }





        So if there is some misconfiguration (e.g. results is not in the correct structure) that causes the class .select2-search-choice-focus not to be added to the DOM element before .selectChoice is called, this is what happens:




        The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.






        Solutions



        There are many solutions to this. One of them is, of course, do some array keys manipulation in ajax.results.



          results: function (data, page) {
        //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
        var array = data.results;
        var i = 0;
        while(i < array.length){
        array[i]["id"] = array[i]['ItemId'];
        array[i]["text"] = array[i]['ItemText'];
        delete array[i]["ItemId"];
        delete array[i]["ItemText"];
        i++;
        }
        return { results: array };
        }


        But you may ask: why must the id be "id" and the text be "text" in the array?



        [{id:1,text:"a"},{id:2,text:"b"}] 


        Can the array be in this structure instead?



        [{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]


        The answer is yes. You just need to overwrite the id and text functions with your own functions.





        Here are the original functions for .selecte2 in Select2.js:



            id: function (e) { return e == undefined ? null : e.id; },
        text: function (e) {
        if (e && this.data && this.data.text) {
        if ($.isFunction(this.data.text)) {
        return this.data.text(e);
        } else {
        return e[this.data.text];
        }
        } else {
        return e.text;
        }
        },





        To overwrite them, just add your own functions inside the object you are passing to .selecte2:



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText }
        ......
        });




        Updates



        What else is happening :




        However, the text of the selected item does not appear in the field after the list closes.




        This means .selectChoice has been successfully executed. Now the problem lies in .updateSelection. In the source code:



           updateSelection: function (data) {

        var container=this.selection.find(".select2-chosen"), formatted, cssClass;

        this.selection.data("select2-data", data);

        container.empty();
        if (data !== null) {
        formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
        }
        if (formatted !== undefined) {
        container.append(formatted);
        }
        cssClass=this.opts.formatSelectionCssClass(data, container);
        if (cssClass !== undefined) {
        container.addClass(cssClass);
        }

        this.selection.removeClass("select2-default");

        if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
        this.container.addClass("select2-allowclear");
        }
        }





        From here we can see that, before the corresponding string of text is placed into the input, it would call formatSelection.



        formatSelection: function (data, container, escapeMarkup) {
        return data ? escapeMarkup(this.text(data)) : undefined;
        },


        Update: Solution



        Previously I thought this.text(data) can be overwritten by having text: funcion(item){ ... } in the parameters, but sadly it doesn't work that way.



        Therefore to render the text properly in the field, you should overwrite formatSelection by doing



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        formatSelection: function (item) { return item.ItemText }
        //......
        });


        instead of trying to overwrite text (which should supposedly have the same effect but this way of overwriting is not yet supported/implemented in the library)



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText } //this will not work.
        //......
        });





        share|improve this answer














        What is happening:



        By default, results of the object you are returning in ajax.results should be an array in this structure [{id:1,text:"a"},{id:2,text:"b"}, ...].



          results: function (data, page) {
        var array = data.results; //depends on your JSON
        return { results: array };
        }





        In Select2.js it actually states:



        * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
        * The expected format is an object containing the following keys:
        * results array of objects that will be used as choices
        * more (optional) boolean indicating whether there are more results available
        * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}





        Reading the source code, we can see that ajax.results is called on AJAX success:



           success: function (data) {
        // TODO - replace query.page with query so users have access to term, page, etc.
        // added query as third paramter to keep backwards compatibility
        var results = options.results(data, query.page, query);
        query.callback(results);
        }





        So ajax.results is really just a function for you to format your data into the appropriate structure ( e.g. [{id:a,text:"a"},{id:b,text:"b"}, ...]) before the data is passed to query.callback:



         callback: this.bind(function (data) {

        // ignore a response if the select2 has been closed before it was received
        if (!self.opened()) return;


        self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
        self.postprocessResults(data, false, false);

        if (data.more===true) {
        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
        } else {
        more.remove();
        }
        self.positionDropdown();
        self.resultsPage = page;
        self.context = data.context;
        this.opts.element.trigger({ type: "select2-loaded", items: data });
        })});





        And what query.callback eventually does is to set the logic up properly so that everything works fine when you choose one of the items and trigger .selectChoice.



        selectChoice: function (choice) {

        var selected = this.container.find(".select2-search-choice-focus");
        if (selected.length && choice && choice[0] == selected[0]) {

        } else {
        if (selected.length) {
        this.opts.element.trigger("choice-deselected", selected);
        }
        selected.removeClass("select2-search-choice-focus");
        if (choice && choice.length) {
        this.close();
        choice.addClass("select2-search-choice-focus");
        this.opts.element.trigger("choice-selected", choice);
        }
        }
        }





        So if there is some misconfiguration (e.g. results is not in the correct structure) that causes the class .select2-search-choice-focus not to be added to the DOM element before .selectChoice is called, this is what happens:




        The drop-down popup stays open. Nothing gets put in the actual field. There are no errors in the JavaScript console. Its like I didn't click anything.






        Solutions



        There are many solutions to this. One of them is, of course, do some array keys manipulation in ajax.results.



          results: function (data, page) {
        //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
        var array = data.results;
        var i = 0;
        while(i < array.length){
        array[i]["id"] = array[i]['ItemId'];
        array[i]["text"] = array[i]['ItemText'];
        delete array[i]["ItemId"];
        delete array[i]["ItemText"];
        i++;
        }
        return { results: array };
        }


        But you may ask: why must the id be "id" and the text be "text" in the array?



        [{id:1,text:"a"},{id:2,text:"b"}] 


        Can the array be in this structure instead?



        [{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]


        The answer is yes. You just need to overwrite the id and text functions with your own functions.





        Here are the original functions for .selecte2 in Select2.js:



            id: function (e) { return e == undefined ? null : e.id; },
        text: function (e) {
        if (e && this.data && this.data.text) {
        if ($.isFunction(this.data.text)) {
        return this.data.text(e);
        } else {
        return e[this.data.text];
        }
        } else {
        return e.text;
        }
        },





        To overwrite them, just add your own functions inside the object you are passing to .selecte2:



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText }
        ......
        });




        Updates



        What else is happening :




        However, the text of the selected item does not appear in the field after the list closes.




        This means .selectChoice has been successfully executed. Now the problem lies in .updateSelection. In the source code:



           updateSelection: function (data) {

        var container=this.selection.find(".select2-chosen"), formatted, cssClass;

        this.selection.data("select2-data", data);

        container.empty();
        if (data !== null) {
        formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
        }
        if (formatted !== undefined) {
        container.append(formatted);
        }
        cssClass=this.opts.formatSelectionCssClass(data, container);
        if (cssClass !== undefined) {
        container.addClass(cssClass);
        }

        this.selection.removeClass("select2-default");

        if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
        this.container.addClass("select2-allowclear");
        }
        }





        From here we can see that, before the corresponding string of text is placed into the input, it would call formatSelection.



        formatSelection: function (data, container, escapeMarkup) {
        return data ? escapeMarkup(this.text(data)) : undefined;
        },


        Update: Solution



        Previously I thought this.text(data) can be overwritten by having text: funcion(item){ ... } in the parameters, but sadly it doesn't work that way.



        Therefore to render the text properly in the field, you should overwrite formatSelection by doing



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        formatSelection: function (item) { return item.ItemText }
        //......
        });


        instead of trying to overwrite text (which should supposedly have the same effect but this way of overwriting is not yet supported/implemented in the library)



        $('#mySelect').select2({
        id: function (item) { return item.ItemId },
        text: function (item) { return item.ItemText } //this will not work.
        //......
        });






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 29 '16 at 12:33

























        answered Sep 29 '14 at 14:49









        Archy Wilhes

        6,66342040




        6,66342040












        • This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
          – user70192
          Sep 29 '14 at 17:02










        • @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
          – Danillo Corvalan
          Sep 29 '14 at 20:34






        • 2




          Endless answer...
          – dani24
          Feb 15 '16 at 14:02






        • 1




          sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
          – Tobias Weichart
          Aug 9 '16 at 6:55






        • 1




          Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
          – HPWD
          Apr 24 at 0:31


















        • This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
          – user70192
          Sep 29 '14 at 17:02










        • @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
          – Danillo Corvalan
          Sep 29 '14 at 20:34






        • 2




          Endless answer...
          – dani24
          Feb 15 '16 at 14:02






        • 1




          sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
          – Tobias Weichart
          Aug 9 '16 at 6:55






        • 1




          Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
          – HPWD
          Apr 24 at 0:31
















        This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
        – user70192
        Sep 29 '14 at 17:02




        This approach at least closes the drop down list. However, the text of the selected item does not appear in the field after the list closes. Why not?
        – user70192
        Sep 29 '14 at 17:02












        @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
        – Danillo Corvalan
        Sep 29 '14 at 20:34




        @user70192 this is because of formatSelection function you have to provide, like I said in my answer below. I had the same issue reporducing the error
        – Danillo Corvalan
        Sep 29 '14 at 20:34




        2




        2




        Endless answer...
        – dani24
        Feb 15 '16 at 14:02




        Endless answer...
        – dani24
        Feb 15 '16 at 14:02




        1




        1




        sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
        – Tobias Weichart
        Aug 9 '16 at 6:55




        sorry to tell, but this answer actually killed my desire to ever use select2^^ i mean the answer may be correct, but the work to put into a simple display of an array is absolutely not worth the pain ;-)
        – Tobias Weichart
        Aug 9 '16 at 6:55




        1




        1




        Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
        – HPWD
        Apr 24 at 0:31




        Yes, this was a long answer but Archy demonstrates how to walk through this plugin and figure out what's going on with the code (a practice I know I need to do more often). I almost didn't read it but ultimately I am glad I did as it did help me find my problem but more so UNDERSTAND why my code wasn't working. A++
        – HPWD
        Apr 24 at 0:31












        up vote
        8
        down vote













        The issue you are facing is that select2 wants all your results to have an id property. If they don't you need to initialise with an id function which returns the id from each result.



        It will not allow you to select a result unless you satisfy one of these. So in the case of your example :



        function getItemFormat(item) {
        var format = '<div>' + item.ItemName + '</div>';
        return format;
        }

        $(function() {
        $('#mySelect').select2({
        minimumInputLength: 5,
        placeholder: 'Search for an item',
        allowClear: true,
        id: function(item) { return item.ItemId; }, /* <-- ADDED FUNCTION */
        ajax: {
        url: '/api/getItems',
        dataType: 'json',
        quietMillis: 250,
        data: function (term, page) {
        return {
        query: term
        };
        },
        results: function (data, page) {
        return { results: data, id: 'ItemId', text: 'ItemText' };
        }
        },
        formatResult: getItemFormat,
        dropdownCssClass: "bigdrop",
        escapeMarkup: function (m) { return m; }
        });
        });





        share|improve this answer

























          up vote
          8
          down vote













          The issue you are facing is that select2 wants all your results to have an id property. If they don't you need to initialise with an id function which returns the id from each result.



          It will not allow you to select a result unless you satisfy one of these. So in the case of your example :



          function getItemFormat(item) {
          var format = '<div>' + item.ItemName + '</div>';
          return format;
          }

          $(function() {
          $('#mySelect').select2({
          minimumInputLength: 5,
          placeholder: 'Search for an item',
          allowClear: true,
          id: function(item) { return item.ItemId; }, /* <-- ADDED FUNCTION */
          ajax: {
          url: '/api/getItems',
          dataType: 'json',
          quietMillis: 250,
          data: function (term, page) {
          return {
          query: term
          };
          },
          results: function (data, page) {
          return { results: data, id: 'ItemId', text: 'ItemText' };
          }
          },
          formatResult: getItemFormat,
          dropdownCssClass: "bigdrop",
          escapeMarkup: function (m) { return m; }
          });
          });





          share|improve this answer























            up vote
            8
            down vote










            up vote
            8
            down vote









            The issue you are facing is that select2 wants all your results to have an id property. If they don't you need to initialise with an id function which returns the id from each result.



            It will not allow you to select a result unless you satisfy one of these. So in the case of your example :



            function getItemFormat(item) {
            var format = '<div>' + item.ItemName + '</div>';
            return format;
            }

            $(function() {
            $('#mySelect').select2({
            minimumInputLength: 5,
            placeholder: 'Search for an item',
            allowClear: true,
            id: function(item) { return item.ItemId; }, /* <-- ADDED FUNCTION */
            ajax: {
            url: '/api/getItems',
            dataType: 'json',
            quietMillis: 250,
            data: function (term, page) {
            return {
            query: term
            };
            },
            results: function (data, page) {
            return { results: data, id: 'ItemId', text: 'ItemText' };
            }
            },
            formatResult: getItemFormat,
            dropdownCssClass: "bigdrop",
            escapeMarkup: function (m) { return m; }
            });
            });





            share|improve this answer












            The issue you are facing is that select2 wants all your results to have an id property. If they don't you need to initialise with an id function which returns the id from each result.



            It will not allow you to select a result unless you satisfy one of these. So in the case of your example :



            function getItemFormat(item) {
            var format = '<div>' + item.ItemName + '</div>';
            return format;
            }

            $(function() {
            $('#mySelect').select2({
            minimumInputLength: 5,
            placeholder: 'Search for an item',
            allowClear: true,
            id: function(item) { return item.ItemId; }, /* <-- ADDED FUNCTION */
            ajax: {
            url: '/api/getItems',
            dataType: 'json',
            quietMillis: 250,
            data: function (term, page) {
            return {
            query: term
            };
            },
            results: function (data, page) {
            return { results: data, id: 'ItemId', text: 'ItemText' };
            }
            },
            formatResult: getItemFormat,
            dropdownCssClass: "bigdrop",
            escapeMarkup: function (m) { return m; }
            });
            });






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 29 '14 at 14:37









            itsmejodie

            3,16311217




            3,16311217






















                up vote
                2
                down vote













                You need to provide an ID that returns from your API like @itsmejodie said.
                The other problem is that you have to provide select2 formatResult and formatSelection functions, once you have it loaded from Ajax but you can't put html on that. e.g.:



                function format (item) { 
                return item.name;
                }

                $(function() {
                $('#mySelect').select2({
                minimumInputLength: 2,
                placeholder: 'Search for an item',
                allowClear: true,
                ajax: {
                url: '/api/getItems',
                dataType: 'jsonp',
                quietMillis: 250,
                data: function (term, page) {
                return {
                query: term
                };
                },
                results: function (data, page) {
                return { results: data };
                }
                },
                formatResult: format,
                formatSelection: format
                });
                });





                share|improve this answer

























                  up vote
                  2
                  down vote













                  You need to provide an ID that returns from your API like @itsmejodie said.
                  The other problem is that you have to provide select2 formatResult and formatSelection functions, once you have it loaded from Ajax but you can't put html on that. e.g.:



                  function format (item) { 
                  return item.name;
                  }

                  $(function() {
                  $('#mySelect').select2({
                  minimumInputLength: 2,
                  placeholder: 'Search for an item',
                  allowClear: true,
                  ajax: {
                  url: '/api/getItems',
                  dataType: 'jsonp',
                  quietMillis: 250,
                  data: function (term, page) {
                  return {
                  query: term
                  };
                  },
                  results: function (data, page) {
                  return { results: data };
                  }
                  },
                  formatResult: format,
                  formatSelection: format
                  });
                  });





                  share|improve this answer























                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    You need to provide an ID that returns from your API like @itsmejodie said.
                    The other problem is that you have to provide select2 formatResult and formatSelection functions, once you have it loaded from Ajax but you can't put html on that. e.g.:



                    function format (item) { 
                    return item.name;
                    }

                    $(function() {
                    $('#mySelect').select2({
                    minimumInputLength: 2,
                    placeholder: 'Search for an item',
                    allowClear: true,
                    ajax: {
                    url: '/api/getItems',
                    dataType: 'jsonp',
                    quietMillis: 250,
                    data: function (term, page) {
                    return {
                    query: term
                    };
                    },
                    results: function (data, page) {
                    return { results: data };
                    }
                    },
                    formatResult: format,
                    formatSelection: format
                    });
                    });





                    share|improve this answer












                    You need to provide an ID that returns from your API like @itsmejodie said.
                    The other problem is that you have to provide select2 formatResult and formatSelection functions, once you have it loaded from Ajax but you can't put html on that. e.g.:



                    function format (item) { 
                    return item.name;
                    }

                    $(function() {
                    $('#mySelect').select2({
                    minimumInputLength: 2,
                    placeholder: 'Search for an item',
                    allowClear: true,
                    ajax: {
                    url: '/api/getItems',
                    dataType: 'jsonp',
                    quietMillis: 250,
                    data: function (term, page) {
                    return {
                    query: term
                    };
                    },
                    results: function (data, page) {
                    return { results: data };
                    }
                    },
                    formatResult: format,
                    formatSelection: format
                    });
                    });






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 29 '14 at 16:10









                    Danillo Corvalan

                    4011818




                    4011818






















                        up vote
                        0
                        down vote













                        For version 4 of Select2 use



                        processResults: function (data) { 


                        instead of



                        results: function (data) {





                        share|improve this answer

























                          up vote
                          0
                          down vote













                          For version 4 of Select2 use



                          processResults: function (data) { 


                          instead of



                          results: function (data) {





                          share|improve this answer























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            For version 4 of Select2 use



                            processResults: function (data) { 


                            instead of



                            results: function (data) {





                            share|improve this answer












                            For version 4 of Select2 use



                            processResults: function (data) { 


                            instead of



                            results: function (data) {






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 20 at 11:06









                            Manic Depression

                            465822




                            465822






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26074414%2funable-to-select-item-in-select2-drop-down%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                404 Error Contact Form 7 ajax form submitting

                                How to know if a Active Directory user can login interactively

                                TypeError: fit_transform() missing 1 required positional argument: 'X'