132

我想要一个包含一组值的下拉列表,但也允许用户“选择”一个未在此处列出的新值。

如果您在模式下使用它,我看到select2tags支持这一点,但是有没有办法在不使用标签的情况下做到这一点?

4

9 回答 9

197

@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;
  }
});
于 2015-05-04T00:40:39.083 回答
103

对于版本 4+,请查看Kevin Brown下面的答案

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

于 2013-02-18T20:57:33.440 回答
14

只是为了让代码保持活力,我从他的评论中发布了@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'}]
});
于 2014-04-14T14:40:28.297 回答
12

由于其中许多答案在 4.0+ 中不起作用,因此如果您使用 ajax,您可以让服务器添加新值作为选项。所以它会像这样工作:

  1. 用户搜索值(向服务器发出 ajax 请求)
  2. 如果发现值很好,则返回该选项。如果不只是让服务器像这样附加该选项:[{"text":" my NEW option)","id":"0"}]
  3. 提交表单后,只需检查该选项是否在数据库中,如果没有,则在保存之前创建它。
于 2015-07-27T05:50:22.903 回答
9

我认为现在有一个更好的解决方案

只需在选择选项上将标记设置为 true 吗?

tags: true

来自https://select2.org/tagging

于 2019-05-10T09:38:45.767 回答
4

@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
于 2015-01-10T12:36:24.460 回答
3

感谢大家的帮助,我在 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]'};
        }
    },
});
于 2015-04-26T08:29:31.033 回答
3

我刚刚从凯文布朗那里偶然发现了这个。 https://stackoverflow.com/a/30019966/112680

您所要做的v4.0.6就是使用tags: true参数。

于 2019-03-20T17:01:23.763 回答
1
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

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

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

将更好地替换为

return this.text.toLowerCase() === term.toLowerCase();
于 2015-02-10T09:53:34.270 回答