Select2 4.0.0 начальное значение с помощью AJAX
у меня есть select2 v4.0.0 заполняется из массива Ajax. Если я установил val select2, я могу видеть через отладку javascript, что он выбрал правильный элемент (#3 в моем случае), однако это не показано в поле выбора, оно все еще показывает заполнитель.

в то время как я должен видеть что-то вроде этого:

в полях моей формы:
<input name="creditor_id" type="hidden" value="3">
<div class="form-group minimal form-gap-after">
<span class="col-xs-3 control-label minimal">
<label for="Creditor:">Creditor:</label>
</span>
<div class="col-xs-9">
<div class="input-group col-xs-8 pull-left select2-bootstrap-prepend">
<select class="creditor_select2 input-xlarge form-control minimal select2 col-xs-8">
<option></option>
</select>
</div>
</div>
</div>
мой javascript:
var initial_creditor_id = "3";
$(".creditor_select2").select2({
ajax: {
url: "/admin/api/transactions/creditorlist",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term,
c_id: initial_creditor_id,
page: params.page
};
},
processResults: function (data, page) {
return {
results: data
};
},
cache: true
},
placeholder: "Search for a Creditor",
width: "element",
theme: "bootstrap",
allowClear: true
}).on("select2:select", function (e) {
var selected = e.params.data;
if (typeof selected !== "undefined") {
$("[name='creditor_id']").val(selected.creditor_id);
$("#allocationsDiv").hide();
$("[name='amount_cash']").val("");
$("[name='amount_cheque']").val("");
$("[name='amount_direct']").val("");
$("[name='amount_creditcard']").val("");
}
}).on("select2:unselecting", function (e) {
$("form").each(function () {
this.reset()
});
("#allocationsDiv").hide();
$("[name='creditor_id']").val("");
}).val(initial_creditor_id);
Как я могу сделать окно выбора показать выбранный элемент, а не прототип? Должен ли я отправлять это как часть ответа AJAX JSON, возможно?
в прошлом для Select2 требовалась опция initselection, которая определялась всякий раз, когда использовался пользовательский источник данных, что позволяло определить начальный выбор для компонента. Это прекрасно работало для меня в v3.5.
11 ответов:
вы делаете большинство вещей правильно, похоже, что единственная проблема, которую вы бьете, заключается в том, что вы не запускаете
changeметод после установки нового значения. Безchangeсобытие, Select2 не может знать, что базовое значение изменилось, поэтому он будет отображать только заполнитель. Изменение последней части на.val(initial_creditor_id).trigger('change');должно исправить вашу проблему, и вы должны увидеть обновление пользовательского интерфейса сразу.
это при условии, что у вас есть
<option>уже естьvalueнаinitial_creditor_id. Если вы не выберете 2, а браузер, фактически не сможет изменить значение, так как нет возможности переключиться, и Select2 не обнаружит новое значение. Я заметил, что ваш<select>содержит только один параметр, один для заполнителя, что означает, что вам нужно будет создать новый<option>вручную.var $option = $("<option selected></option>").val(initial_creditor_id).text("Whatever Select2 should display");а затем добавить его к
<select>что вы инициализировали Select2 on. Вы можете получить текст из внешнего источника, гдеinitSelectionиспользуется для вступления в игру, что по-прежнему возможно с Select2 4.0.0. Как и стандартный select, это означает, что вам придется сделать запрос AJAX для получения значения, а затем установить<option>текст на лету корректировать.var $select = $('.creditor_select2'); $select.select2(/* ... */); // initialize Select2 and any events var $option = $('<option selected>Loading...</option>').val(initial_creditor_id); $select.append($option).trigger('change'); // append the option and update Select2 $.ajax({ // make the request for the selected data object type: 'GET', url: '/api/for/single/creditor/' + initial_creditor_id, dataType: 'json' }).then(function (data) { // Here we should have the data object $option.text(data.text).val(data.id); // update the text that is displayed (and maybe even the value) $option.removeData(); // remove any caching data that might be associated $select.trigger('change'); // notify JavaScript components of possible changes });хотя это может выглядеть как много кода, это именно так вы бы это сделали для не-Select2 установите флажки, чтобы убедиться, что все изменения были сделаны.
то, что я сделал, более чистое и должно сделать два массива:
- один содержит список объектов с идентификатором и текстом (в моем случае его идентификатор и имя, в зависимости от вашего templateResult) (его то, что вы получаете от запроса ajax)
- второй-это только массив идентификаторов (стоимость выбора)
Я инициализирую select2, используя первый массив в качестве данных, а второй в качестве val.
пример функции с параметрами a dict of идентификационное имя.
function initMyList(values) { var selected = []; var initials = []; for (var s in values) { initials.push({id: s, name: values[s].name}); selected.push(s); } $('#myselect2').select2({ data: initials, ajax: { url: "/path/to/value/", dataType: 'json', delay: 250, data: function (params) { return { term: params.term, page: params.page || 1, }; }, processResults: function (data, params) { params.page = params.page || 1; return { results: data.items, pagination: { more: (params.page * 30) < data.total_count } }; }, cache: true }, minimumInputLength: 1, tokenSeparators: [",", " "], placeholder: "Select none, one or many values", templateResult: function (item) { return item.name; }, templateSelection: function (item) { return item.name; }, matcher: function(term, text) { return text.name.toUpperCase().indexOf(term.toUpperCase()) != -1; }, }); $('#myselect2').val(selected).trigger('change'); }вы можете передать значение инициалов с помощью ajax-вызовов и использовать jQuery обещает выполнить инициализацию select2.
вопрос о том, чтобы быть вынужденным
trigger('change')сводили меня с ума, так как у меня был пользовательский кодchangeтриггер, который должен срабатывать только тогда, когда пользователь изменяет параметр в раскрывающемся списке. ИМО, изменение не должно запускаться при установке значения инициализации в начале.я копнул глубоко и нашел следующее:https://github.com/select2/select2/issues/3620
пример:
$dropDown.val(1).trigger('change.select2');
один сценарий, который я не видел, чтобы люди действительно отвечали, - Это как иметь предварительный выбор, когда параметры AJAX sourced, и вы можете выбрать несколько. Поскольку это страница перехода для предварительного выбора AJAX, я добавлю свое решение здесь.
$('#mySelect').select2({ ajax: { url: endpoint, dataType: 'json', data: [ { // Each of these gets processed by fnRenderResults. id: usersId, text: usersFullName, full_name: usersFullName, email: usersEmail, image_url: usersImageUrl, selected: true // Causes the selection to actually get selected. } ], processResults: function(data) { return { results: data.users, pagination: { more: data.next !== null } }; } }, templateResult: fnRenderResults, templateSelection: fnRenderSelection, // Renders the result with my own style selectOnClose: true });
если вы используете templateSelection и ajax, некоторые из этих других ответов могут не работать. Кажется, что создание нового
optionэлемент и заданиеvalueиtextне будет удовлетворять метод шаблона, когда ваши объекты данных используют другие значения, чем id и текст.вот что сработало для меня:
$("#selectElem").select2({ ajax: { ... }, data: [YOUR_DEFAULT_OBJECT], templateSelection: yourCustomTemplate }Проверьте jsFiddle здесь:https://jsfiddle.net/shanabus/f8h1xnv4
в моем случае, я должен был
processResultsв так как мой данные не содержали необходимогоidиtextполя. Если вам нужно сделать это, вам также нужно будет запустить свой первоначальный выбор через ту же функцию. Вот так:$(".js-select2").select2({ ajax: { url: SOME_URL, processResults: processData }, data: processData([YOUR_INIT_OBJECT]).results, minimumInputLength: 1, templateSelection: myCustomTemplate }); function processData(data) { var mapdata = $.map(data, function (obj) { obj.id = obj.Id; obj.text = '[' + obj.Code + '] ' + obj.Description; return obj; }); return { results: mapdata }; } function myCustomTemplate(item) { return '<strong>' + item.Code + '</strong> - ' + item.Description; }
это работает для меня ...
Не используйте jQuery, только HTML: создайте Параметр Значение будет отображаться как избранные. Если ID это select2 data он будет выбран автоматически.
<select id="select2" name="mySelect2"> <option value="mySelectedValue"> Hello, I'm here! </option> </select>
проведя несколько часов в поисках решения, я решил создать свой собственный. Он это:
function CustomInitSelect2(element, options) { if (options.url) { $.ajax({ type: 'GET', url: options.url, dataType: 'json' }).then(function (data) { element.select2({ data: data }); if (options.initialValue) { element.val(options.initialValue).trigger('change'); } }); } }и вы можете инициализировать выбор с помощью этой функции:
$('.select2').each(function (index, element) { var item = $(element); if (item.data('url')) { CustomInitSelect2(item, { url: item.data('url'), initialValue: item.data('value') }); } else { item.select2(); } });и конечно, вот HTML:
<select class="form-control select2" id="test1" data-url="mysite/load" data-value="123"></select>
Я добавляю этот ответ в основном потому, что я не могу прокомментировать выше! Я обнаружил, что это был комментарий @Nicki и ее jsfiddle,https://jsfiddle.net/57co6c95/, что в конечном итоге заставило это работать на меня.
среди прочего, он привел примеры формата для необходимого json. Единственное изменение, которое я должен был сделать, это то, что мои первоначальные результаты были возвращены в том же формате, что и другой вызов ajax, поэтому мне пришлось использовать
$option.text(data[0].text).val(data[0].id);, а не
$option.text(data.text).val(data.id);
создать простой ajax комбо с de начальное значение seleted для select2 4.0.3
<select name="mycombo" id="mycombo""></select> <script> document.addEventListener("DOMContentLoaded", function (event) { selectMaker.create('table', 'idname', '1', $("#mycombo"), 2, 'type'); }); </script>библиотека .js
var selectMaker = { create: function (table, fieldname, initialSelected, input, minimumInputLength = 3, type ='',placeholder = 'Select a element') { if (input.data('select2')) { input.select2("destroy"); } input.select2({ placeholder: placeholder, width: '100%', minimumInputLength: minimumInputLength, containerCssClass: type, dropdownCssClass: type, ajax: { url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type, type: 'post', dataType: 'json', contentType: "application/json", delay: 250, data: function (params) { return { term: params.term, // search term page: params.page }; }, processResults: function (data) { return { results: $.map(data.items, function (item) { return { text: item.name, id: item.id } }) }; } } }); if (initialSelected>0) { var $option = $('<option selected>Cargando...</option>').val(0); input.append($option).trigger('change'); // append the option and update Select2 $.ajax({// make the request for the selected data object type: 'GET', url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type + '&initialSelected=' + initialSelected, dataType: 'json' }).then(function (data) { // Here we should have the data object $option.text(data.items[0].name).val(data.items[0].id); // update the text that is displayed (and maybe even the value) $option.removeData(); // remove any caching data that might be associated input.trigger('change'); // notify JavaScript components of possible changes }); } } };и на стороне php сервера
<?php if (isset($_GET['getQuery']) && isset($_GET['table']) && isset($_GET['fieldname'])) { //parametros carga de petición parse_str(file_get_contents("php://input"), $data); $data = (object) $data; if (isset($data->term)) { $term = pSQL($data->term); }else{ $term = ''; } if (isset($_GET['initialSelected'])){ $id =pSQL($_GET['initialSelected']); }else{ $id = ''; } if ($_GET['table'] == 'mytable' && $_GET['fieldname'] == 'mycolname' && $_GET['type'] == 'mytype') { if (empty($id)){ $where = "and name like '%" . $term . "%'"; }else{ $where = "and id= ".$id; } $rows = yourarrayfunctionfromsql("SELECT id, name FROM yourtable WHERE 1 " . $where . " ORDER BY name "); } $items = array("items" => $rows); $var = json_encode($items); echo $var; ?>
для простого и семантического решения я предпочитаю определять начальное значение в HTML, например:
<select name="myfield" data-placeholder="Select an option"> <option value="initial-value" selected>Initial text</option> </select>поэтому, когда я называю
$('select').select2({ ajax: {...}});начальное значениеinitial-valueи его вариант текстаInitial text.моя текущая версия Select2 4.0.3, но я думаю, она имеет большую совместимость с другими версиями.
Привет почти бросил это и вернулся к выбору 3.5.1. Но в конце концов я получил ответ!
$('#test').select2({ placeholder: "Select a Country", minimumResultsForSearch: 2, ajax: { url: '...', dataType: 'json', cache: false, data: function (params) { var queryParameters = { q: params.term } return queryParameters; }, processResults: function (data) { return { results: data.items }; } } }); var option1 = new Option("new",true, true); $('#status').append(option1); $('#status').trigger('change');просто убедитесь, что новый параметр является одним из параметров select2. Я получаю это от json.
Comments