jQuery UI Autocomplete categories with count mechanism
Asked Answered
J

2

7

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>
Jamilajamill answered 9/5, 2012 at 15:28 Comment(2)
I think one problem with that jQuery UI example is that the items in the list have to be grouped also by category, otherwise the categories repeat. For example, if you add another product at the end of the data array, you'll end up with a second Products category after the first People category.Huntley
I agree on the issue with category grouping. There must be a way to iterate through the results, group them into an array separated by category, then output the results list based on that array.Jamilajamill
W
3

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/

Weis answered 10/5, 2012 at 1:46 Comment(0)
Q
0
$.widget("custom.catcomplete", $.ui.autocomplete, {
            _renderMenu: function (ul, items) {
                var self = this,
                currentCategory = "", itemCount = 0, itemsLength = items.length - 1;
                $.each(items, function (index, item) {
                    if (item.category != currentCategory) {
                        ul.find('.ui-autocomplete-category:last').text(function () { return $(this).text() + ' ' + itemCount });
                        ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
                        currentCategory = item.category;
                        itemCount = 1;
                    }
                    else {
                        itemCount++;
                    }

                    if (index === itemsLength) {
                        ul.find('.ui-autocomplete-category:last').text(function () { return $(this).text() + ' ' + itemCount });
                    }

                    self._renderItem(ul, item);
                });
            }
        });
Quintero answered 10/5, 2012 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.