问题
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