Sto convertendo un in un dropdown select2 e alimentandolo con il metodo query
$('#inputhidden').select2({ query: function( query ) { query.callback( data ); // the data is in the format select2 expects and all works well.. ); });
Il problema è che avevo bisogno di hackerare l’interfaccia utente select2 e posizionare due pulsanti nella parte superiore della barra di ricerca che, quando si fa clic, eseguirà chiamate ajax e dovrà aggiornare il contenuto di select2.
Ora, ho bisogno che quegli aggiornamenti si verifichino senza ribuild interamente select2 ma piuttosto semplicemente aggiornando gli elementi nel menu a discesa. Non riesco a trovare un modo per passare un nuovo set di dati a un controllo select2 già creato, è ansible?
Se hai un array locale con opzioni (ricevute da una chiamata ajax), penso che dovresti usare data
parametri dei data
come funzione che restituisce i risultati per la casella di selezione:
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/
Nel caso in cui si personalizzi l’interfaccia select2 con i pulsanti, è sufficiente chiamare updateResults
(questo metodo non è autorizzato a chiamare da outsite dell’object select2 ma è ansible aggiungerlo all’array AllowedMethods in select2 se necessario) dopo l’aggiornamento dell’array di dati (pillole nell’esempio) .
L’adattatore dati personalizzato con ulteriori updateOptions
(non è chiaro il motivo per cui l’originale ArrayAdapter
manchi di questa funzionalità) può essere utilizzato per aggiornare dynamicmente l’elenco delle opzioni (tutte le opzioni in questo esempio):
$.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 puoi definire il metodo di trasporto personalizzato che può funzionare con l’array di dati locale (ad esempio, thx @Caleb_Kiage, ho giocato con esso senza successo)
documenti: https://select2.github.io/options.html#can-an-ajax-plugin-other-than-jqueryajax-be-used
Select2 utilizza il metodo di trasporto definito in ajax.transport per inviare richieste all’API. Per impostazione predefinita, questo metodo di trasporto è jQuery.ajax ma può essere modificato.
$('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); } } });
MA con questo metodo è necessario modificare gli id delle opzioni se il testo dell’opzione nella matrice cambia – l’elenco dell’elemento di opzione interno select2 dom non è stato modificato. Se l’id dell’opzione nell’array rimane uguale, verrà visualizzata l’opzione salvata precedente anziché aggiornata dall’array! Questo non è un problema se la matrice viene modificata solo aggiungendo nuovi elementi – ok per i casi più comuni.
FIDDLE: https://jsfiddle.net/xu48n36c/3/
Penso che sia sufficiente consegnare i dati direttamente:
$("#inputhidden").select2("data", data, true);
Si noti che il secondo parametro sembra indicare che è necessario un aggiornamento.
Grazie a @Bergi per l’aiuto con questo .
Se questo non viene aggiornato automaticamente, puoi provare a chiamare direttamente il metodo updateResults.
$("#inputhidden").select2("updateResults");
Oppure triggersrlo indirettamente inviando un trigger all ‘”input.select2-input” in questo modo:
var search = $("#inputhidden input.select2-input"); search.trigger("input");
Usando Select2 4.0 con Meteor puoi fare qualcosa del genere:
Template.TemplateName.rendered = -> $("#select2-el").select2({ data : Session.get("select2Data") }) @autorun -> # Clear the existing list options. $("#select2-el").select2().empty() # Re-create with new options. $("#select2-el").select2({ data : Session.get("select2Data") })
Cosa sta succedendo:
Questo funziona per qualsiasi fonte di dati retriggers, ad esempio Collection.find (). Fetch (), non solo Session.get ().
NOTA: a partire da Select2 versione 4.0 è necessario rimuovere le opzioni esistenti prima di aggiungere nuove forze. Vedi questo problema su GitHub per i dettagli . Non esiste un metodo per “aggiornare le opzioni” senza cancellare quelli esistenti.
Quanto sopra è coffeescript. Molto simile per Javascript.
Ho risolto questo problema utilizzando l’opzione ajax e specificando una funzione di trasporto personalizzata.
guarda questo demo di opzioni dinamiche Select2
Ecco il js pertinente per farlo funzionare.
var $items = []; let options = { ajax: { transport: function(params, success, failure) { let items = $items; if (params.data && params.data.q) { items = items.filter(function(item) { return new RegExp(params.data.q).test(item.text); }); } let promise = new Promise(function(resolve, reject) { resolve({ results: items }); }); promise.then(success); promise.catch(failure); } }, placeholder: 'Select item' }; $('select').select2(options); let count = $items.length + 1; $('button').on('click', function() { $items.push({ id: count, text: 'Item' + count }); count++; });
var selBoxObj = $ (‘# selectpill’); selBoxObj.trigger ( “change.select2”);
Come meglio posso dire, non è ansible aggiornare le opzioni select2 senza aggiornare l’intero elenco o inserire un testo di ricerca e utilizzando una funzione di query.
Cosa dovrebbero fare quei pulsanti? Se vengono utilizzati per determinare le opzioni di selezione, perché non metterli al di fuori della casella di selezione e averli a livello di programmazione impostare i dati della casella di selezione e quindi aprirlo? Non capisco perché vorresti metterli in cima alla casella di ricerca. Se l’utente non deve cercare, puoi utilizzare l’opzione minimumResultsForSearch per hide la funzione di ricerca.
Modifica : Che ne dici di questo …
HTML :
Javascript
var data = [{id: 0, text: "Zero"}], select = $('#select2'); select.select2({ query: function(query) { query.callback({results: data}); }, width: '150px' }); console.log('Opening select2...'); select.select2('open'); setTimeout(function() { console.log('Updating data...'); data = [{id: 1, text: 'One'}]; }, 1500); setTimeout(function() { console.log('Fake keyup-change...'); select.data().select2.search.trigger('keyup-change'); }, 3000);
Esempio : Plunker
Modifica 2: Ciò consentirà almeno di aggiornare l’elenco, tuttavia vi è ancora qualche stranezza se è stato immesso il testo di ricerca prima di triggersre l’evento di keyup-change
della keyup-change
.
Per Select2 4.X
var instance = $('#select2Container').data('select2'); var searchVal = instance.dropdown.$search.val(); instance.trigger('query', {term:searchVal});