JavaScript, Web

jQuery Tag-it–autocomplete with grouping

image

For many people tag-it is the most recommended tag editor plugin. I tried and I can wholeheartedly confirm.
Last time I had a requirement to add grouping to autocomplete list and I’d like to share my solution with you.

Solution

Pretty obvious and awesome feature of tag-it is that it’s built upon jQuery UI Autocomplete widget which is nicely documented and configurable. Tag-it expose “autocomplete:” as one of it’s options which means that you can bind to all of its events and customize its options as you wish.

To put grouping to autocomplete list you need to override one of the methods that autocomplete widget uses to render the list. Here is the vital part – full demo will be shown in the end of the post:


    var availableTags = [
        {category: "favourite", label: "c#",         value: "c#", },
        {category: "favourite", label: "JavaScript", value: "JavaScript"},
        {category: "other",     label: "c++",        value: "c++"},
        {category: "other",     label: "c",          value: "c"},
        {category: "other",     label: "Java",       value: "Java"},
        {category: "other",     label: "J#",         value: "J#"},
    ];

    var customRenderMenu = function(ul, items){
        var self = this;
        var category = null;
        var sortedItems = items.sort(function(a, b) {
           return a.category.localeCompare(b.category);
        });

        $.each(sortedItems, function (index, item) {
            if (item.category != category) {
                category = item.category;
                ul.append("<li class='ui-autocomplete-group'>" + category + "</li>");
            }
            self._renderItemData(ul, item);
        });
    };

    $("#tags").tagit({
        autocomplete: {
            source: availableTags,
            create: function () {
                //access to jQuery Autocomplete widget differs depending
                //on jQuery UI version - you can also try .data('autocomplete')
                $(this).data('uiAutocomplete')._renderMenu = customRenderMenu;
            }
        }
    })

In tag-it initialization block I override the default autocomplete _renderMenu function. I can agree that this can be considered as smell – overriding private (by convention) method, but to keep things simple it’s pretty clean solution.

“customRenderMenu” method is simple and I don’t feel a need to explain it. Just keep in mind, that this implementation assumes that you pass “category” as a different property of autocomplete item and the source list is initially ordered by categories.

 

Demo

Here’s a link to jsFiddle where you can try the given code: demo

Advertisements