Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Autocomplete Custom Object as Source rather than String Array

I am using JQueryUI Autocomplete and am wondering how to use a custom object as my data source (i.e. I want to pass back a list of the following type):

public class Tag
{
    public string Name { get; set; }
    public int Count { get; set; }
}

The autocomplete code that I am currently using (and that works fine when I pass back a straight forward string array of names) is pretty much a copy off the jQuery UI site:

$(function () {
        function split(val) {
            return val.split(/ \s*/);
        }
        function extractLast(term) {
            return split(term).pop();
        }

        $("#tags")
        // don't navigate away from the field on tab when selecting an item
        .bind("keydown", function (event) {
            if (event.keyCode === $.ui.keyCode.TAB &&
                    $(this).data("autocomplete").menu.active) {
                event.preventDefault();
            }
        })
        .autocomplete({
            source: function (request, response) {
                $.getJSON("Home/GetTag", {
                    term: extractLast(request.term)
                }, response);
            },
            search: function () {
                // custom minLength
                var term = extractLast(this.value);
                if (term.length < 1) {
                    return false;
                }
            },
            focus: function () {
                // prevent value inserted on focus
                return false;
            },
            select: function (event, ui) {
                var terms = split(this.value);
                // remove the current input
                terms.pop();
                // add the selected item
                terms.push(ui.item.value);
                // add placeholder to get the comma-and-space at the end
                terms.push("");
                this.value = terms.join(" ");
                return false;
            }
        });
    });

The only thing I've changed from the original demo source is the Url and I'm splitting on a space rather than comma (for multiple autocomplete).

Here's the HTML:

<div class="ui-widget">
    <label for="tags">Tags: </label>
    <input id="tags"/>
</div>

Ideally, I want to present the user with a list of names, with corresponding count alongside.

like image 449
marcusstarnes Avatar asked Aug 10 '11 14:08

marcusstarnes


1 Answers

how to use a custom object as my data source

You need to format your data in a manner that the widget expects. You must have either a label property or a value property (or both) in each object in the results array in order for the widget to show your results. You can include other data in the object, as long as it meets those requirements.

To format the data coming back from the server, the convention is to use $.map:

source: function (request, response) {
    $.getJSON("Home/GetTag", {
        term: extractLast(request.term)
    }, function (data) {
        response($.map(data, function (item) {
            return {
                value: item.Name,
                count : item.Count
            };
        });
    });
},

(Untested)

This should get results populating for you. This goes hand-in-hand with the second part of your question:

Ideally, I want to present the user with a list of names, with corresponding count alongside.

This is pretty easily accomplished, following this demo as a guide:

$("#auto").autocomplete({ ... })
    .data("autocomplete")._renderItem = function(ul, item) {
        return $("<li>")
            .data("item.autocomplete", item)
            .append("<a>" + item.label + "<br />" + item.count + "</a>")
            .appendTo(ul);
    };

You can override the _renderItem function to display whatever you want, as long as it's an li that contains a tag and has data item.autocomplete.

Combine those two strategies and you should be in business. For a working example of this, check out an example here: http://jsfiddle.net/andrewwhitaker/UvegL/

This example combines a remote datasource and custom data & display. Hopefully it'll help, even though the AJAX call is a bit different.

like image 149
Andrew Whitaker Avatar answered Oct 03 '22 23:10

Andrew Whitaker