jquery-uijqueryjquery-ui-autocomplete

Transforming data returned while using jQuery's Autocomplete function


I'm trying to use the Autocomplete plugin to produce a search box similar to the one at IMDB, I want it to:

The docs say that there are 3 types of datasource it will work with:

A data source can be:

an Array with local data
a String, specifying a URL
a Callback

I can get the autocomplete to work with the 2nd option, but then there isn't the ability to transform the data returned, it just takes the JSON and puts it straight in the dropdown. This means the source url can only return data in the format {label: "blah", value: "blurg"}.

If I could inject a transformation function, then I could have the url return whatever JSON I like, the function would change the data into the format the autocomplete expects but also formatted as I wish, and all without changing the response served by the url (I'm not going to return HTML from there, only JSON).

e.g. The url could return this:

{ label:"Grosse Point Blank", id: 3, img:"/imgs/gpb.png",...}

and a transform function could mung it into something like this:

{ label:"<a href='/films/3/grosse-point-blank'><img src='/imgs/gpb.png' />Grosse Point Blank</a>", value="grosse-point-blank"}

I've tried using option 3, a callback, with a getJSON call, but I can't get it to work. The nearest code I've found to what I may need is here, but it has options that aren't listed in the current docs for Autocomplete and I don't understand how to use the response object.

Is there an example of using the callback method with an AJAX request, or how I can inject a function that transforms the code?


Solution

  • You can use the _renderItem() private method of autocomplete to format the return data. It looks like this:

    $("#element").autocomplete({...}).data( "autocomplete" )._renderItem = function( ul, item ) {
        //...
    };
    

    You can see the method definition here https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js#L520

    An example of code that I have used:

    $("#element").autocomplete({...})
    .data("autocomplete")._renderItem = function( ul, item ) {
        return $( "<li></li>" ) // create the list item
            .data( "item.autocomplete", item ) // save the data to the DOM
            .append( "<a>"+ item.label + "</a>" ) // add the HTML
            .appendTo( ul ); // append to the UL
    };