【问题标题】:Is it possible to paste a list to a select2 field and match each item in the list?是否可以将列表粘贴到 select2 字段并匹配列表中的每个项目?
【发布时间】:2013-06-16 08:10:45
【问题描述】:

我正在使用 Select2 来管理大量数据。用户表示希望能够将列表粘贴到 Select2 字段中,以便一次选择各种项目,而不是手动输入和匹配列表中的每个项目。

我尝试使用tokenSeparators 来分隔列表中的项目。这和demo on tokens in the documentation 让我相信我希望做的事情是可能的,但到目前为止我还没有快乐。

我用来实例化 Select2 的代码是:

$('input').select2({
    width: 'element',
    matcher: function (term, text) {
        return text.toUpperCase().indexOf(term.toUpperCase()) === 0;
    },
    minimumInputLength: 3,
    multiple: true,
    data: tagList, // tagList is an array of objects with id & text parameters
    placeholder: 'Manage List',
    initSelection: function (element, callback) {
        var data = [];
        $.each(function () {
            data.push({id: this, text: this});
        });
        callback(data);
    },
    tokenSeparators: [',', ', ', ' ']
});

澄清一下,select2 字段在所有其他方面都有效。只是将列表粘贴到字段中时没有任何匹配项。我想测试粘贴列表中的所有项目。这可能吗?如果可以,怎么做?

编辑:我尝试了以下代码,但似乎不起作用:

$('body').on('paste', '#s2id_list-unitids .select2-input', function () {
    var that = this;
    setTimeout(function () {
        var tokens = that.value.split(/[\,\s]+/);
        $('#list-unitids').val(tokens, true);console.log($('#list-unitids').select2('val'));
    }, 1);
});

这是我创建的一个小提琴:http://jsfiddle.net/KCZDu/

【问题讨论】:

    标签: jquery jquery-select2


    【解决方案1】:

    select2 提供了一个tokenizer 选项,可让您预处理输入。这是您特定用例的可能实现:

    tokenizer: function(input, selection, callback) {
    
            // no comma no need to tokenize
            if (input.indexOf(',')<0) return;
    
            var parts=input.split(",");
            for (var i=0;i<parts.length;i++) {
                var part=parts[i];
                part=part.trim();
                // todo: check for dupes (if part is already in [selection])
    
                // check if the part is valid
                // todo: you will need a better way of doing this
                var valid=false;
                for (var j=0;j<unitIds.length;j++) {
                    if (part===unitIds[j]) { valid=true; break; }
                }
    
                if (valid) callback({id:part,text:part});
            }
        }
    

    这是一个有效的小提琴:http://jsfiddle.net/XcCqg/38/

    还请注意您的原始小提琴使用非常过时的 select2 3.2,可能不支持标记器。

    【讨论】:

    • 谢谢!这个周末我现在可以放松了! :)
    • 不知道是不是因为设置,但是当焦点进入输入时出现错误“TypeError:input.indexOf is not a function”。它也不能防止重复
    【解决方案2】:

    基本上它会覆盖默认的粘贴函数来处理新的输入文本,这段代码将根据选项'tokenSeparators'中指定的分隔符打破输入,然后将它们全部添加到分隔列表中,你只需要运行这个页面末尾的代码:

    $(document).on('paste', 'span.select2', function (e) {
            e.preventDefault();
            var select = $(e.target).closest('.select2').prev();
            var clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
            var createOption = function (value, selected) {
                selected = typeof selected !== 'undefined' ? selected : true;
                return $("<option></option>")
                    .attr("value", value)
                    .attr("selected", selected)
                    .text(value)[0]
            };
            $.each(
                clipboard.split(new RegExp(select.data('select2').options.options.tokenSeparators.map(function (a) {
                    return (a).replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
                }).join('|'))),
                function (key, value) {
                    if (value && (!select.val() || (select.val() && select.val().indexOf('' + value) == -1))) {
                        select.append(createOption(value));
                    }
                });
            select.trigger('change');
        });
    

    【讨论】:

    • 您能否添加注释来解释它的作用?
    • @Sudar 基本上它覆盖了 select2 字段的默认粘贴功能以处理新的输入文本,此代码将根据选项 'tokenSeparators' 中指定的分隔符中断输入,然后将它们全部添加到选项列表分开。希望你能理解我糟糕的英语:)
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2023-01-08
    相关资源
    最近更新 更多