Нужна была возможность добавлять новый элемент в список если такого элемента у нас еще не было, благо select2 предусматривает подобную возможность. Загвоздка заключалась только в том что мы использовали список с числовыми id как значение и брался из базы данных. Имеем классическую конструкцию из трех таблиц:
материал(id, ..., ..., ...);
теги(id,...,...,...);
материал_тег(id_material, id_tag);
Так вот, сам select2 мы используем так:
<select id="multiple" class="form-control select2-multiple" multiple name="tags[]" >
{foreach $labels as $label}
<option value="{$label->id}" {if !empty($exists.{$label->id})}selected{/if} >{$label->title}</option>
{/foreach}
</select>
<script>
$(document).ready(function () {
$("#multiple").select2({
placeholder: "Select or add tags",
tags: true,
tokenSeparators: [",", " "],
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0)
{
return { id: term, text:term };
}
}
});
</script>
На стороне сервера я использую фреймворк Laravel 5 и в контроллере использую такую часть кода:
//...
//материал
$record = Linkedin_GroupLabel::find($id);
//...
//Сбрасываем связи с тегами
$record->tags()->detach();
$rtags = array();
foreach ($request->input('tags') as $tag){
//если значение элемента селекта число, значит это id
if (is_numeric($tag)){
$rtags[] = $tag;
}
else //в противном случае это новое значение
{
$new = Linkedin_Label::where('title','=',trim($tag))->first();
if (empty($new->id)){
$new = new Linkedin_Label();
}
$new->title = trim($tag);
$new->save();
$rtags[] = $new->id;
}
}
//аттачим айдишники между записями
$record->tags()->attach($rtags);
Единственное НО при таком, записи тегов не должны быть только числом, иначе is_numeric подумает что добавлен айдишник, а не новый тег.
Очень вероятно что у кого-то есть вариант получше, но данный случай для меня работает.