Javascript 选择2 Custom Matcher可在组标题匹配时保持选项打开
我希望我的问题有意义——我不确定用什么样的方式来描述这一点。我有一个分组的Select2 select表单输入,如下所示:Javascript 选择2 Custom Matcher可在组标题匹配时保持选项打开,javascript,jquery,jquery-select2,jquery-select2-4,select2,Javascript,Jquery,Jquery Select2,Jquery Select2 4,Select2,我希望我的问题有意义——我不确定用什么样的方式来描述这一点。我有一个分组的Select2 select表单输入,如下所示: 蔬菜 生菜 西红柿 洋葱 水果 苹果 橙子 香蕉 价差 素食主义者 坚果 花生酱 因此,您开始键入App,当然您会从Select2下拉列表中获得Apples。如果您键入veg,您将获得Vegemite和vegets组标题,但所有选项均隐藏。如果搜索词与组标题匹配,我希望所有组选项都可见 我在select2源代码中做了一些挖掘,我认为这其实很容易,但我可能是错的,如果我是
- 蔬菜
- 生菜
- 西红柿
- 洋葱
- 水果
- 苹果
- 橙子
- 香蕉
- 价差
- 素食主义者
- 坚果
- 花生酱
App
,当然您会从Select2下拉列表中获得Apples
。如果您键入veg
,您将获得Vegemite
和vegets
组标题,但所有选项均隐藏。如果搜索词与组标题匹配,我希望所有组选项都可见
我在select2源代码中做了一些挖掘,我认为这其实很容易,但我可能是错的,如果我是对的,我会一直坚持如何让它工作。以下是源代码:
:
我创建了一个要点,而不是试图将其粘贴到这里:
我改变了代码的顺序,并对变量名做了一些轻微的更改以反映这一点。我认为这将保持选项组的开放性。我试图基于此创建一个自定义匹配器(参见我的要点),但我被困在它调用变音符号的地方:
在谷歌搜索之后,我意识到这是在替换我知道我没有的重音字符,所以我删除了这一部分
现在,我的matcher失败,出现TypeError:data.indexOf不是函数。(在“data.indexOf(term)”中,“data.indexOf”未定义)
我的浏览器中出现错误
我相信我离这里很近,但我有点不知所措,超出了我的经验和/或技能水平来完成这件事。如有任何建议或想法,将不胜感激
更新
下面是我正在使用的JSFIDLE:
我从您的问题中收集到的信息是,当选项
文本或选项
的父option
值属性中存在匹配项时,您希望能够显示选项
以供选择
这是相对简单的:主要是查看两个值,如果其中一个匹配,使用Select2的matcher
选项返回true
:
(注意:使用Select2 v3.5.4。)
v4.*及以上版本将术语
和文本
更改为更复杂的对象,因此会略有不同,但主要概念是相同的。如您所见,我所做的就是使用jQuery选择选项的父项(如果它是optgroup
元素),并将其包含在匹配器
检查中
此外,如果显示了optgroup
的任何子项,则将显示optgroup,因此您只需担心显示一个或多个选项,而不必手动显示optgroup
如果您有不同的要求,请提供一个(工作/非工作?)演示小提琴,显示您有什么,我们可以在哪里实际运行它
编辑
Select2自定义匹配在4.0版本中发生了显著变化。这里有一个自定义匹配器,已发布到该站点。为完整起见,现复制如下
注意,它为子元素(option
元素在option
元素中)调用自身,因此modelMatcher()
同时针对option
元素和选项运行,但是,在删除不匹配的optgroup
和选项后,将返回组合集。在上面的版本中,您得到了每个选项
元素,如果希望显示它(以及父元素),只需返回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
});
})();
如果您创建了一个JSFIDLE,而不是将其上传到GitHub,这将非常有帮助。看:你所做的改变对我来说很好。此外,我在Select2中找不到出现的data.indexOf
。你确定是Select2出错了吗?这就是你说的吗?这就是我要找的,但我使用的是v4和引导主题,所以很接近。我应该指定我使用的版本。虽然我得到了你的解决方案,但我失去了对主题的支持。@DanTappin-请使用你当前的代码创建一个主题,并在此处的注释中链接到它([@my name],以便我收到通知)。当你说你失去了主题支持,那是什么意思?你让它与v4一起工作,但它与引导不起作用,或者你切换到v3.5.4?还有别的事吗?我现在正在做JSFIDLE。如何获得指向select2 is和css的CND链接?是你主持的吗?我将我的select2 rails gem降级为您的版本,您的matcher工作得非常出色。我将发布v4抛出的错误。我同意-文档一点也不清楚。我将接受这个答案,因为你花了时间来回答,它确实有效(对于旧版本),它促使我最终找到一个有效的解决方案。谢谢。child.parentText+=data.parentText+“”+data.text代码>应该是child.parentText=data.parentText+“”+data.text
否则,child.parentText
将随着每次搜索而不断增长。。。
(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
});
})();