How to pre-load an array via ajax and use it for select2?

混江龙づ霸主 提交于 2019-12-24 13:16:04

问题


My general problem is that I want to have a Javascript variable which I then use with select2, to prepare the options for a select multiple. I have a fairly large array (7000 objects) and just want to store that once in a variable rather than constantly polling the server with search terms. Here is what I got.

The HTML is simply:

<input type="hidden" id="group_a" multiple="multiple" placeholder="Select at least two treatments">

Now, when I write the variable directly everything works as expected:

var treatments = [{id: 1, text: "you"}, {id: 2, text: "me"}];
$("#group_a").select2({
    data: treatments,
    minimumInputLength: 1,
    multiple: true,
    closeOnSelect: false,
    width: "660px"
});

However, when I use ajax to load the array things get weird. My code to do that:

$.ajax({
    url: '/funny/url',
}).done(function(data) {
    treatments = data.choices;
});

I tend to get the following error unless I use the debugger to step through the code, then it works as expected. So could this somehow be a timing issue?

uncaught exception: query function not defined for Select2 group_a

My complete javascript looks like below and I've also prepared a fiddle which shows the same error.

$(document).ready(function() {
    var treatments;
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        treatments = data.choices;
    });
    $("#group_a").select2({
        data: treatments,
        minimumInputLength: 1,
        multiple: true,
        closeOnSelect: false,
        width: "960px"
    });
});

回答1:


The ajax call is asynchronous, so at the time you are instrumenting the Select2 control, treatments is still undefined.

You could do the following:

$(document).ready(function() {
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        $("#group_a").select2({
            data: data.choices,
            minimumInputLength: 1,
            multiple: true,
            closeOnSelect: false,
            width: "960px"
        });
    });
});

jsfiddle

Better yet though, I would do the following.

Initially set treatments to an empty array, and use a function for the data option so if treatments is changed, the changes will be picked up by the Select2 control. That way, you can instrument the Select2 control right away, and then update treatments with the data returned by the ajax call. Additionally, you could initially disable the Select2 control, and then enable it when the ajax call returns.

$(document).ready(function() {
    var treatments = [];
    $.ajax({
        url: '/funny/url',
    }).done(function(data) {
        treatments = data.choices;
        $("#group_a").select2('enable', true);
    });
    $("#group_a").select2({
        data: function() { return { results: treatments }; },
        minimumInputLength: 1,
        multiple: true,
        closeOnSelect: false,
        width: "960px"
    }).select2('enable', false);
});

jsfiddle

The third option would be to keep your original code, but make the ajax call synchronous. I recommend not doing that though. When you make an ajax call synchronous, you lock up the entire browser.




回答2:


Here is my solution. Thanks to @John S for the initial approach, but I couldn't get the select2 formatter to parse my array. Select2 box would tell me 'no results found.' I ended up running a for loop through my array and writing out the :id, :text hashes.

Starting with my json ajax call is an array of string 'terms':

// localhost:3000/search/typeahead_terms_all.json    
[
        "Super Term",
        "cool term",
        "killer term",
        "awesome term",
        "try term",
        "param term",
        "try name",
        "Academic Year",
        "grade average",
        "Hello Term",
        "Academic Calendar",
        "kinda cool term",
        "My Term",
    ]

Then the javascript:

$(document).ready(function() {
  var term_names_array = [];
  $.ajax({
    url: '/search/typeahead_terms_all',
  }).done(function(data) {
    // Here I iterate through my array of strings and write out the hash select2 needs
    for (index = 0; index < data.length; ++index) {
      term_names_array.push({ id: index, text: data[index] });
    }
    $('.report_term_input').select2('enable', true);
  });
  $('.report_term_input').select2({
    dataType: 'json',
    data: term_names_array,
    multiple: true,
    width: "500px"
  });
});


来源:https://stackoverflow.com/questions/28498599/how-to-pre-load-an-array-via-ajax-and-use-it-for-select2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!