Select2 用于创建新标签的事件
Posted
技术标签:
【中文标题】Select2 用于创建新标签的事件【英文标题】:Select2 Event for creating a new tag 【发布时间】:2015-04-23 18:49:51 【问题描述】:我正在使用 jQuery Select2 (v4) 插件作为标签选择器。
我想监听在 select 元素中何时创建了新标签并触发 ajax 请求来存储新标签。我发现有createTag
事件,但这似乎每次在 select2 元素中输入一个字母时都会触发。如我的小提琴所示:http://jsfiddle.net/3qkgagwk/1/
是否有类似的事件仅在新标签输入完成时触发? IE。它被一个灰色的盒子包围着。
【问题讨论】:
你不能只使用:select
事件吗?因此,每次选择某些内容时,您都会得到这样的结果:$(selector).on("select2:select", function (e) console.log(e.params.data); );
。这确实在现有对象和新对象之间没有区别,但它是一个开始。
***.com/questions/23295168/…
createTag
不是事件,而是被覆盖的方法。看起来开发人员第二天就在 Gitlab 上回复了您关于此问题的问题 (github.com/select2/select2/issues/3063) - 如果您更新了您的问题或提供了答案,那就太好了。对于其他人,开发人员建议收听select2:selected
事件;我发现change
事件也被触发了。
愿编码之神保佑你@Paul
【参考方案1】:
很遗憾,我找不到任何 native 方法。但是,如果您对简单的“解决方法”感兴趣,也许这会让您更接近:
$('.select2').select2(
tags: true,
tokenSeparators: [",", " "],
createTag: function (tag)
return
id: tag.term,
text: tag.term,
// add indicator:
isNew : true
;
).on("select2:select", function(e)
if(e.params.data.isNew)
// append the new option element prenamently:
$(this).find('[value="'+e.params.data.id+'"]').replaceWith('<option selected value="'+e.params.data.id+'">'+e.params.data.text+'</option>');
// store the new tag:
$.ajax(
// ...
);
);
DEMO
[编辑] (小更新:见@Alex下方评论)
上述方法仅在使用鼠标添加标签时有效。对于通过点击空格或逗号添加的标签,使用change
事件。
然后你可以过滤option
与data-select2-tag="true"
属性(新添加的标签):
$('.select2').select2(
tags: true,
tokenSeparators: [",", " "]
).on("change", function(e)
var isNew = $(this).find('[data-select2-tag="true"]');
if(isNew.length && $.inArray(isNew.val(), $(this).val()) !== -1)
isNew.replaceWith('<option selected value="'+isNew.val()+'">'+isNew.val()+'</option>');
$.ajax(
// ... store tag ...
);
);
DEMO 2
【讨论】:
如何检测标签是否被移除? 我只想要新标签被移除时的事件 然后您可以在创建新标签时添加一个指示符(如 class)并在:unselect
事件处理程序中简单地检查该指示符。 Demo
如果您输入“aw”并按回车键选择“awesome”,它会创建一个新标签“aw”将其添加到选择框并添加“awesome”。显然,在这种情况下,所需的行为只是添加“真棒”,而不是添加新标签。我认为这就是@Sahan 所解释的,但我想不出办法来防止这个问题。
作者(select2)的答案似乎使用隐藏在文档中的不同方法来回答它:jsfiddle.net/3qkgagwk/2【参考方案2】:
创建新标签时唯一对我有用的事件监听器是:
.on("select2:close", function()
(my code)
)
这是针对新标签和从列表中选择而触发的。 change
、select2:select
、select2:selecting
和任何其他都不起作用。
【讨论】:
为了区分我使用的现有标签或新标签:if(e.params.hasOwnProperty('originalSelect2Event') && e.params.originalSelect2Event.data.isNew == true)
【参考方案3】:
一个更简单的检查将是基于事件的 args 的差异.....
在处理这种情况时,我看到了这种不同;当创建新元素时,事件 args 数据没有元素对象,但在选择已经可用的选项时它存在...
.on('select2:selecting', function (e)
if (typeof e.params.args.data.element == 'undefined')
// do a further check if the item created id is not empty..
if( e.params.args.data.id != "" )
// code to be executed after new tag creation
)
【讨论】:
【参考方案4】:另一种解决方法。只需将其插入开头即可:
).on('select2:selecting', function (evt)
var stringOriginal = (function (value)
// creation of new tag
if (!_.isString(value))
return value.html();
// picking existing
return value;
)(evt.params.args.data.text);
........
它依赖 underscore.js 来检查它是否是字符串。你可以用任何你喜欢的方法替换 _.isString 方法。
它使用的事实是,当创建新术语时,它始终是一个对象。
【讨论】:
以上是关于Select2 用于创建新标签的事件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 select2 new /remove tag 事件上触发新的 ajax?