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事件。

然后你可以过滤optiondata-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)
)

这是针对新标签和从列表中选择而触发的。 changeselect2:selectselect2:selecting 和任何其他都不起作用。

【讨论】:

为了区分我使用的现有标签或新标签:if(e.params.hasOwnProperty('originalSelect2Event') &amp;&amp; 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:选择新标签后更新选项

如何在 select2 new /remove tag 事件上触发新的 ajax?

如何使用 Select2 创建新标签并保存到数据库

键入新标签时 Select2 失去焦点

在 express 中将新的 select2 选项标签写入本地数据库

select2 添加带有确认框的新标签