jQuery 使用 jQueryUI 的新自动完成功能的多列结果的快速示例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2744747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 14:11:57  来源:igfitidea点击:

Quick example of multi-column results with jQueryUI's new Autocomplete?

jqueryjquery-uiautocomplete

提问by Lance

I just found out that the jQueryUI now has it's own built-in auto-complete combo box. Great news!

我刚刚发现jQueryUI 现在有它自己的内置自动完成组合框。好消息!

Unfortunately, the next thing I found is that making it multi-column doesn't seem nearly that simple (at least via documentation).

不幸的是,我发现的下一件事是使它成为多列似乎并不那么简单(至少通过文档)。

There is a post herewhere someone mentions that they've done it (and even gives code), but I'm having trouble understanding what some of their code is doing.

这里有一篇文章,有人提到他们已经完成了(甚至提供了代码),但我无法理解他们的某些代码在做什么。

I'm just curious if anyone has ran across this before and could post a quick and easy sample of making a multi-column result set.

我只是好奇是否有人之前遇到过这个问题,并且可以发布一个快速简便的制作多列结果集的示例。

Thanks much in advance.

非常感谢。

回答by Lance

I ended up manually overriding the _renderMenuand _renderItemfunctions after all. Works like a charm so far, and was actually veryeasy to do. I was hoping for a "per-instance" solution, but we'll burn that bridge when we come to it. Here's what it came to, and thanks again!

毕竟,我最终手动覆盖了_renderMenu_renderItem函数。到目前为止,它就像一个魅力,实际上容易做到。我希望有一个“每个实例”的解决方案,但是当我们遇到它时,我们会烧掉那座桥。原来如此,再次感谢!

$.ui.autocomplete.prototype._renderMenu = function(ul, items) {
  var self = this;
  ul.append("<table><thead><tr><th>ID#</th><th>Name</th><th>Cool&nbsp;Points</th></tr></thead><tbody></tbody></table>");
  $.each( items, function( index, item ) {
    self._renderItem( ul.find("table tbody"), item );
  });
};

$.ui.autocomplete.prototype._renderItem = function(table, item) {
  return $( "<tr></tr>" )
    .data( "item.autocomplete", item )
    .append( "<td>"+item.id+"</td>"+"<td>"+item.value+"</td>"+"<td>"+item.cp+"</td>" )
    .appendTo( table );
};

$("#search").autocomplete({
  source: [
    {id:1,value:"Thomas",cp:134},
    {id:65,value:"Richard",cp:1743},
    {id:235,value:"Harold",cp:7342},
    {id:982,value:"Nina",cp:21843},
    {id:724,value:"Pinta",cp:35},
    {id:78,value:"Santa Maria",cp:787}],
  minLength: 1
});

?

?

回答by Paul Haley

I managed to get the full menu functionality working with a table layout, including selection, highlighting etc. I found that it is impossible to use <table><tr><td>with autocomplete but you can put <div>inside the autocomplete items and use display: table-cellin CSS. This works from IE8 onwards and all the main modern browsers.

我设法使完整的菜单功能与表格布局一起使用,包括选择、突出显示等。我发现它无法<table><tr><td>与自动完成一起使用,但您可以将其<div>放入自动完成项目并display: table-cell在 CSS 中使用。这适用于 IE8 和所有主要的现代浏览器。

$.widget("custom.threecolumnautocomplete", $.ui.autocomplete,
    {
        _renderMenu: function( ul, items )
        {
            ul.addClass("threecolumnautocomplete");
            return this._super(ul, items);
        },

        _renderItem: function (ul, item)
        {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a><div class='col'>" + item.id + "</div><div class='col'>" + item.value + "</div><div class='col'>" + item.cp + "</div></a>")
                .appendTo(ul);
        }
    });

And then define CSS like this:

然后像这样定义 CSS:

.threecolumnautocomplete li { display: table-row-group; }

.threecolumnautocomplete a { display: table-row !important; }

.threecolumnautocomplete .col { display: table-cell; }

.ie7 .threecolumnautocomplete .col { display: block; float: left; width: 15em; overflow: hidden; white-space: nowrap; }

This also shows a basic override with fixed width columns that works in IE7. To use this add the ie7class higher up the document, e.g. on the bodyelement.

这也显示了适用于 IE7 的固定宽度列的基本覆盖。要使用它ie7,请在文档上方添加类,例如在body元素上。

回答by Thiago Silva

