Search code examples
c#jquery-uijquery-ui-autocompletewebmethod

Textbox autocomplete not populating from WebMethod returning object


I have a textbox hooked up to jQuery UI Autocomplete widget. The source for the autocomplete is a WebMethod returning a list of 'Person' objects. The user will start typing a persons name and then makes their selection from the autocomplete list. I then want several other textboxes to populate with values (company, phone, email, etc) based on the item selected from autocomplete list. These other values are contained in the returned 'Person' object.

My WebMethod is successfully populating the list of objects but the autocomplete list does not appear when the user enters text. I'm not sure how to tell if the list of objects is actually being properly passed back out to the jQuery Autocomplete.

So this is a 2 part question:

  1. Why is the autocomplete list not populating?
  2. Is my code to populate the secondary textboxes correct?

Please note that I have looked at all the other 'could be percieved to be duplicate' questions but none of them addressed this particular scenario.

My Person class:

public class Person
{
    //New properties -------------
    public string label {get; set;}
    public string value {get; set;}
    // ----------------------------
    public string Name {get; set;}
    public string Company {get; set;}
    public string Phone {get; set;}
    public string Mobile {get; set;}
    public string Email {get; set;}
    public string Fax {get; set;}
}

The HTML/Javascript:

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    <link href="Scripts/themes/ui-lightness/jquery.ui.all.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery-1.5.1.min.js" type="text/javascript"></script>
    <script src="js/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True">
    </asp:ScriptManager>
    <div>
        <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
    </div>
    <div>
        <asp:TextBox ID="txtCompany" runat="server" ></asp:TextBox>
        <asp:TextBox ID="txtPhone" runat="server" ></asp:TextBox>
        <asp:TextBox ID="txtMobile" runat="server" ></asp:TextBox>
        <asp:TextBox ID="txtEmail" runat="server" ></asp:TextBox>
        <asp:TextBox ID="txtFax" runat="server" ></asp:TextBox>
    </div>
    <script type="text/javascript">
        PageMethods.SearchContacts(function (results) {
            $("#txtName").autocomplete({
                source: results,
                select: function (event, ui) {
                    $('#txtCompany').val(ui.item.company);
                    $('#txtPhone').val(ui.item.phone);
                    $('#txtMobile').val(ui.item.mobile);
                    $('#txtEmail').val(ui.item.mobile);
                    $('#txtFax').val(ui.item.mobile);
               }
            });
        });
    </script>
</asp:Content>

The WebMethod returning list of Person objects:

[System.Web.Script.Services.ScriptMethod()]
[System.Web.Services.WebMethod]
public static List<Person> SearchContacts()
{
    try
    {
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = "SELECT Name, Company, PhoneOffice, PhoneMobile, Email, Fax FROM Contacts";
                cmd.Connection = conn;
                conn.Open();
                List<Person> contacts = new List<Person>();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        Person person = new Person();
                        //New properties --------------------
                        person.label = sdr["Name"].ToString();
                        person.value = sdr["Name"].ToString();
                        // ----------------------------------
                        person.Name = sdr["Name"].ToString();
                        person.Company = sdr["Company"].ToString();
                        person.Phone = sdr["PhoneOffice"].ToString();
                        person.Mobile = sdr["PhoneMobile"].ToString();
                        person.Email = sdr["Email"].ToString();
                        person.Fax = sdr["Fax"].ToString();
                        contacts.Add(person);
                    }
                }
                conn.Close();
                return contacts;
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}

Solution

  • Figured it out with some help from Andrew

    First thing was to add 'label' and 'value' properties to my Person class. The jQuery Autocomplete widget expects the following data format for an array of objects:

    [ { label: "Choice1", value: "value1" }, ... ]
    

    Second thing was that I needed to set the ClientIDMode to 'Static' on all the textboxes.

    <asp:TextBox ID="txtName" runat="server" ClientIDMode="Static"></asp:TextBox>
    

    Third thing was that referencing the object properties in javascript is case sensitive.

    $('#txtCompany').val(ui.item.Company);  //Needed uppercase 'C' on Company to match class definition