views:

78

answers:

3

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

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 here where 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.

+1  A: 

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.

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.

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.

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

Brian
I wrote a custom auto-complete and am hoping to replace it with this new feature, so unfortunately, my code wouldn't do much good. Essentially, I'm just trying to squeeze my returned data into a tabular format and am having trouble seeing how I could do this. Anything I've found about "multi-column" seems to be more about "multi-item" than tabular columns.
Lance May
The example you linked to is pretty straight forward so if you are still having trouble with it I'd guess that either your suggesturl isn't accepting the 'term' param in the queryString, or the response isn't coming back as a json array of objects with label/value props. Both problems are faily easy to fix in the callback.
Brian
A: 

I ended up manually overriding the _renderMenu and _renderItem functions after all. Works like a charm so far, and was actually very easy 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!

$.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
});

Lance May
A: 

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:

$.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({
           .
           .
           .
Thiago Silva