Aggiorna i dati select2 senza ribuild il controllo

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.

inserisci la descrizione dell'immagine qui

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?

select2 v3.x

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) .


select2 v4: adattatore dati personalizzato

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/


select2 v4: funzione di trasporto ajax

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:

  1. Quando il modello è reso …
  2. Inizia un controllo select2 con i dati di Session.
  3. La funzione @autorun (this.autorun) viene eseguita ogni volta che cambia il valore di Session.get (“select2Data”).
  4. Ogni volta che la sessione cambia, deselezionare le opzioni selezionate2 e ricreare con nuovi dati.

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});