jQuery with ASP.NET

Building rich UI with jQuery and ASP.NET

How to Customize jQuery UI Autocomplete to Update Multiple Fields

without comments


This post is a response to frequently asked question – how to customize jquery UI Autocomplete widget with a custom action. Typical use case is a functionality where user can find the nearest office or a local shop. Usually system offers a list of cities to choose from. When the list is long, it makes sense to give user an option to type the city in. That combined with autocomplete feature makes the operation of finding the right office efficient and user-friendly. However after selecting the desired city system should display not only selected city but also additional information like full address, map or phone number. This is exactly where customization of jQuery Autocomplete widget comes into an account.

Customization of jQuery UI Autocomplete widget

Autocomplete widget can work with various data sources, but the most flexibility gives Callback option. Hence this the option I will use to customize the widget. But before that, I need to enhance (compering the code from the initial jQuery UI Autocomplete with ASP.NET post) the ASP.NET webservice to return not only list of strings but list of addresses. Single Address can contain arbitrary number of properties. Here is new version:

[System.Web.Script.Services.ScriptService]
public class PredictiveSearch : System.Web.Services.WebService
{
    [WebMethod]
    public IList<Address> GetAllPredictionsWithAdditionalData(string keywordStartsWith)
    {
        //TODO: implement real search here!

        // dummy implementation
        IList<Address> output = new List<Address>();
        output.Add(new Address { StreetAddress = "32 Spring Street", City = "New York", PostCode = "NJ 07302" });
        output.Add(new Address { StreetAddress = "32 Spring Street", City = "Boston", PostCode = "NJ 07302" });
        output.Add(new Address { StreetAddress = "32 Spring Street", City = "Los Angeles", PostCode = "NJ 07302" });
        output.Add(new Address { StreetAddress = "32 Spring Street", City = "Washington", PostCode = "NJ 07302" });
        return output;
    }
}

public class Address
{
    public string City { get; set; }
    public string PostCode { get; set; }
    public string StreetAddress { get; set; }
}

In second step I will modify jQuery code to work with enhanced ASP.NET webservice and use Callback data source (line 2) to process data accordingly. Within Callback function I will call ASP.NET webservice using ajax() function to get data. The most interesting things are in lines 10 to 24 where data from the webservice are transformed into a format expected by autocomplete widget.

Code has a lot of comments so I think everything should be understandable:

    $(".searchinput").autocomplete({
        source: function (request, response) {
            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "/Services/PredictiveSearch.asmx/GetAllPredictionsWithAdditionalData",
                data: "{'keywordStartsWith':'" + request.term + "'}",
                dataType: "json",
                async: true,
                success: function (data) {
                    // here I will store list of all cities which
                    // will be passed to autocomplete widget
                    var autocompleteOutput = [];

                    // looping to get all the cities out of the list of
                    // addresses returned by the webservice
                    $.each(data.d, function (index, address) {
                        autocompleteOutput[index] = address.City;
                    });

                    // passing all the available options to autocomplete widget
                    response(autocompleteOutput);

                    // store results in global variable, it will be needed
                    // later to get the rest of details for selected option
                    autocompleteData = data.d;
                },
                error: function (result) {
                    alert("Due to unexpected errors we were unable to load data");
                }
            });
        }
    });

Line 24 is important as this is where the data from webservice are stored in global variable autocompleteData and this way I have access to those data later on from other parts of jQuery code. I will use it in next step – autocomplete widget will trigger change event everytime where value in text input has been changed. I will attach my handler to this event and on each change I will display all the additional information about selected city. Please note that in line 10 I use global variable autocompleteData which contains all the data from the webservice:

    change: function (event, ui) {
        // ui.item can be null when user didn't select
        // any option from displayed hints
        // it can happen when user, regardless of displayed hints,
        // simply typed something into the text input
        // the safest option would be to take value directly from text input
        var selectedCity = ui.item ? selectedCity = ui.item.value : selectedCity = $(".searchinput").val();

        // find matching element
        var matchingElementsArray = $.grep(autocompleteData, function (item) { return item.City == selectedCity; });

        // here I'm checking if there is at least 1 matching element,
        // I expect to find exactly 1
        if (matchingElementsArray[0]) {
            // city and address are spans, the easiest way to
            // set new values is by using html() function
            $("#selectedCity").html(matchingElementsArray[0].City);
            $("#selectedAddress").html(matchingElementsArray[0].StreetAddress);
            // this is a text input, therefore different way
            // of setting the value - val() function
            $("#selectedPostCode").val(matchingElementsArray[0].PostCode);
        }
        else {
            // in this case there is something in the text input
            // but I don't have any details (address) for it on a client side
            // so here can be added a separate AJAX call to a webservice
            // to ask for missing data
            // something like:
            //
            // /Services/PredictiveSearch.asmx/GetDetailsForCity
            //
            // and selected city should be passed as a parameter
        }
    }

And this is basically it, as usually, you can download the full project with working example to experiment with it on your own.

jQuery UI Autocomplete Demo

Any questions? Just leave a comment and I will try to help.

VN:F [1.9.20_1166]
Rating: 6.2/10 (5 votes cast)
How to Customize jQuery UI Autocomplete to Update Multiple Fields, 6.2 out of 10 based on 5 ratings

Written by admin

January 3rd, 2012 at 1:17 am

Leave a Reply