I am converting an <input type="hidden">
to a select2 dropdown and feeding it data through the query method
$('#inputhidden').select2({
query: function( query ) {
query.callback( data ); // the data is in the format select2 expects and all works well..
);
});
The problem is i needed to hack the select2 UI and position two buttons on top of the search bar that, when clicked, will perform ajax calls and will have to update the select2 content.
Now, I need those updates to occur without rebuilding the select2 entirely but rather just refreshing the items on the dropdown. I cannot find a way to pass a new set of data to an already created select2 control, is that possible ?
If you have local array with options (received by ajax call), i think you should use data
parameter as function returning results for select box:
var pills = [{id:0, text: "red"}, {id:1, text: "blue"}];
$('#selectpill').select2({
placeholder: "Select a pill",
data: function() { return {results: pills}; }
});
$('#uppercase').click(function() {
$.each(pills, function(idx, val) {
pills[idx].text = val.text.toUpperCase();
});
});
$('#newresults').click(function() {
pills = [{id:0, text: "white"}, {id:1, text: "black"}];
});
FIDDLE: http://jsfiddle.net/RVnfn/576/
In case if you customize select2 interface with buttons, just call updateResults
(this method not allowed to call from outsite of select2 object but you can add it to allowedMethods
array in select2 if you need to) method after updateting data array(pills in example).
Custom data adapter with additional updateOptions
(its unclear why original ArrayAdapter
lacks this functionality) method can be used to dynamically update options list (all options in this example):
$.fn.select2.amd.define('select2/data/customAdapter',
['select2/data/array', 'select2/utils'],
function (ArrayAdapter, Utils) {
function CustomDataAdapter ($element, options) {
CustomDataAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomDataAdapter, ArrayAdapter);
CustomDataAdapter.prototype.updateOptions = function (data) {
this.$element.find('option').remove(); // remove all options
this.addOptions(this.convertToOptions(data));
}
return CustomDataAdapter;
}
);
var customAdapter = $.fn.select2.amd.require('select2/data/customAdapter');
var sel = $('select').select2({
dataAdapter: customAdapter,
data: pills
});
$('#uppercase').click(function() {
$.each(pills, function(idx, val) {
pills[idx].text = val.text.toUpperCase();
});
sel.data('select2').dataAdapter.updateOptions(pills);
});
FIDDLE: https://jsfiddle.net/xu48n36c/1/
in v4 you can define custom transport method that can work with local data array (thx @Caleb_Kiage for example, i've played with it without succes)
docs: https://select2.github.io/options.html#can-an-ajax-plugin-other-than-jqueryajax-be-used
Select2 uses the transport method defined in ajax.transport to send requests to your API. By default, this transport method is jQuery.ajax but this can be changed.
$('select').select2({
ajax: {
transport: function(params, success, failure) {
var items = pills;
// fitering if params.data.q available
if (params.data && params.data.q) {
items = items.filter(function(item) {
return new RegExp(params.data.q).test(item.text);
});
}
var promise = new Promise(function(resolve, reject) {
resolve({results: items});
});
promise.then(success);
promise.catch(failure);
}
}
});
BUT with this method you need to change ids of options if text of option in array changes - internal select2 dom option element list did not modified. If id of option in array stay same - previous saved option will be displayed instead of updated from array! That is not problem if array modified only by adding new items to it - ok for most common cases.
FIDDLE: https://jsfiddle.net/xu48n36c/3/