Select2 自定义匹配器以在组标题匹配时保持选项打开
Posted
技术标签:
【中文标题】Select2 自定义匹配器以在组标题匹配时保持选项打开【英文标题】:Select2 Custom Matcher to keep options open if group title matches 【发布时间】:2016-06-28 06:10:06 【问题描述】:我希望我的问题是有道理的 - 不确定描述这个问题的最佳方式。我有一个分组的 Select2 选择表单输入,如下所示:
蔬菜 生菜 西红柿 洋葱 水果 苹果 橙子 香蕉 点差 素食主义者 能多益 花生酱所以你开始输入App
,当然你会从Select2下拉列表中得到Apples
。如果您输入veg
,您将获得Vegemite
和Vegetables
组标题,但所有选项都被隐藏。如果搜索词与组标题匹配,我想保持所有组选项可见。
我在 select2 源代码中进行了一些挖掘,我认为这实际上很容易,但我可能是错的,如果我是对的,我会被困在如何使它工作上。这是源代码: https://github.com/select2/select2/blob/81a4a68b113e0d3e0fb1d0f8b1c33ae1b48ba04f/src/js/select2/defaults.js:
以及我创建的 Gist 与尝试将其粘贴到此处:
https://gist.github.com/jasper502/40b810e55b2195476342
我切换了代码的顺序并做了一些细微的变量名更改以反映这一点。我认为这将使选项组保持打开状态。我试图基于此制作一个自定义匹配器(请参阅我的 Gist),但我被困在它调用 DIACRITICS
的地方:
https://github.com/select2/select2/blob/8ad8f200ba8c9429d636453b8ee3bcf593e8c87a/src/js/select2/diacritics.js
经过一些谷歌搜索后,我意识到这是替换我知道我没有的重音字符,所以我删除了那部分。
现在我的匹配器因浏览器中的TypeError: data.indexOf is not a function. (In 'data.indexOf(term)', 'data.indexOf' is undefined)
错误而失败。
我确信我在这里非常接近,但我有点过头了,超出了我的经验和/或技能水平来完成这项工作。任何指针或想法将不胜感激。
更新
这是我正在使用的 JSfiddle:
https://jsfiddle.net/jasper502/xfw4tmbx/9/
【问题讨论】:
如果您为此创建了一个 jsFiddle,而不是将其上传到 GitHub,这将非常有帮助。见:jsfiddle.net 您所做的更改对我来说效果很好。此外,我在 Select2 中找不到任何data.indexOf
。你确定是 Select2 出错了吗?
你说的是这个吗? jsfiddle.net/xfw4tmbx/2
【参考方案1】:
我从您的问题中收集到的是,当option
文本或option
的父optgroup
值属性中存在匹配项时,您希望能够显示option
s 以供选择。
这相对简单:主要是查看两个值,如果匹配,return true
使用 Select2 的 matcher
选项:
(注意:使用 Select2 v3.5.4。)
(function()
function matcher(term, text, opt)
var $option = $(opt),
$optgroup = $option.parent('optgroup'),
label = $optgroup.attr('label');
term = term.toUpperCase();
text = text.toUpperCase();
if (text.indexOf(term) > -1
|| (label !== undefined
&& label.toUpperCase().indexOf(term) > -1))
return true;
return false;
$(".select2").select2(
matcher: matcher
);
)();
https://jsfiddle.net/xfw4tmbx/2/
v4.* 及更高版本将term
和text
更改为更复杂的对象,因此会略有不同,但主要概念是相同的。正如你所看到的,我所做的只是使用 jQuery 来选择 option
的父元素,如果它是一个 optgroup
元素并且包括在 matcher
检查中。
此外,optgroup
将在其任何子项显示时显示,因此您只需担心显示一个或多个option
,而无需手动“显示”optgroup
显示它。
如果您有不同的要求,请提供一个(工作/不工作?)演示小提琴,展示您在哪里可以实际运行它。
编辑
Select2 自定义匹配在 4.0 版本中发生了显着变化。这是发布到此GitHub issue 的自定义匹配器。为了完整起见,它按原样复制如下。
请注意,它为子元素(optgroup
元素中的 option
元素)调用自身,因此 modelMatcher()
与 optgroup
和 option
元素同时运行, 但在删除不匹配的 optgroup
和 option
元素后返回组合集。在上面的版本中,你得到了每个 option
元素,如果你想显示它(和父元素),只需返回 true/false。没有那么复杂得多,但你确实需要多考虑一下。
(function()
function modelMatcher(params, data)
data.parentText = data.parentText || "";
// Always return the object if there is nothing to compare
if ($.trim(params.term) === '')
return data;
// Do a recursive check for options with children
if (data.children && data.children.length > 0)
// Clone the data object if there are children
// This is required as we modify the object to remove any non-matches
var match = $.extend(true, , data);
// Check each child of the option
for (var c = data.children.length - 1; c >= 0; c--)
var child = data.children[c];
child.parentText += data.parentText + " " + data.text;
var matches = modelMatcher(params, child);
// If there wasn't a match, remove the object in the array
if (matches == null)
match.children.splice(c, 1);
// If any children matched, return the new object
if (match.children.length > 0)
return match;
// If there were no matching children, check just the plain object
return modelMatcher(params, match);
// If the typed-in term matches the text of this term, or the text from any
// parent term, then it's a match.
var original = (data.parentText + ' ' + data.text).toUpperCase();
var term = params.term.toUpperCase();
// Check if the text contains the term
if (original.indexOf(term) > -1)
return data;
// If it doesn't contain the term, don't return anything
return null;
$(".select2").select2(
matcher: modelMatcher
);
)();
https://jsfiddle.net/xfw4tmbx/16/
【讨论】:
这就是我正在寻找的,但我使用的是 v4 和引导主题,所以它很接近。我应该指定我使用的版本。我得到了你的解决方案,但我失去了主题支持。 @DanTappin - 请使用您当前的代码创建一个jsfiddle.net 并在此处的评论中链接到它([@my name] 以便我收到通知)。当你说你失去了主题支持时,这是什么意思?你让它与 v4 一起工作,但它不能与 Bootstrap 一起工作,或者你切换到 v3.5.4?还有什么? 我现在正在研究 jsfiddle。你如何获得到 select2 is 和 css 的 CND 链接?那些是你主持的吗?我将我的 select2 rails gem 降级到你拥有的版本,你的匹配器就像一个魅力。我将发布 v4 引发的错误。 我同意 - 文档一点也不清晰。我将接受这个答案,因为您花时间回复,它确实有效(对于旧版本),它促使我最终找到了一个有效的解决方案。谢谢。child.parentText += data.parentText + " " + data.text;
应该是 child.parentText = data.parentText + " " + data.text;
否则,child.parentText
会随着每次搜索而不断增长...以上是关于Select2 自定义匹配器以在组标题匹配时保持选项打开的主要内容,如果未能解决你的问题,请参考以下文章
创建自定义导航栏渲染器以在 xamarin 表单 IOS 项目中添加自定义后退按钮图标