you could also extend the AutoComplete widget and create a custom one, very similarly to what you're doing. Below is sample of how to show a flyout panel with 3 columns using a table and 3 unordered lists:

您还可以扩展 AutoComplete 小部件并创建一个自定义小部件,这与您正在执行的操作非常相似。下面是如何使用表格和 3 个无序列表显示具有 3 列的弹出面板的示例:

$.widget("custom.threecolumnautocomplete", $.ui.autocomplete, {

            //going to extend the AutoComplete widget by customizing renderMenu and renderItems
            _renderMenu: function (ul, items) {
                var self = this;
                //we'll define a table structure with 3 columns, and use UL elements to shove items into.
                ul.append("<table class='customautocomplete' cellpadding='5'>\
                            <thead><tr>\
                                <th>Products</th>\
                                <th class='border'>Accessories</th>\
                                <th class='border'>Categories</th>\
                            </tr></thead>\
                            <tbody><tr>\
                                <td><ul class='products'></ul></td>\
                                <td class='border'><ul class='accessories'></ul></td>\
                                <td class='border'><ul class='categories'></ul></td>\
                            </tr></tbody>\
                        </table>");

                $.each(items, function (index, item) {
                    self._renderItem(ul.find("table tbody"), item);
                });
            },

            _renderItem: function (table, item) {

                if (item.category.toLowerCase() == "product") {
                    return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a href='ProductDetails.aspx?Id=" + item.value + "'>" + item.label + "</a>") // need the actual URL for a product details page
                .appendTo(table.find("ul.products"));
                }

                if (item.category.toLowerCase() == "accessory") {
                    return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a href='ProductDetails.aspx?Id=" + item.value + "'>" + item.label + "</a>") // need the actual URL for a product details page
                .appendTo(table.find("ul.accessories"));
                }

                if (item.category.toLowerCase() == "category") {
                    return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a href='ProductSearch.aspx?q=" + item.value + "'>" + item.label + "</a>") // need the actual URL for a product search page
                .appendTo(table.find("ul.categories"));
                }

                // default if a category was not matched, just append a row to the containing table
                return $("<tr></tr>")
                .data("item.autocomplete", item)
                .append("<td colspan='3'>" + item.label + "</td>")
                .appendTo(table);
            }
        });

    $(function () {
        $("#tbSearchBox").threecolumnautocomplete({
           .
           .
           .

回答by Matt Wickless

Thanks Lance for putting me on the right track. This answer is selectable and works in jquery-ui-1.11.4.

感谢 Lance 让我走上正轨。这个答案是可选择的并且适用于 jquery-ui-1.11.4。

$.ui.autocomplete.prototype._renderMenu = function (ul, items) {
    var self = this;
    ul.append("<li class='ui-autocomplete-category' aria-label='header'><div class='listFullName listHeader'>Name</div><div class='listEmployeeID listHeader'>Employee ID</div><div class='listJobTitle listHeader'>Job Title</div></li>");
    $.each(items, function (index, item) {
        self._renderItemData(ul, item);
    });
};

$.ui.autocomplete.prototype._renderItem = function (table, item) {
    return $("<li>")
      .data("item.autocomplete", item)
      .append("<div class='listFullName'>" + item.label + "</div>" + "<div class='listEmployeeID'>" + item.value + "</div>"  + "<div class='listJobTitle'>" + item.JobTitle + "</div>")
      .appendTo(table);
};
$("#employeeLookup").autocomplete({
    source: [
        { value: 1, label: "Bob Smith", JobTitle: "President" },
        { value: 2, label: "Bob Washington", JobTitle: "Vice-President" },
        { value: 3, label: "Bobby Fischer", JobTitle: "Secretary" },
        { value: 4, label: "Bobby Brady", JobTitle: "Treasurer" },
        { value: 5, label: "Bobby Socks", JobTitle: "Senior Vice-President" },
        { value: 6, label: "Barney Rubble", JobTitle: "Sidekick" },
        { value: 7, label: "Brenda Stevens", JobTitle: "Assistant Senior Vice-President" }
    ],
    minLength:1
});

Here's the CSS I then add to format the columns:

这是我添加的用于格式化列的 CSS:

.listFullName{
    width:200px;
    display:inline-block;
}
.listJobTitle{
    width:150px;
    display:inline-block;
}
.listEmployeeID{
    width:100px;
    display:inline-block;
}

Note that I add the 'ui-autocomplete-category' class to the header row to prevent it from being selectable in the results. I add the aria-label attribute to avoid a jQueryUI runtime exception apparently caused by encountering a list item that wasn't rendered using _renderItemData, although I did not do a deep dive into that.

请注意,我将 'ui-autocomplete-category' 类添加到标题行以防止它在结果中被选择。我添加了 aria-label 属性以避免 jQueryUI 运行时异常,这显然是由于遇到未使用 _renderItemData 呈现的列表项而引起的,尽管我没有对此进行深入研究。

Now, if you are pulling data via ajax, such as in the following example:

现在,如果您通过 ajax 拉取数据,例如在以下示例中:

$("#employeeLookup").autocomplete({
    source: function (request, response) {
       // var id = $(this);
       // alert(id);
        $.ajax({
            url: "Search.asmx/FindEmployee",
            data: "{ 'partialName': '" + request.term + "'}",
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataFilter: function (data) { return data; },
            success: function (data) {
                response($.map(data.d, function (item) {
                    return {
                        FullName: item.FullName,
                        EmployeeID: item.Person_ID,
                        JobTitle: item.JobTitle,
                        label: item.FullName,
                        value:item.FullName
                    }
                }))
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert(XMLHttpRequest);
            }
        });
    },
    minLength: 3,
    delay: 500,
    select: function (event, ui) {
         alert("select" + ui.item.FullName);
    }
});

You could change the _renderItem override to this:

您可以将 _renderItem 覆盖更改为:

$.ui.autocomplete.prototype._renderItem = function (table, item) {
    return $("<li>")
      .data("item.autocomplete", item)
      .append("<div class='listFullName'>" + item.FullName + "</div>" + "<div class='listEmployeeID'>" + item.EmployeeID + "</div>"  + "<div class='listJobTitle'>" + item.JobTitle + "</div>")
      .appendTo(table);
};

In the Success event, jQueryUI is looking for "label" and "value" elements in the resulting array. You can map other elements as well for your own coding clarity, but "label" is the array element that jQueryUI Autocomplete will search/filter by, and "value" is the array element that JQueryUI Autocomplete will put into the html input once you select a value from the list.

在 Success 事件中,jQueryUI 在结果数组中寻找“label”和“value”元素。为了您自己的编码清晰,您也可以映射其他元素,但“标签”是 jQueryUI 自动完成将搜索/过滤的数组元素,而“值”是您选择后 JQueryUI 自动完成将放入 html 输入的数组元素列表中的一个值。

回答by Brian Cauthon

The post you reference is using a callback for the source instead of a url. The important part of it is the success callback on the ajax function. It takes response from the server and maps it to an object that the autocomplete expects to recieve:{label: '', value: ''}. In that example they are setting the label (which shows in the menu) to the html they want displayed.

您引用的帖子使用的是源的回调而不是 url。它的重要部分是对 ajax 函数的成功回调。它从服务器获取响应并将其映射到自动完成期望接收的对象:{label: '', value: ''}。在该示例中,他们将标签(显示在菜单中)设置为他们想要显示的 html。

If you look at the autocomplete source the actual rendering of each item is handled by _renderItem, each label is wrapped by an <a>and then appended to an <li>element.

如果您查看自动完成源,每个项目的实际渲染是由 _renderItem 处理的,每个标签都由 包裹<a>,然后附加到一个<li>元素。

If what you want to do cannot be handled by setting the item label to whatever html you want to display, you could try and monkeypatch as described here.

如果您无法通过将项目标签设置为您想要显示的任何 html 来处理您想要做的事情,您可以按照此处所述尝试使用monkeypatch 。

Post some of your code and I might be able to help with a more concrete example.

发布您的一些代码,我可能会帮助提供更具体的示例。

回答by MIkee

I know this is an old thread but this widget supports multi column autocomplete

我知道这是一个旧线程,但此小部件支持多列自动完成

Here is a demo pageusing multi column autocomplete

这是一个使用多列自动完成功能的演示页面

The code below shows how to create a multi column autocomplete input:

下面的代码显示了如何创建多列自动完成输入:

$('input#starttime').menuoptions({
                                    "Data": $("body").data("alltimes"),

                                    "ClearBtn": true,
                                    "onSelect": function(e, data) { 
                                        ResetEndTimeData(data.newVal); 
                                    }, 
                                    "ColumnCount": 4,
                                    "Width": 300,
                                    "Height": 200,
                                    "Sort": []
                                    });