As the title suggests I would like to load remote data once only. I thought about loading a data with independent ajax call and set it "locally" at the control but wonder if there is more "built in" way to do so...
As the title suggests I would like to load remote data once only. I thought about loading a data with independent ajax call and set it "locally" at the control but wonder if there is more "built in" way to do so...
Share Improve this question asked Dec 20, 2013 at 10:30 YaronYaron 2,7194 gold badges21 silver badges35 bronze badges 1 |4 Answers
Reset to default 10a solution can be found here:
https://github.com/ivaynberg/select2/issues/110
$("#selIUT").select2({
cacheDataSource: [],
placeholder: "Please enter the name",
query: function(query) {
self = this;
var key = query.term;
var cachedData = self.cacheDataSource[key];
if(cachedData) {
query.callback({results: cachedData.result});
return;
} else {
$.ajax({
url: '/ajax/suggest/',
data: { q : query.term },
dataType: 'json',
type: 'GET',
success: function(data) {
self.cacheDataSource[key] = data;
query.callback({results: data.result});
}
})
}
},
width: '250px',
formatResult: formatResult,
formatSelection: formatSelection,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
Edit:
I might have misinterpreted your question. if you wish to load all data once, then use that is Select2, there is no built in functionality to do that.
Your suggestion to do a single query, and then use that stored data in Select2 would be the way to go.
This is for Select2 v4.0.3:
I had this same question and got around it by triggering an AJAX call and using the data returned as the initialized data array.
// I used an onClick event to fire the AJAX, but this can be attached to any event.
// Ensure ajax call is done *ONCE* with the "one" method.
$('#mySelect').one('click', function(e) {
// Text to let user know data is being loaded for long requests.
$('#mySelect option:eq(0)').text('Data is being loaded...');
$.ajax({
type: 'POST',
url: '/RetrieveDropdownOptions',
data: {}, // Any data that is needed to pass to the controller
dataType: 'json',
success: function(returnedData) {
// Clear the notification text of the option.
$('#mySelect option:eq(0)').text('');
// Initialize the Select2 with the data returned from the AJAX.
$('#mySelect').select2({ data: returnedData });
// Open the Select2.
$('#mySelect').select2('open');
}
});
// Blur the select to register the text change of the option.
$(this).blur();
});
This worked well for what I had in mind. Hope this helps people searching with the same question.
To load data once:
Assumptions:
You have a REST API endpoint at /services that serves a JSON array of objects
The array contains objects which have at least a "name" and "id" attribute. Example:
[{"id": 0, "name": "Foo"}, {"id": 1, "name": "Bar"}]
You want to store that array as the global 'services_raw'
First, our function to load the data and create the global 'services_raw' (AKA 'window.services_raw'):
fetchFromAPI = function() {
console.log("fetchFromAPI called");
var jqxhr = $.ajax(
{
dataType:'json',
type: 'GET',
url: "/services",
success: function(data, textStatus, jqXHR) {
services_raw = data;
console.log("rosetta.fn.fetchServicesFromAPI SUCCESS");
rosetta.fn.refreshServicesSelect();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Error inside rosetta.fn.fetchServicesFromAPI", errorThrown, textStatus, jqXHR);
setTimeout(rosetta.fn.fetchServicesFromAPI(), 3000); // retry in 3 seconds
}
}
)
.done(function () {
console.log("success");
console.log(jqxhr);
})
.fail(function () {
console.log("error");
})
.always(function () {
console.log("complete");
});
// Perform other work here ...
// Set another completion function for the request above
jqxhr.always(function () {
console.log("second complete");
});
};
Second, our Select2 instantiation code which transforms our data into a format that Select2 can work with:
refreshServicesSelect = function () {
// ref: http://jsfiddle.net/RVnfn/2/
// ref2: http://jsfiddle.net/RVnfn/101/ # mine
// ref3: http://jsfiddle.net/RVnfn/102/ # also mine
console.log('refreshServicesSelect called');
$("#add-service-select-service").select2({
// allowClear: true
data: function() {
var arr = []; // container for the results we're returning to Select2 for display
for (var idx in services_raw) {
var item = services_raw[idx];
arr.push({
id: item.id,
text: item.name,
_raw: item // for convenience
});
}
return {results: arr};
}
});
};
Here's what the Select2 element in HTML should look like before your call the above functions:
<input id="add-service-select-service" type="hidden" style="width:100%">
To use all of this, call (in JS):
window.fetchFromAPI();
window.refreshServicesSelect();
Lastly, here's a JSFiddle where you can play with a similar thing: http://jsfiddle.net/RVnfn/102/
Basically, in my example above, we're just using ajax to populate the equivalent of window.pills in the Fiddle.
Hope this helps :)
Please reply if you know how to do this via the Select2 .ajax function, as that would be a bit shorter.
In my condition, it is working perfectly with the given code
$('#itemid').select2({
cacheDataSource: [],
closeOnSelect: true,
minimumInputLength: 3,
placeholder: "Search Barcode / Name",
query: function(query) {
// console.log(query);
self = this;
var key = query.term;
var cachedData = self.cacheDataSource[key];
if(cachedData) {
query.callback({results: cachedData});
return;
} else {
$.ajax({
url: "./includes/getItemSelect2.php",
data: { value : query.term },
dataType: 'json',
type: 'POST',
success: function(data) {
self.cacheDataSource[key] = data;
query.callback({results: data});
}
});
}
},
});
And my data return from the ajax is in this form
<?php
$arr = [
["id" => 1, "text" => "Testing"],
["id" => 2, "text" => "test2"],
["id" => 3, "text" => "test3"],
["id" => 4, "text" => "test4"],
["id" => 5, "text" => "test5"]
];
echo json_encode($arr);
exit();
?>
select2
which gives you that flexibility, the only way of doing it would be to control the ajax call based on whether it has been called earlier or not.this controlling should be within theinitselection:
of select2 – dreamweiver Commented Dec 20, 2013 at 10:45