TheAJAX Control Toolkit provides a lot of control extender options for many of the common tasks used often in Web-based applications. One such extender is the AutoComplete text extender, which provides a forward look-up feature to select a value from a list of values that match a prefix string.
When the user types a part of the text (searchPrefix) in the associated textbox, an asynchronous call is made to a WebMethod (a PageMethod can be used as an alternative) and a searchPrefix is passed as a parameter. The WebMethod uses the prefix to search for all matches using the underlying data provider. The minimum number of characters needed for the WebMethod call can be configured. The WebMethod returns a string array containing all the matches for the searchPrefix parameter.
Background and Motivation
The default implementation of the AutoCompleteExtender doesn t have a value associated with the chosen key in the forward look-up list. This is a shortcoming in cases where one would want a corresponding value string used to populate other related fields. By using the solution proposed in this article, we can have the more detailed value string with a chosen key in the list. This behavior is similar to that of a DropDownList, where every Text entry in the list is associated with a Value entry.
Figure 1 illustrates an Employee entry page where the employees can be searched with a search string. When an employee is selected from the list, more detailed information can be accessed with the value associated with the key. In this example, the key Employee7 is associated with the more detailed value of FullName, Department, Address, City, and ZipCode. Figure 1 shows the look-up search starting with the prefix Emp .
Figure 1: A sample Employee entry page.
With the proposed solution, once an employee in the list is chosen, the associated values for the full name, description, address, state, ZIP code, and any other relevant information can be retrieved via the associated value attribute. There is a clear advantage of not cluttering the look-up list with too much information.
For each selected employee key in the list, there s an object instance with the values of FullName, Department, Address, City, and ZipCode. The object instance is serialized into a JSON format string and is associated with a Key value. The Web method would return a Key-Value collection, one entry for each employee. The value string is deserialized into an object that is used for updating the DOM. Figure 2 shows the value string for the chosen key being used to fill the related data fields.
Figure 2: The value string for the chosen key.
The user enters some prefix text, which is used for an asynchronous call to a Web service. The Web method returns a custom collection of Keys that match the prefix text, along with their associated values. The keys are used in the DOM to update the matching list. When the user selects one of these keys, the associated value is stored in the AutoCompleteExtender client-side object instance. Figure 3 shows this flow.
Figure 3: High-level system flow.
The current WebMethod signature is shown here:
Here s the proposed WebMethod signature:
The class DataItem consists of a Key and a Value as shown below
public class DataItem
public string Key;
public string Value;
In cases where the Value associated with a Key is more than a string literal, the Value associated with the Key is returned as a JSON encoded string.
If for every key there is a corresponding object instance, the object instance can be serialized and passed to the client side as a JSON string. The advantage of using JSON is that the client-side script can use a structured entity for further manipulation of DOM instead of parsing a string value.
There is a new property named EnableValueField added to the AutoCompleteExtender. This property determines if we want to associate a Value with a given Key. The default Value is set to false. The steps followed for this enhancement are:
- Include EnableValueField (a Boolean property)
- Modify the AutoCompleteBehavior.js file
- Include a WebMethod with the suggested signature
The listing in Figure 4 shows the property defined in the AutoCompleteExtender.cs (or .vb) source.
Figure 4: The property defined in the AutoCompleteExtender source.
The WebMethod with the modified signature to return a Key-Value collection can be used with the EnableValueField set as true. If the default behavior is desired, the WebMethod returning a string array can be used with EnableValueField set as false. Both these scenarios are shown in the prototype page.
The listings in Figure 5 and Figure 6 show the default initialization of this property and the supporting methods in AutoCompleteBehavior.js.
Figure 5: The highlighted region shows the initialization of the newly added field.
Figure 6: New properties to enable and access a Value field associated with a key.
The function _setText(text) checks whether the _enableValueField is set to associate a Value with the chosen key in the list of received keys from the asynchronous call. The value of _enableValueField is determined by the EnableValueField property. The value associated with the selected key is stored in the field _currentValue. This behavior is shown in Figure 6 in the function _setcurrentValue.
The function responsible to list the items returned by the Web method that matches the prefixText is _update, as shown in the listing in Figure 7.
Figure 7: The _update function.
While updating the DOM, this function also looks at the value of _enableValueField to determine if the autocomplete list is to be constructed by using the key part of the Key-Value collection or use the default behavior to iterate through the string collection returned by the WebMethod. The script block in Figure 8 shows how the Value stored in _currentValue is used at the client-side script to manipulate the DOM and update the related fields for the employee.
Figure 8: Use _currentValue to manipulate the DOM.
By changing the extender WebMethod signature return value from string to List<DataItem>, the control is enhanced to have both the display and value attributes, as in the case of a DropDownList. A custom Boolean property, EnableValueField, is created, which can be configured declaratively and programmatically to decide whether or not to have the value attribute for a chosen key in the list of matches. The example code shows both scenarios. The source code for AjaxControlToolkit used in this article is based on version 10301.
Files referenced in this article are available for download.
Deepak Raghavan has been involved with Web-based technologies for the past six years and currently works as a Senior .NET Developer/Architect in Minneapolis. His interests lie in the upcoming Microsoft technologies, SOA, DSL, Software Factories, Agile, and XP, to name a few. He holds a Masters degree in Electrical Engineering and MCAD.NET certification.