Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 选择2 Custom Matcher可在组标题匹配时保持选项打开_Javascript_Jquery_Jquery Select2_Jquery Select2 4_Select2 - Fatal编程技术网

Javascript 选择2 Custom Matcher可在组标题匹配时保持选项打开

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源代码中做了一些挖掘,我认为这其实很容易,但我可能是错的,如果我是

我希望我的问题有意义——我不确定用什么样的方式来描述这一点。我有一个分组的Select2 select表单输入,如下所示:

  • 蔬菜
  • 生菜
  • 西红柿
  • 洋葱
  • 水果
  • 苹果
  • 橙子
  • 香蕉
  • 价差
  • 素食主义者
  • 坚果
  • 花生酱
因此,您开始键入
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
    });
})();