Select2, но разрешить новые значения пользователем?
Я хочу иметь раскрывающийся список с набором значений, но также позволяю пользователю "выбирать" новое значение, не указанное в нем.
Я вижу, что select2 поддерживает это, если вы используете его в режиме tokens
, но есть ли способ сделать это, не имея токенов?
Ответы
Ответ 1
Для версии 4+ отметьте этот ответ ниже Кевин Браун
В Select2 3.5.2 и ниже вы можете использовать что-то вроде:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(взято из ответа на список рассылки select2, но не может найти ссылку сейчас)
Ответ 2
отличный ответ, предоставленный @fmpwizard, работает для Select2 3.5.2 и ниже, но он не будет работать в 4.0.0.
С самого начала (но, возможно, не раньше этого вопроса) Select2 поддерживает "тегирование": где пользователи могут добавлять свое значение, если вы разрешаете им это делать. Это можно включить с помощью опции tags
, и вы можете играть с примером в документации.
$("select").select2({
tags: true
});
По умолчанию это создаст параметр, который имеет тот же текст, что и введенный им поисковый запрос. Вы можете изменить объект, который используется, если вы хотите пометить его особым образом или создать объект удаленно после его выбора.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
В дополнение к тому, чтобы использовать как простой флаг для объекта, прошедшего через событие select2:select
, дополнительное свойство также позволяет вам отображать опцию несколько иначе в результате. Поэтому, если вы хотите визуально сигнализировать о том, что это новый вариант, поставив "(новый)" рядом с ним, вы можете сделать что-то вроде этого.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
Ответ 3
Просто ради сохранения кода, я отправляю @rrauenza Fiddle code из его комментарий.
HTML
<input type='hidden' id='tags' style='width:300px'/>
JQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Ответ 4
Так как многие из этих ответов не работают в 4.0+, если вы используете ajax, вы могли бы добавить новое значение в качестве опции. Поэтому он будет работать следующим образом:
- Пользователь выполняет поиск значения (что делает запрос ajax серверу)
- Если значение найдено отлично, верните параметр. Если не просто сервер добавит этот параметр, как это:
[{"text":" my NEW option)","id":"0"}]
- Когда форма отправляется, просто проверьте, не указана ли эта опция в db, и если она не создана перед сохранением.
Ответ 5
Устранить ответ @fmpwizard:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Ответ 6
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
В большинстве случаев нам нужно сравнивать значения с нечувствительным регистром. И этот код вернет false, что приведет к созданию дубликатов записей в базе данных. Кроме того, String.prototype.localeCompare() не поддерживается браузером Safary, и этот код не будет работать в этом браузере;
return this.text.localeCompare(term)===0;
лучше заменить на
return this.text.toLowerCase() === term.toLowerCase();
Ответ 7
Я только что наткнулся на это от Кевина Брауна. fooobar.com/questions/619983/...
Все, что вам нужно сделать для v4.0.6
это использовать tags: true
параметр.
Ответ 8
Спасибо за помощь, ребята, я использовал код ниже в Codeigniter. Я использую версию: 3.5.2 из select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
Ответ 9
Есть лучшее решение, я думаю, что сейчас
просто установить теги в true на выбранных опциях?
tags: true
с https://select2.org/tagging