如何去除Select2分组选项中的重复标签?
解决Select2分组中重复标签选中后重复显示的问题
问题核心:你遇到的情况是因为两个分组里的"BBB"选项id完全相同,但属于不同的选项对象,Select2默认允许同一id的选项被多次选中,导致选中后重复显示。
下面提供两种解决思路:
方案一:预处理数据源,移除重复选项
从根源上确保同一个id的选项只在下拉框中出现一次,这样选中时自然不会重复。
修改代码如下:
var tagsCat1 = [ "AAA", "BBB", "CCC" ]; var childrenCat1 = []; for (var i = 0; i < tagsCat1.length; i++) { childrenCat1.push({ id: tagsCat1[i], text: tagsCat1[i] }); } var tagsCat2 = [ "DDD", "EEE", "BBB" // duplicate tag ]; var childrenCat2 = []; for (var i = 0; i < tagsCat2.length; i++) { childrenCat2.push({ id: tagsCat2[i], text: tagsCat2[i] }); } // 合并所有子选项并去重(利用Map的键唯一性) const allChildren = [...childrenCat1, ...childrenCat2]; const uniqueChildren = Array.from(new Map(allChildren.map(item => [item.id, item])).values()); // 重新构建分组,重复项只保留在第一个出现的分组 var options = []; options.push({ text: "Cat1", children: uniqueChildren.filter(item => tagsCat1.includes(item.id)) }); options.push({ text: "Cat2", children: uniqueChildren.filter(item => tagsCat2.includes(item.id) && !tagsCat1.includes(item.id)) }); $('#example1').select2({ data: options, tags: true, multiple: true, allowClear: true, placeholder: 'select...', });
这段代码会把"BBB"只保留在Cat1分组中,下拉框里不会再出现重复的"BBB",选中后自然只会显示一次。
方案二:拦截选中事件,阻止重复选中
如果需要保留下拉框中两个分组的"BBB"选项,但不想让用户重复选中,可以通过监听Select2的选中事件来拦截重复操作。
修改代码如下:
var tagsCat1 = [ "AAA", "BBB", "CCC" ]; var childrenCat1 = []; for (var i = 0; i < tagsCat1.length; i++) { childrenCat1.push({ id: tagsCat1[i], text: tagsCat1[i] }); } var tagsCat2 = [ "DDD", "EEE", "BBB" // duplicate tag ]; var childrenCat2 = []; for (var i = 0; i < tagsCat2.length; i++) { childrenCat2.push({ id: tagsCat2[i], text: tagsCat2[i] }); } var options = []; options.push({ text: "Cat1", children: childrenCat1 }); options.push({ text: "Cat2", children: childrenCat2 }); $('#example1').select2({ data: options, tags: true, multiple: true, allowClear: true, placeholder: 'select...', }); // 监听选中事件,阻止重复选中同一id的选项 $('#example1').on('select2:select', function(e) { const selectedId = e.params.data.id; const currentSelectedIds = $(this).val() || []; if (currentSelectedIds.includes(selectedId)) { e.preventDefault(); } });
这样用户选中其中一个"BBB"后,再选另一个时会被阻止,避免重复显示已选中的标签。
内容的提问来源于stack exchange,提问作者PBrockmann
相关产品推荐
相关产品推荐

