问题
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