Обновите данные select2 без перестройки элемента управления
Я конвертирую в выпадающее меню select2 и подаю его данные методом запроса
$('#inputhidden').select2({ query: function( query ) { query.callback( data ); // the data is in the format select2 expects and all works well.. ); });
Проблема в том, что мне нужно взломать пользовательский интерфейс select2 и поместить две кнопки в верхней части панели поиска, которые при нажатии будут выполнять вызовы ajax и должны будут обновить содержимое select2.
- Как установить выбранное значение в Multi-Value Select в JQuery-Select2.?
- Select2 не работает, если он встроен в загрузочный модальный
- Динамически добавлять элемент в элемент управления jQuery Select2, который использует AJAX
- Select2, но разрешить новые значения пользователем?
- Использование bootstrap select2 с формой JqGrid
Теперь мне нужны эти обновления, чтобы не перестраивать select2 полностью, а просто обновлять элементы в раскрывающемся списке. Я не могу найти способ передать новый dataset уже созданному элементу управления select2, возможно ли это?
select2 v3.x
Если у вас есть локальный массив с параметрами (полученными по вызову ajax), я думаю, вы должны использовать параметр data
качестве функции, возвращающей результаты для windows выбора:
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/
В случае, если вы настроили интерфейс select2 с помощью кнопок, просто вызовите updateResults
(этот метод не разрешен для вызова из outsite объекта select2, но вы можете добавить его в allowedMethods
в select2, если вам нужен) после массива данных обновления (например, в примерах) ,
select2 v4: пользовательский адаптер данных
Пользовательский адаптер данных с дополнительными updateOptions
(его непонятно, почему оригинальный ArrayAdapter
не имеет этой функции) метод может использоваться для динамического обновления списка опций (все параметры в этом примере):
$.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: ajax транспортная функция
в v4 вы можете определить настраиваемый метод транспорта, который может работать с локальным массивом данных (например, thx @Caleb_Kiage, я играл с ним без успешных действий)
docs: https://select2.github.io/options.html#can-an-ajax-plugin-other-than-jqueryajax-be-used
Select2 использует метод транспорта, определенный в ajax.transport, для отправки запросов в ваш API. По умолчанию этот метод транспорта – jQuery.ajax, но это можно изменить.
$('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); } } });
НО с помощью этого метода вам нужно изменить идентификаторы опций, если текст опции в массиве изменяется – внутренний список элементов select2 dom не был изменен. Если id опции в массиве останется прежним – предыдущая сохраненная опция будет отображаться вместо обновления из массива! Это не проблема, если массив изменен только путем добавления к нему новых элементов – нормально для большинства распространенных случаев.
FIDDLE: https://jsfiddle.net/xu48n36c/3/
Я думаю, что достаточно передать данные напрямую:
$("#inputhidden").select2("data", data, true);
Обратите внимание, что второй параметр указывает, что требуется обновление.
Спасибо @Bergi за помощь в этом .
Если это не будет автоматически обновляться, вы можете попробовать напрямую обратиться к методу updateResults.
$("#inputhidden").select2("updateResults");
Или вызвать его косвенно, посылая триггер на «input.select2-input» следующим образом:
var search = $("#inputhidden input.select2-input"); search.trigger("input");
Используя Select2 4.0 с Meteor, вы можете сделать что-то вроде этого:
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") })
Что происходит:
- Когда Шаблон визуализируется …
- Инициируйте элемент управления select2 с данными из сеанса.
- Функция @autorun (this.autorun) запускается каждый раз, когда изменяется значение Session.get (“select2Data”).
- Всякий раз, когда сеанс изменяется, очищайте существующие опции select2 и создавайте новые данные.
Это работает для любого реактивного источника данных, такого как Collection.find (). Fetch () – не просто Session.get ().
ПРИМЕЧАНИЕ. Начиная с версии Select2 версии 4.0 вы должны удалить существующие параметры перед добавлением новых onces. См. Этот вопрос GitHub для деталей . Нет способа «обновить параметры» без очистки существующих.
Вышеприведенное является coffeescript. Очень похоже на Javascript.
Я решил эту проблему, используя опцию ajax и указав настраиваемую функцию транспорта.
см. эту скрипту Select2 dynamic options demo
Вот соответствующие js, чтобы заставить это работать.
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”);
Насколько я могу судить, невозможно обновить опции select2 без обновления всего списка или ввода некоторого текста поиска и использования функции запроса.
Что должны делать эти кнопки? Если они используются для определения опций выбора, почему бы не поместить их за пределы поля выбора и попросить их программно установить данные windows выбора и затем открыть его? Я не понимаю, почему вы хотите разместить их поверх windows поиска. Если пользователь не должен искать, вы можете использовать параметр minimumResultsForSearch, чтобы скрыть функцию поиска.
Изменить : как насчет этого …
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);
Пример : Plunker
Изменить 2: это, по крайней мере, позволит обновить список, однако есть еще какая-то странность, если вы ввели текст поиска, прежде чем запускать событие keyup-change
ключа.
Для Select2 4.X
var instance = $('#select2Container').data('select2'); var searchVal = instance.dropdown.$search.val(); instance.trigger('query', {term:searchVal});