Auto tokenize last item in pasted string using select2

孤者浪人 提交于 2019-12-21 05:13:30

问题


I am using jQuery Select2 to create an input that allows auto tokenization. I've initialized the select2 input with the following options:

{
    tags: [''],
    tokenSeparators = [',', ' ']
}

Very basic stuff. When I type a string of text into the input, followed by a comma or space, the preceding string is tokenized, exactly as I would expect.

However, I need to support pasting of text into the input. This is where things fall apart.

If I paste '1,2,3,4' into the input, I get separate tokens for 1, 2, and 3, but 4 is not tokenized. Instead, it remains as the value of the input.select2-input and when the focus changes the value disappears.

I have tried a number of different approaches, to no avail.

I have attempted intercepting the paste event, getting the pasted string's value with e.originalEvent.clipboardData.getData('text/plain'), cancelling the event, and adding a comma to the end of the string before changing the input's value with a timed out .select2('val', str).

I have tried simulating a comma keypress event after the paste event. (.trigger({type: 'keypress', which: 188}))

I have tried changing the value of input.select2-input for each item in the array created by splitting the paste string.

Nothing seems to work. Any ideas?


回答1:


Based on a question that you have posted, you can use the following code that works with the variations:

1 2 3 4

1,2,3,4

1,2 3, 4

You can check this jsfiddle. Please note: I've found that version 3.5.0 has a bug with the third variation, so you should use the latest 3.5.1.

$("#select2-input").select2({
    tags: [''],
    tokenizer: function(input, selection, callback) {
        if (input.indexOf(',') < 0 && input.indexOf(' ') < 0)
            return;

        var parts = input.split(/,| /);
        for (var i = 0; i < parts.length; i++) {
            var part = parts[i];
            part = part.trim();

            callback({id:part,text:part});
        }
    }
});



回答2:


I don't sure if I really understand your issue, but I've made a code to separate new input from paste function, Basically it overrides the default paste function to handle the new input text, this code will break the input based on the separators specified in the option 'tokenSeparators', then adds them all to the list separated, you only need to run this code at the end of your page:

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

You may review my original answer here https://stackoverflow.com/a/37006931/2073339



来源:https://stackoverflow.com/questions/25367499/auto-tokenize-last-item-in-pasted-string-using-select2

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