使用AJAX在select2中进行标记化

79

我正在使用select2进行标记。

我有以下要求:

  1. 我需要使用select2 ajax搜索一些标签。
  2. 我还需要在select2中使用“标签”,允许使用不在列表(Ajax结果)中的值。

这两种情况都可以独立地工作。但是如果将它们组合起来,只会出现aJax值。如果我们键入任何其他不在列表中的值,则会显示“未找到匹配项”。

我的场景是:如果用户输入了任何新值,而该值不在列表中,则允许他们自己创造标签。

有没有办法使这个工作?

4个回答

101

Select2有一个名为“createSearchChoice”的函数:

从用户的搜索词中创建一个新的可选项。允许创建无法通过查询函数获得的选项。在用户可以动态创建选项时非常有用,例如对于“标签”用例。

您可以通过使用以下方式实现所需功能:

createSearchChoice:function(term, data) {
  if ($(data).filter(function() {
    return this.text.localeCompare(term)===0;
  }).length===0) {
    return {id:term, text:term};
  }
},
multiple: true

以下是更完整的答案,返回一个JSON结果给ajax搜索,并允许从术语中创建标签(如果返回没有结果):
$(".select2").select2({
  tags: true,
  tokenSeparators: [",", " "],
  createSearchChoice: function(term, data) {
    if ($(data).filter(function() {
      return this.text.localeCompare(term) === 0;
    }).length === 0) {
      return {
        id: term,
        text: term
      };
    }
  },
  multiple: true,
  ajax: {
    url: '/path/to/results.json',
    dataType: "json",
    data: function(term, page) {
      return {
        q: term
      };
    },
    results: function(data, page) {
      return {
        results: data
      };
    }
  }
});

5
如果您在使用这段代码时遇到困难:$(data).filter函数是进行匹配的地方,而this.text只是返回JSON中text键的值。例如,如果您返回联系人列表,则需要检查this.name。此外,如果您正在远程文件(/path/to/results.json)中进行某种术语匹配,您只需确保返回的项具有所需的属性,并且在从远程文件返回后未定义或格式错误。(哎呀,好答案。谢谢Chris!) - jClark
1
请你看一下这个问题。http://stackoverflow.com/questions/35231584/jquery-select2-duplicate-tag-getting-recreated/35244715?noredirect=1#comment58210873_35244715 - Roxx

39

选择器v4

http://jsfiddle.net/8qL47c1x/2/

HTML:

<select multiple="multiple" class="form-control" id="tags" style="width: 400px;">
    <option value="tag1">tag1</option>
    <option value="tag2">tag2</option>
</select>

JavaScript:

$('#tags').select2({
    tags: true,
    tokenSeparators: [','],
    ajax: {
        url: 'https://api.myjson.com/bins/444cr',
        dataType: 'json',
        processResults: function(data) {
          return {
            results: data
          }
        }
    },

    // Some nice improvements:

    // max tags is 3
    maximumSelectionLength: 3,

    // add "(new tag)" for new tags
    createTag: function (params) {
      var term = $.trim(params.term);

      if (term === '') {
        return null;
      }

      return {
        id: term,
        text: term + ' (new tag)'
      };
    },
});

选择 v3.5.2

带有一些改进的示例:

http://jsfiddle.net/X6V2s/66/

html:

<input type="hidden" id="tags" value="tag1,tag2" style="width: 400px;">

js:

$('#tags').select2({
    tags: true,
    tokenSeparators: [','],
    createSearchChoice: function (term) {
        return {
            id: $.trim(term),
            text: $.trim(term) + ' (new tag)'
        };
    },
    ajax: {
        url: 'https://api.myjson.com/bins/444cr',
        dataType: 'json',
        data: function(term, page) {
            return {
                q: term
            };
        },
        results: function(data, page) {
            return {
                results: data
            };
        }
    },

    // Take default tags from the input value
    initSelection: function (element, callback) {
        var data = [];

        function splitVal(string, separator) {
            var val, i, l;
            if (string === null || string.length < 1) return [];
            val = string.split(separator);
            for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
            return val;
        }

        $(splitVal(element.val(), ",")).each(function () {
            data.push({
                id: this,
                text: this
            });
        });

        callback(data);
    },

    // Some nice improvements:

    // max tags is 3
    maximumSelectionSize: 3,

    // override message for max tags
    formatSelectionTooBig: function (limit) {
        return "Max tags is only " + limit;
    }
});

JSON:

[
  {
    "id": "tag1",
    "text": "tag1"
  },
  {
    "id": "tag2",
    "text": "tag2"
  },
  {
    "id": "tag3",
    "text": "tag3"
  },
  {
    "id": "tag4",
    "text": "tag4"
  }
]

更新于2015-01-22:

修复jsfiddle: http://jsfiddle.net/X6V2s/66/

更新于2015-09-09:

使用Select2 v4.0.0+更加容易。

Select v4.0.0

https://jsfiddle.net/59Lbxvyc/

HTML:

<select class="tags-select" multiple="multiple" style="width: 300px;">
  <option value="tag1" selected="selected">tag1</option>
  <option value="tag2" selected="selected">tag2</option>
</select>

JS:

$(".tags-select").select2({
  // enable tagging
  tags: true,

  // loading remote data
  // see https://select2.github.io/options.html#ajax
  ajax: {
    url: "https://api.myjson.com/bins/444cr",
    processResults: function (data, page) {
      return {
        results: data
      };
    }
  }
});

@faost 能否请您看一下这个问题。如果可以的话,http://stackoverflow.com/questions/35216302/jquery-select2-error-in-getting-data-from-php-mysql - Roxx
3
@faost: 在你的演示中,select2 v4.0.0 的自动完成功能无法工作,也无法过滤/查找单词。 - ಠ_ಠ
1
@ಠ_ಠ select2将搜索词作为查询参数发送,在我的示例请求中,请求的URL看起来像这样:GET https://api.myjson.com/bins/444cr?q=TEST。但是https://api.myjson.com/bins/444cr是一个静态URL,无法处理查询参数。在真实应用程序中,您的后端将使用这个查询参数"q"来过滤结果。 - alexfv
@faost:你的例子在4.0.3版本(最新版)中不起作用。 - NewCod3r
@alexfv,myjson.com服务已不再提供,也许您可以在示例中使用jsonserve.com代替? - Mark G
显示剩余2条评论

5
createSearchChoice : function (term) { return {id: term, text: term}; }

只需添加此选项项。

4
不应这样做,因为如果已经存在标签,用户会有两个相同的选择,例如来自数据库的“test”和新创建的“test”。您应该检查术语是否已经存在于数据中。 - marxin

0

你可以通过让ajax函数在结果列表中作为第一个返回搜索词,使其能够工作。然后用户就可以将该结果选择为标签。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接