select2: Disable case-sensitive matches

你离开我真会死。 提交于 2019-12-08 06:45:52

问题


I'm trying to allow only one value within select2 library, no matter how it's written. For example if the value "Test" is in the data list, "test" should not be added again. I've searched for a while and also looked at the documentation, but I didn't solve this one.

        $("#timezones").select2({
            tags: true,
            createTag: function (tag) {
                return {
                    id: tag.term,
                    text: tag.term + " (new)",
                    isNew: true
                };
            },
            matcher: function (term, data) {
                // `term.term` should be the term that is used for searching
                // `data.text` is the text that is displayed for the data object
                if ($.trim(term.term) === '') {
                    return data;
                }

                var termString = term.term.trim();
                var textString = data.text.trim();
                var termStringUpper;
                var textStringUpper;

                if (termString) termStringUpper = termString.toUpperCase();
                if (textString) textStringUpper = textString.toUpperCase();

                return termStringUpper == textStringUpper;
            }
        });

Here is one JSFiddle: https://jsfiddle.net/2sz0oj8m/


回答1:


The issue is that you are running all the comparisons in the matcher method when you should be running them in the createTag method:

  • By default, matcher is case insensitive and you don't need to ran any special code for that. Notice that if you remove the function, and type "test", the suggestions will include "Test" (with a capital T even when you wrote it with a lower case t).

  • createTag specifies the actions that will be run to suggest a new tag creation. It is executed with each change in the textbox (as specified here) and not when there is not a match.

So the solution would be to:

  1. Remove the matcher method.
  2. Add the case comparison to the createTag method.
  3. Only return the new suggestion if no case-insensitive match was found.

The result would be like this:

$("#timezones").select2({
    tags: true,
    createTag: function (tag) {

        // Check if the option is already there
        var found = false;
        $("#timezones option").each(function() {
            if ($.trim(tag.term).toUpperCase() === $.trim($(this).text()).toUpperCase()) {
                found = true;
            }
        });

        // Show the suggestion only if a match was not found
        if (!found) {
            return {
                id: tag.term,
                text: tag.term + " (new)",
                isNew: true
            };
        }
    }
});

And you can see it running on this update of your JSFiddle: https://jsfiddle.net/2sz0oj8m/1/ (type "test" and you'll see how the suggestion doesn't show up for that particular value).

EDIT: This solution is not compatible with remote data source, you may want to store last values or directly check in ajax results if tag is existing.




回答2:


For remote data source and tags:true, I did the following code:

$('selector').select2({
    tags: true,
    createTag: function ($params) {
        var $term = $.trim($params.term);
        if ($term === '') {
          return null;
        }

        return {
          id: $term,
          text: $term,
          newTag: true // add additional parameters
        }
    },
    insertTag: function(data, tag) {
        var $found = false;
        $.each(data, function(index, value) {
            if($.trim(tag.text).toUpperCase() == $.trim(value.text).toUpperCase()) {
                $found = true;
            }
        });

        if(!$found) data.unshift(tag);
    },
    // .. other select2 options include remote options 
});
  • Note: The code above is for Select2 4.0.x


来源:https://stackoverflow.com/questions/30944275/select2-disable-case-sensitive-matches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!