4

我正在使用select2 小部件,我需要显示格式为 html 的搜索结果。

所以我这样使用它:

  function formatMyItem(myItem) {
     return defaultEscapeMarkup(myItem.someDescription) + " <strong>(" + myItem.someOtherValue + ")</strong>";
  }

  function defaultEscapeMarkup(markup) {
     var replace_map = {
        '\\': '&#92;',
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
        "/": '&#47;'
     };

     return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
        return replace_map[match];
     });
  }

  var suggestionValues = [];
  for (var i = 0; i < myData.length; i++) {
     var myItem = myData[i];
     suggestionValues.push({
        id: myItem.someKey,
        text: formatMyItem(myItem)
     });
  }

  $mySelect.select2({
     width: 'resolve',
     multiple: true,
     data: suggestionValues,
     escapeMarkup: function(m) {
        // Do not escape HTML in the select options text
        return m;
     }
  });

但是现在当用户搜索某些内容时,该词会在选项的 HTML 中搜索。

例如,如果用户搜索“strong”(假设某些描述可以包含“strong”一词),那么 select2 将建议所有值(因为它们都包含“strong”)。

此外,当用户搜索“<”(假设某些描述包含数学符号)时,select2 将返回所有值(因为它们都包含 html 标签),但不会突出显示描述中实际的“小于”符号, 因为它们实际上已被转换为“& lt;”。

如何使 select2 不在 html 标签内搜索?

4

1 回答 1

3

好的,看来解决方案实际上很简单:D

我添加了以下内容:

  $mySelect.select2({
     width: 'resolve',
     multiple: true,
     data: suggestionValues,
     escapeMarkup: function(m) {
        // Do not escape HTML in the select options text
        return m;
     },
     matcher: function(term, text) {
        // Search the term in the formatted text
        return $("<div/>").html(text).text().toUpperCase().indexOf(term.toUpperCase())>=0;
     }
  });

所以现在当用户搜索“强”时,他们只会得到相关的结果。

但是现在还有一个问题:

现在,如果用户搜索“<”,那么 select2 将突出显示强标签内的“<”。

看来我还需要以某种方式“修补”搜索结果荧光笔......

编辑: 回到这一点,突出显示的解决方案似乎并不那么容易......

select2 中的默认实现是这样的:

    formatResult: function(result, container, query, escapeMarkup) {
        var markup=[];
        markMatch(result.text, query.term, markup, escapeMarkup);
        return markup.join("");
    },
    .......

    function markMatch(text, term, markup, escapeMarkup) {
        var match=text.toUpperCase().indexOf(term.toUpperCase()),
            tl=term.length;

        if (match<0) {
            markup.push(escapeMarkup(text));
            return;
        }

        markup.push(escapeMarkup(text.substring(0, match)));
        markup.push("<span class='select2-match'>");
        markup.push(escapeMarkup(text.substring(match, match + tl)));
        markup.push("</span>");
        markup.push(escapeMarkup(text.substring(match + tl, text.length)));
    }

不知何故,我需要替换这两个函数,但我找不到一个简单的解决方案,将格式化 HTML 中的字符范围(要突出显示的搜索项)映射回源 html(以便我可以添加 < span 类='select2-match' > ) ...

如果你们有更好的解决方案,请随时分享...

于 2013-09-13T14:29:16.463 回答