【问题标题】:Recursive tag search for Autocomplete - jQuery plugin自动完成的递归标签搜索 - jQuery 插件
【发布时间】:2017-10-18 16:33:26
【问题描述】:

我正在使用 jQuery autocomplete 插件在文本区域中搜索标签。

它工作得很好,但现在我需要在用户在文本框中输入时再次搜索。

例如,我有:

var tags = [ 
        { label: "#schedules", value: "Monday, Wednesday and Friday from 9:00 p.m. to 6:00 p.m." }, 
        { label: "@address", value: "Some Address, 12345 - Some City" },
    ];

$("#text_box").autocomplete({

        source: function(request, response) {

            var matcher = new RegExp(
                "^" + $.ui.autocomplete.escapeRegex(request.term), "i"
            );

            response($.grep(tags, function(item) {
                return matcher.test(item.label);
            }));

        }

    });

所以如果用户写:

“你好,坦克联系我们,在哪里可以#schedules你可以在@address找到我们”

插件必须重新搜索所有的巧合,并且每次都在文本框底部提示它们。并且文本框中的结果字符串必须是:

“您好,请联系我们的坦克,周一、周三和周五晚上 9:00 到 6:00 可以在 Some Address, 12345 - Some City 找到我们”

问题:我该怎么做?插件可以做到这一点,还是我需要创建自己的算法?

【问题讨论】:

标签: javascript jquery jquery-ui autocomplete


【解决方案1】:

正如我所提到的,对 Demo 进行一些小改动后,您可以制作一个快速替换菜单。

var tags = [{
  label: "@schedules",
  value: "Monday, Wednesday and Friday from 9:00 p.m. to 6:00 p.m."
}, {
  label: "@address",
  value: "Some Address, 12345 - Some City"
}];

$(function() {
  function split(val) {
    return val.split(" ");
  }

  function extractLast(term) {
    return split(term).pop();
  }
  $("#text_box").on("keydown", function(event) {
      if (event.keyCode === $.ui.keyCode.TAB &&
        $(this).autocomplete("instance").menu.active) {
        event.preventDefault();
      }
    })
    .autocomplete({
      minLength: 0,
      source: function(request, response) {
        var q = extractLast(request.term);
        console.log("Term: " + q);
        if (q.indexOf("@") == 0) {
          // delegate back to autocomplete, but extract the last term
          response($.ui.autocomplete.filter(tags, q));
        }
      },
      focus: function() {
        // prevent value inserted on focus
        return false;
      },
      select: function(event, ui) {
        var terms = split(this.value);
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push(ui.item.value);
        // add placeholder to get the comma-and-space at the end
        terms.push("");
        this.value = terms.join(" ");
        return false;
      }
    });
});
#text_box {
  width: 75%;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<textarea id="text_box"></textarea>

更新

如果您怀疑您将有多个符号,您可以使用switch() 语句或复杂的if()。比如:

if(q.indexOf("@") == 0 || q.indexOf("$") == 0 || q.indexOf("#") == 0){
  response($.ui.autocomplete.filter(tags, q));
}

或者:

switch(true){
  case (q.term.indexOf("@") == 0):
  case (q.term.indexOf("$") == 0):
  case (q.term.indexOf("#") == 0):
    response($.ui.autocomplete.filter(tags, q));
    break;
}

【讨论】:

  • 对不起,我忘了提一个很重要的事情:标签的初始符号可以是任意的,并不总是相同的。
  • 文本区域内总是出现加载动画并且永远不会消失是否正常?
  • @emi 不,这不正常。另外,我不确定您在评论中所说的“可以是任何东西,并不总是相同”是什么意思。
  • 可以像@aaa、$bbb、#ccc 或标签开头的任何其他符号。
  • @emi 您拥有的初始符号越多,您必须实现的代码就越困难或越多以查找这些不同的符号。
猜你喜欢
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
相关资源
最近更新 更多