Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Autocomplete categories with count mechanism

I am implementing the jQuery UI Autocomplete based on the categories example in the documentation. I would like to add the number of results to the Categories header, so instead of displaying "Products" it displays "Products (3)". I know the _renderMenu function needs to be modified from the example but I'm having trouble understanding how it can be modified. Any help starting me down the right path would be greatly appreciated.

Here is the example code from jQuery UI Autocomplete Categories demo:

    <script>
    $.widget( "custom.catcomplete", $.ui.autocomplete, {
        _renderMenu: function( ul, items ) {
            var self = this,
                currentCategory = "";
            $.each( items, function( index, item ) {
                if ( item.category != currentCategory ) {
                    ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
                    currentCategory = item.category;
                }
                self._renderItem( ul, item );
            });
        }
    });
    </script>
    <script>
    $(function() {
        var data = [
            { label: "anders", category: "" },
            { label: "andreas", category: "" },
            { label: "antal", category: "" },
            { label: "annhhx10", category: "Products" },
            { label: "annk K12", category: "Products" },
            { label: "annttop C13", category: "Products" },
            { label: "anders andersson", category: "People" },
            { label: "andreas andersson", category: "People" },
            { label: "andreas johnson", category: "People" }
        ];

        $( "#search" ).catcomplete({
            delay: 0,
            source: data
        });
    });
    </script>



<div class="demo">
    <label for="search">Search: </label>
    <input id="search" />
</div>
like image 593
lukemcd Avatar asked May 09 '12 15:05

lukemcd


1 Answers

One good strategy would be to create an object/hash that stores categories as keys and arrays of items matching that category as values. In other words, you want to build something like this:

{ "Products": ["annhhx10", "annk K12", /*etc*/],
  "People": ["anders andersson", "andreas andersson", /*etc*/]
}

Once you build this you can iterate through it and output each category followed by its values. The advantage of this is all you have to do to get get the number of items is take the length of the array corresponding to the current category. Something like:

$.widget("custom.catcomplete", $.ui.autocomplete, {
    _renderMenu: function(ul, items) {
        var self = this,
            categories = { };

        /* Build a dictionary/hash where keys are categories and values are 
         * arrays of items with that category 
         */
        $.each(items, function (index, item) {
            if (!categories.hasOwnProperty(item.category)) {
                 categories[item.category] = [item];
            } else {
                categories[item.category].push(item);
            }
        });

        /* Iterate over the hash we just built and display a category followed by its
         * items.
         */
        $.each(categories, function(category, items) {
            if (category) {
                ul.append("<li class='ui-autocomplete-category'>" + category + " (" + items.length + ")</li>");
            }
            $.each(items, function (index, item) {
                self._renderItem(ul, item);
            });
        });
    }
});

Example: http://jsfiddle.net/andrewwhitaker/vNtGd/

like image 66
Andrew Whitaker Avatar answered Sep 27 '22 18:09

Andrew Whitaker