select2下拉,但允许用户的新值?

我想要有一组值的下拉菜单,但也允许用户“select”一个没有列在那里的新值。

我发现select2支持这个,如果你在tokens模式中使用它,但有没有办法做到这一点,而不是令牌?

对于版本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邮件列表上的答案,但现在找不到链接)

@fmpwizard提供的优秀答案适用于Select2 3.5.2及更低版本, 但在4.0.0中不起作用

从很早以来(但也许不像这个问题那么早),Select2支持“标记”:用户可以在其中添加自己的值,如果你允许的话。 这可以通过tags选项来启用,你可以在文档中使用一个例子 。

 $("select").select2({ tags: true }); 

默认情况下,这将创build一个与他们input的search词具有相同文本的选项。 如果要以特殊方式标记对象,可以修改所使用的对象,或者在select对象后远程创build对象。

 $("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; } }); 

为了保持代码的活力,我从他的评论中发布了@rrauenza Fiddle的代码 。

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.0+中不起作用,如果您使用的是ajax,您可以让服务器添加新值作为选项。 所以它会这样工作:

  1. 用户search的价值(这使得一个AJAX请求到服务器)
  2. 如果发现值很大,请返回选项。 如果不只是服务器追加这样的选项: [{"text":" my NEW option)","id":"0"}]
  3. 提交表单时,只需检查该选项是否在数据库中,如果不在保存之前创build它。

@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 
 var text = 'New York Mills'; var term = 'new york mills'; return text.localeCompare(term)===0; 

在大多数情况下,我们需要将值与不敏感寄存器进行比较。 而这段代码将返回false,这将导致在数据库中创build重复的logging。 此外,浏览器Safary不支持String.prototype.localeCompare(),此代码在此浏览器中不起作用。

 return this.text.localeCompare(term)===0; 

将更好地取代

 return this.text.toLowerCase() === term.toLowerCase(); 

感谢您们的帮助,我在Codeigniter II中使用了以下代码,使用select2的3.5.2版本。

 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]'}; } }, });