Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery UI Autocomplete Rendering Categories with Links

I'm using JQuery UI Autocomplete for quick search widget. I have several grouped items like hotels, cities, areas etc. I could render categories, but I couldn't link them. When I try, ui autocomplete plugin detect categories like items. That's not problem, but when I focused them using up/down arrow or using mouse, it returns me an error like this:

"TypeError: item is undefined. this.liveRegion.text( item.value );"

How can I fix this? I try to use JQuery UI Autocomplete's "focus" event with several methods (like 'return false, e.stopPropagation or e.preventDefault'), but it didn't work

Here's my code:

$.widget("custom.catcomplete", $.ui.autocomplete, {
        _renderMenu: function (ul, items) {
            var searchkey = "";
            var itemtype = "";
            var searchtype = "";

            var self = this, currentCategory = "";
            $.each(items, function (index, item) {
                if (typeof item.kelime != 'undefined') { searchkey = item.kelime; }
                if (item.category != currentCategory) {
                    if (item.category == "Bölge" || item.category == "Şehir") {
                        itemtype = "cat-bolgeler";
                    } else if (item.category == "Otel") {
                        itemtype = "cat-oteller";
                        searchtype = "otel";
                    } else if (item.category == "Yurt Dışı Tur") {
                        itemtype = "cat-ydtur";
                        searchtype = "yurtdisitur";
                    } else if (item.category == "Yurt İçi Tur") {
                        itemtype = "cat-yitur";
                        searchtype = "yurticitur";
                    } else if (item.category == "Cruise") {
                        itemtype = "cat-cruise";
                        searchtype = "cruise";
                    }
                    if (searchtype != "") {
                        ul.append("<li class='ui-autocomplete-category " + itemtype + "' id='" + item.searchid + "'><a href='/arama/" + searchkey + "?k=" + searchtype + "&q=" + searchkey + "'>" + item.category + "</a></li>");
                    } else {
                        ul.append("<li class='ui-autocomplete-category " + itemtype + "' id='" + item.searchid + "'>" + item.category + "</li>");
                    }
                    currentCategory = item.category;
                }
                self._renderItem(ul, item);
            });
        }
    });

    $(".hizliaratext").catcomplete({
        source: function (request, response) {
            $.ajax({
                url: '/filename.aspx',
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                type: "get",
                data: { kelime: request.term },
                success: function (data) {
                    response($.map(data, function (item) {
                        return {
                            label: item.label,
                            searchid: item.searchid,
                            category: item.category,
                            link: item.link,
                            kelime: item.kelime
                        }
                    }));
                }
            });
        },
        minLength: 3,
        appendTo: "#hizliara",
        select: function (event, ui) {
            window.location = ui.item.link;
        },
        focus: function (event, ui) {
        }
    }).data("catcomplete")._renderItem = function (ul, item) {
        return $("<li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").appendTo(ul);
    };

Here's the sample JSON response for "?kelime=anka":

[{"searchid":2001,"label":"Alba Ankara Hotel","category":"Otel","link":"/otel-detay/alba-ankara-hotel","kelime":"anka"},{"searchid":2238,"label":"Ankara Madi İnci Hotel","category":"Otel","link":"/otel-detay/ankara-madi-inci-hotel"},{"searchid":2244,"label":"Madi Hotel Ankara","category":"Otel","link":"/otel-detay/madi-hotel-ankara"},{"searchid":2403,"label":"City Hotel Ankara","category":"Otel","link":"/otel-detay/city-hotel-ankara"},{"searchid":2404,"label":"Doğa Residence Ankara","category":"Otel","link":"/otel-detay/doga-residence-ankara"},{"searchid":6779,"label":"Ankara","category":"Şehir","link":"/ustaramaliste.aspx?y=6779"},{"searchid":6785,"label":"Ankara / Çankaya","category":"Bölge","link":"/ustaramaliste.aspx?y=6785"},{"searchid":14601,"label":"İzmir / Çankaya","category":"Bölge","link":"/ustaramaliste.aspx?y=14601"}]
like image 511
fgokalp Avatar asked Dec 07 '12 13:12

fgokalp


1 Answers

Sounds (and looks) like you want the select/focus event for the category items (if this isn't the case I'll update my answer).

The autocomplete widget internally expects list items to have item.autocomplete data associated with them. In order to get around the error, you could create your "category" items with the appropriate data. This will enable you to react to the select event and get rid of the error occurring on the focus event:

Updated widget code:

$.widget("custom.catcomplete", $.ui.autocomplete, {
    _renderMenu: function(ul, items) {
        var searchkey = "";
        var itemtype = "";
        var searchtype = "";

        var self = this,
            currentCategory = "";
        $.each(items, function(index, item) {
            if (typeof item.kelime != 'undefined') {
                searchkey = item.kelime;
            }
            if (item.category != currentCategory) {
                if (item.category == "Bölge" || item.category == "Şehir") {
                    itemtype = "cat-bolgeler";
                } else if (item.category == "Otel") {
                    itemtype = "cat-oteller";
                    searchtype = "otel";
                } else if (item.category == "Yurt Dışı Tur") {
                    itemtype = "cat-ydtur";
                    searchtype = "yurtdisitur";
                } else if (item.category == "Yurt İçi Tur") {
                    itemtype = "cat-yitur";
                    searchtype = "yurticitur";
                } else if (item.category == "Cruise") {
                    itemtype = "cat-cruise";
                    searchtype = "cruise";
                }
                if (searchtype != "") {
                    ul.append($("<li class='ui-autocomplete-category " + itemtype + "' id='" + item.searchid + "'><a href='/arama/" + searchkey + "?k=" + searchtype + "&q=" + searchkey + "'>" + item.category + "</a></li>").data("item.autocomplete", {}));
                } else {
                    ul.append($("<li class='ui-autocomplete-category " + itemtype + "' id='" + item.searchid + "'>" + item.category + "</li>").data("item.autocomplete", {}));
                }
                currentCategory = item.category;
            }
            self._renderItem(ul, item);
        });
    }
});

Example: http://jsfiddle.net/J5rVP/20/

like image 122
Andrew Whitaker Avatar answered Oct 12 '22 12:10

Andrew Whitaker