使用 select2 显示匹配 optgroup 的结果

Posted

技术标签:

【中文标题】使用 select2 显示匹配 optgroup 的结果【英文标题】:Display result matching optgroup using select2 【发布时间】:2014-03-26 09:48:36 【问题描述】:

我在 Bootstrap 3 中使用select2。 现在我想知道如果搜索与 optgroup 名称匹配,是否可以显示所有 optgroup 项目,同时仍然能够搜索项目。如果可以,我该怎么做?

【问题讨论】:

【参考方案1】:

上述答案似乎不适用于 Select2 4.0,所以如果您正在寻找答案,请查看:https://github.com/select2/select2/issues/3034

(使用这样的函数:$("#example").select2(matcher: modelMatcher);

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;

【讨论】:

这行得通。这现在应该是答案,因为上面确实有问题。谢谢威尔布拉德利。【参考方案2】:

其实通过修改matcher opt找到了解决办法

 $("#myselect").select2(
    matcher: function(term, text, opt)
         return text.toUpperCase().indexOf(term.toUpperCase())>=0 || opt.parent("optgroup").attr("label").toUpperCase().indexOf(term.toUpperCase())>=0
    
);

在每个optgroup中都设置了label属性的前提下。

【讨论】:

不错!不过,我建议使用默认匹配器实现,除非您有意偏离默认匹配器。 element.select2( matcher: function (term, text, opt) return element.select2.defaults.matcher(term, text) || element.select2.defaults.matcher(term, opt.parent("optgroup").attr("label")); ); 这不仅可以忽略大小写,还可以忽略变音符号,从而实现更好的匹配。 text.toUpperCase 不是函数错误。调试并看到文本作为对象出现,而不是字符串?你见过这个问题吗? 没有没见过。那是一个什么样的物体?你有对象的转储吗?也许新版本的匹配器参数已更改? Select2 V4 将不同的参数传递给匹配器函数。 (见@willbradley 的回答)也许可以帮助你【参考方案3】:

对人们建议的代码进行了一些小改动,减少了重复性,并且在没有父 optgroup 时可以应对:

$('select').select2(
    matcher: function(term, text, opt)
        var matcher = opt.parent('select').select2.defaults.matcher;                        
        return matcher(term, text) || (opt.parent('optgroup').length && matcher(term, opt.parent('optgroup').attr("label"))); 
    
);

【讨论】:

【参考方案4】:

从select2/issues/3034找到解决方案

使用 select2 v.4 测试

$("select").select2(
    matcher(params, data) 
        const originalMatcher = $.fn.select2.defaults.defaults.matcher;
        const result = originalMatcher(params, data);

        if (
            result &&
            data.children &&
            result.children &&
            data.children.length
        ) 
            if (
                data.children.length !== result.children.length &&
                data.text.toLowerCase().includes(params.term.toLowerCase())
            ) 
                result.children = data.children;
            
            return result;
        

        return null;
    ,
);

【讨论】:

以上是关于使用 select2 显示匹配 optgroup 的结果的主要内容,如果未能解决你的问题,请参考以下文章

Select2:动态隐藏某些 optgroup

带有 optgroup 和图像的 Jquery select2 json 数据

使用 select2 折叠/展开 optgroup

使用 select2 的可选 optgroup

jQuery Select2 - 如何隐藏 Select2 Optgroup

Select2 v4.0 使 optgroups 可选