Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
add comment

1 Answer

up vote 5 down vote accepted

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.

share|improve this answer
 
Thanks Andrew - Perfect solution, works great. –  marcusstarnes Aug 11 '11 at 7:42
 
@marcusstarnes: No problem! Glad to help. –  Andrew Whitaker Aug 11 '11 at 11:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.