Ответ 1
Это обеспечило простое решение: Установите данные в Select2 после вставки с помощью AJAX
$("#select2").select2('data', {id: newID, text: newText});
У меня есть элемент управления jQuery Select2, который использует AJAX для заполнения:
<input type="text" name="select2" id="select2" style='width:400px' value="999">
var initialSelection = { id: '999', text:"Some initial option"};
$("#select2").select2({
placeholder: "Select Option",
minimumInputLength: 2,
ajax: {
url: "/servletToGetMyData",
dataType: 'json',
data: function (term, page) { return { term: term }; },
results: function (data, page) { return { results: data.results} }
},
initSelection : function(element, callback){ callback(initialSelection); },
escapeMarkup: function (m) { return m; }
});
AJAX ссылается на базу данных возможных параметров, и, как вы можете видеть, требуется два символа ввода.
Проблема заключается в том, что пользователь может использовать диалог для добавления новой опции, если опция не существует в базе данных. По возвращении из этого диалога я пытаюсь:
var o = $("<option/>", {value: newID, text: newText});
$('#select2').append(o);
$('#select2 option[value="' + newID + '"]').prop('selected',true);
$('#select2').trigger('change');
Но это не сработает. Тот же самый точный код работает для не-AJAX Select2. Я пробовал различные альтернативы, например, используя $('#select2').select2("val", newID);
, но он не работает.
Я даже попытался полностью удалить элемент управления Select2. Однако $('#select2').remove()
удаляет только исходный <input> но оставляет элемент управления Select2 затяжным. Обратите внимание, что на странице есть несколько элементов управления Select2, поэтому я не могу использовать селектор классов для элементов управления Select2, поскольку он удалит другие элементы управления, которые мне нужны.
Любая идея: либо a) динамически добавить опцию в элемент управления Select2, который использует AJAX; или b) полностью удалить элемент управления Select2, чтобы его можно было программно добавить обратно? Или любое другое решение...
Edit Я нашел еще один вопрос, который показывает, как удалить элемент select2, используя .select2 ( "destroy" ). Это работает, но, на мой взгляд, субоптимально. Я бы предпочел бы просто добавить этот вариант, кроме как уничтожить и воссоздать select2.
Это обеспечило простое решение: Установите данные в Select2 после вставки с помощью AJAX
$("#select2").select2('data', {id: newID, text: newText});
Это намного проще сделать, начиная с select2 v4. Вы можете создать new Option
и добавить его к элементу select
напрямую. См. Мой codepen или пример ниже:
$(document).ready(function() {
$("#state").select2({
tags: true
});
$("#btn-add-state").on("click", function(){
var newStateVal = $("#new-state").val();
// Set the value, creating a new option if necessary
if ($("#state").find("option[value=" + newStateVal + "]").length) {
$("#state").val(newStateVal).trigger("change");
} else {
// Create the DOM option that is pre-selected by default
var newState = new Option(newStateVal, newStateVal, true, true);
// Append it to the select
$("#state").append(newState).trigger('change');
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>
<select id="state" class="js-example-basic-single" type="text" style="width:90%">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>
<br>
<br>
<input id="new-state" type="text" />
<button type="button" id="btn-add-state">Set state value</button>
В Select2 4.0.2
$("#yourId").append("<option value='"+item+"' selected>"+item+"</option>");
$('#yourId').trigger('change');
В случае версии Select2 4+
он изменил синтаксис, и вам нужно написать так:
// clear all option
$('#select_with_blank_data').html('').select2({data: [{id: '', text: ''}]});
// clear and add new option
$("#select_with_data").html('').select2({data: [
{id: '', text: ''},
{id: '1', text: 'Facebook'},
{id: '2', text: 'Youtube'},
{id: '3', text: 'Instagram'},
{id: '4', text: 'Pinterest'}]});
// append option
$("#select_with_data").append('<option value="5">Twitter</option>');
$("#select_with_data").val('5');
$("#select_with_data").trigger('change');
Я разрешил проблему с помощью этой ссылки http://www.bootply.com/122726. надеюсь, поможет вам
Добавить параметр в select2 jquery и связать ваш вызов ajax с созданным идентификатором ссылки (#addNew) для новой опции из бэкэнд. и код
$.getScript('http://ivaynberg.github.io/select2/select2-3.4.5/select2.js',function(){
$("#mySel").select2({
width:'240px',
allowClear:true,
formatNoMatches: function(term) {
/* customize the no matches output */
return "<input class='form-control' id='newTerm' value='"+term+"'><a href='#' id='addNew' class='btn btn-default'>Create</a>"
}
})
.parent().find('.select2-with-searchbox').on('click','#addNew',function(){
/* add the new term */
var newTerm = $('#newTerm').val();
//alert('adding:'+newTerm);
$('<option>'+newTerm+'</option>').appendTo('#mySel');
$('#mySel').select2('val',newTerm); // select the new term
$("#mySel").select2('close'); // close the dropdown
})
});
<div class="container">
<h3>Select2 - Add new term when no search matches</h3>
<select id="mySel">
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
<option>Five</option>
<option>Six</option>
<option>Twenty Four</option>
</select>
<br>
<br>
</div>
Продолжение на Bumptious Q Ответ Банвистл:
$('#select2').append($('<option>', {
value: item,
text : item
})).select2();
Это добавит новые параметры в теги <select>
и позволит select2 повторно отобразить его.
Я сделал это так, и это сработало для меня как шарм.
var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2,
text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];
$(".js-example-data-array").select2({
data: data
})
$("#my_select").select2('destroy').empty().select2({data: [{id: 1, text: "new_item"}]});
Чтобы заставить динамические теги работать с ajax, вот что я сделал.
Select2 версия 3.5
Это легко сделать в версии 3.5, потому что она предлагает хук createSearchChoice
. Он даже работает для множественного выбора, если заданы multiple: true
и tags: true
.
HTML
<input type="hidden" name="locations" value="Whistler, BC" />
JS
$('input[name="locations"]').select2({
tags: true,
multiple: true,
createSearchChoice: function(term, data) {
if (!data.length)
return { id: term, text: term };
},
ajax: {
url: '/api/v1.1/locations',
dataType: 'json'
}
});
Идея здесь заключается в использовании хука select2 createSearchChoice
который передает вам как введенный пользователем term
, так и ответ ajax (как data
). Если ajax возвращает пустой список, скажите select2, чтобы предложить введенный пользователем term
в качестве опции.
Демо: https://johnny.netlify.com/select2-examples/version3
Select2 версия 4.X
Версия 4.X больше не имеет хука createSearchChoice
, но вот как я сделал то же самое.
HTML
<select name="locations" multiple>
<option value="Whistler, BC" selected>Whistler, BC</option>
</select>
JS
$('select[name="locations"]').select2({
ajax: {
url: '/api/v1.1/locations',
dataType: 'json',
data: function(params) {
this.data('term', params.term);
return params;
},
processResults: function(data) {
if (data.length)
return {
results: data
};
else
return {
results: [{ id: this.$element.data('term'), text: this.$element.data('term') }]
};
}
}
});
Идея состоит в том, чтобы спрятать термин, который пользователь ввел в хранилище данных jQuery, внутри хука data
select2. Затем в хуке select2 processResults
я проверяю, пустой ли ответ ajax. Если это так, я беру потерянный термин, введенный пользователем, и возвращаю его в качестве опции select2.