Improving Ajax Control Toolkit Autocomplete
August 21st, 2008
I found a workaround to improve the Ajax Control Toolkit Autocomplete Extender look.
By default, Autocomplete shows a list of texts, but we were looking for something a little more fancy, showing also a description (or any custom HTML).
Some things had to be done:
· Customize server response
· Re-render the dropdown list
· Hook the item selection event
Customize serialization
Autocomplete behavior has some kind of support for key/value pairs, and not only to standard string arrays, but not in the way I expected it to do.
I expected that a System.Web.UI.Pair[] had to be return, but instead, it had to be an array of Json objects similar to the System.Web.UI.Pair.
I took advantage of the DataContractJsonSerializer to make it work with Autocomplete extender.
Sending some data
The .First property is taken as the text to be displayed in the list and the .Second field is taken as the Value to set into the textbox (Autocomplete target).
Re-rendering the dropdown list
As Autocomplete behavior encodes the text to display to HTML, so it can be displayed correctly, here is a little workaround to that feature, which is an obstacle for our approach:
Set the OnClientShowing property of the extender to the following JS function:
function acItemShowing (sender, args)
{
var c = sender.get_completionList ();
if (c.childNodes.length > 0)
{
for(var i = 0; i <c.childNodes.length; i++)
{
c.childNodes[i].innerHTML = c.childNodes[i].firstChild.nodeValue;
}
}
}
This function will make the display values to be shown as HTML.
Retrieving the selected value
As the value of the selected item was in the root element, but it is not present in the element which fired the selection event (one of the tags of the elements that we re-rendered), we need to retrieve that value.
By hooking a custom function on the OnItemSelected we can retrieve that value form the parent element.
function acItemSelected (sender, args)
{
var item = args.get_item ();
var cl = sender.get_completionList ();
while (item != null && item.parentNode != cl)
{
item = item.parentNode;
}
args = new AjaxControlToolkit.AutoCompleteItemEventArgs(item, item._value, item._value);
sender.get_element().value = args.get_value ();
}
Known issues
After this modifications, something has been missed for Internet Explorer, items won’t highlight correctly when hovering the items. Even thus, when clicking or selecting the element by keyboard will work ok. I hope to be able to fix this later.
Thanks,
Diego