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

时间:2010-04-30 13:20:33

标签: jquery jquery-ui autocomplete

我刚发现jQueryUI now has it's own built-in auto-complete combo box。好消息!

不幸的是,我发现接下来的事情是将其设为多列似乎并不那么简单(至少通过文档)。

有一个post here有人提到他们已经完成了(甚至提供了代码),但我无法理解他们的一些代码正在做什么。

我很好奇是否有人之前遇到过这个问题并且可以发布一个快速简单的样本来制作多列结果集。

非常感谢。

6 个答案:

答案 0 :(得分:10)

我最终手动覆盖 _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
});

答案 1 :(得分:6)

我设法使用表格布局来完成全部菜单功能,包括选择,突出显示等。我发现使用自动填充功能<table><tr><td>是不可能的,但您可以将<div>放在自动填充中项目并在CSS中使用display: table-cell。这适用于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);
        }
    });

然后像这样定义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; }

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

答案 2 :(得分:3)

您还可以扩展自动完成窗口小部件并创建自定义窗口小部件,与您正在执行的操作非常相似。下面是如何使用表格和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({
           .
           .
           .

答案 3 :(得分:2)

感谢兰斯让我走上正轨。这个答案是可选的,适用于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
});

这是我随后添加的CSS格式化列:

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

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

现在,如果您通过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);
    }
});

您可以将_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);
};

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

答案 4 :(得分:1)

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

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

如果无法通过将项目标签设置为您要显示的html来处理您想要执行的操作,则可以按照here所述尝试monkeypatch。

发布一些代码,我可以帮助我们提供一个更具体的例子。

答案 5 :(得分:0)

我知道这是一个旧帖子,但this widget supports multi column autocomplete

Here is a demo page使用多列自动填充

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

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

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