jQuery UI自动完成多项搜索

时间:2011-06-13 19:42:53

标签: jquery user-interface autocomplete

我正在尝试使用jQuery UI自动完成功能。经过一段时间的搜索,在简单编写自己的搜索之前,也许已经有了解决方案。

我之前使用过jQuery插件http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/,但出于各种原因想要迁移到UI中集成的插件。

目前有两件事让我受到挑战。

所选术语突出显示和多个术语搜索/选择以及如何实现这些。

这是一个小提琴页面:http://jsfiddle.net/vapc2/以显示示例。 输入“蚂蚁”,它会突出蚂蚁。但是,如果我输入“蚂蚁吉尔山”,它应该选择并突出显示所有带有“蚂蚁”的条目,所有条目都带有“吉尔”,所有条目都带有“山丘”,而不是像现在这样。基本上,如果一个术语出现在任何地方,在任何答案中,我想返回该值并突出显示该术语,即使它不是完全匹配,只是因此它包含在某处的答案中。因此,如果我输入“ant bug”,我想用这两个单词中的任何一个返回所有条目。

假设我有以下示例JSON对象:

var sampleAnswers = [
    {
    "id": "00450",
    "label": "Ants, Ants on a hill near Jill",
    "Category": "Ants",
    "value": "hill ant"},
{
    "id": "00450",
    "label": "Ants, Ant not on a hill",
    "Category": "Ants",
    "value": "regular ant"},
{
    "id": "00452",
    "label": "Some ants on a hill",
    "Category": "Ants",
    "value": "hill ants"},
{
    "id": "00454",
    "label": "Red ants on a hill near Jill",
    "Category": "Ants",
    "value": "hill ant red"},
{
    "id": "00470",
    "label": "Bugs on a rug",
    "Category": "bugs",
    "value": "rug bug"},
{
    "id": "00472",
    "label": "rug bugs under the rug",
    "Category": "bugs",
    "value": "rug bug"},
{
    "id": "69000",
    "label": "bed bugs",
    "Category": "bed",
    "value": "bed bugs"},
{
    "id": "69005",
    "label": "Large complicated bed bugs",
    "Category": "bugs",
    "value": "bed bug"},
{
    "id": "69020",
    "label": "red bed bugs",
    "Category": "bugs",
    "value": "red bugs"}
];
function replaceWords(wordsy, text) {
    //var re = '(' + words.join('|') + ')(?![^<]*(?:<\/script|>))',
    var re = '(' + wordsy + ')(?![^<]*(?:<\/script|>))',
        regExp = new RegExp(re, 'ig'),
        sTag = "<span class='autoCompleteWord'>",
        eTag = "</span>";
    return text.replace(regExp, sTag + '$&' + eTag);
};
$("#tags").autocomplete({
    minLength: 1,
    source: sampleAnswers,
    delay: 1000,
    focus: function(event, ui) {
        $("#cpt").val(ui.item.label);
        return false;
    },
    open: function(event, ui) {
        var myValue = $(this).val(); //get typed
        $("ul.ui-autocomplete li a").each(function() {
            var autoCompleteRow = $(this);
            var htmlString = autoCompleteRow.html();
            var words = myValue.split(" ");
            $('#mesText2').val(myValue + ":" + words.length);
            var i = words.length;
            while (i--) {
                htmlString = replaceWords(words[i], htmlString);
            };
            autoCompleteRow.html(htmlString);
        });
    },
    select: function(event, ui) {
        var hasValue = (ui.item.value != undefined && ui.item.value != "" && ui.item.value != null);
        $("#bugid").val(ui.item.id);
        $("#bugcategory").val(ui.item.Category);
        $("#bug").val(hasValue ? ui.item.value : ui.item.label);
        $("#bugLabel").val(ui.item.label);

        return false;
    }
}).data("autocomplete")._renderItem = function(ul, item) {
    return $("<li></li>").data("item.autocomplete", item).append("<a>" + item.id + " <span class='autoCompCat'>" + item.Category + "</span> (Category)<br/>" + item.label + " <br/><span class='autoCompCpt'>" + item.value + "</span>" + "</a>").appendTo(ul);
};

标记:

<p><label class='mesFieldLabel'>
    ya typed:</label><input id='mesText2' type='text' class='mesText' /></p><div class="ui-widget cptarea">
<label class='mesFieldLabel' for="tags">Tags:</label>
<input id="tags" /><span class='testCSS'>type 'ant' for example</span>
</div>
<div class='bugarea'>
    <div>
        <label class='mesFieldLabel'>
            Code:</label><input id='bugid' maxlength="100" />
    </div>
    <div>
        <label class='mesFieldLabel'>
            Category:</label><input id='bugcategory' maxlength="100" />
    </div>
    <div>
        <label class='mesFieldLabel'>
            Bug:</label><input id='bug' maxlength="100" />
    </div><div>
    <label class='mesFieldLabel'>
        Bug Label:</label><input id='bugLabel' maxlength="100" />
    </div>
</div>

jQuery UI最新版本,jQuery 1.6是首选。

编辑: 我试图使用以下“来源”:

    source: function(request, response) {
        var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
        response($.each(sampleAnswers, function() {
            var text = $(this).label;
            if (this.value && (!request.term || matcher.test(text)))
                return {
                    label: text.replace(
                                        new RegExp(
                                            "(?![^&;]+;)(?!<[^<>]*)(" +
                                            $.ui.autocomplete.escapeRegex(request.term) +
                                            ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                        ), "<strong>$1</strong>"),
                    value: text,
                    option: this
                };
        }));
    },

但这会返回结果,不包括我输入的术语列表(如“红虫”返回项目00450,00450,00452),我不想显示。 请参阅此更新的小提琴:http://jsfiddle.net/vapc2/1/

1 个答案:

答案 0 :(得分:2)

好的,我解决了它返回所有结果而不是过滤

的问题

http://jsfiddle.net/vapc2/4/

以下是我所做的代码更改 - 需要注意的事项:

  • 我将$(this)更改为此。
  • 我添加了一个结果数组,并且仅在测试通过时添加(根据我的原始评论。)
  • 你的正则表达式不起作用,但我认为这不属于这个问题的范围。

    source: function(request, response) {
    
      var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
    
      var resultset = [];
    
      $.each(sampleAnswers, function() {
    
        var t = this.label;
    
        if (this.value && (!request.term || matcher.test(t)))
        {
           resultset.push( {
    
           label: t.replace(
                     new RegExp(
                             "(?![^&;]+;)(?!<[^<>]*)(" +
                             $.ui.autocomplete.escapeRegex(request.term) +
                             ")(?![^<>]*>)(?![^&;]+;)", "gi"
                           ), "<strong>$1</strong>"),
           value: t,
           option: this
         });
       }  
       return;
     });
    
     response(resultset);
    
    },