Tuesday, January 22, 2013

Ajax AutoCompleteExtender


One of the many control extenders in the ASP.NET AJAX Control Toolkit is the AutoCompleteExtender, which allows you to show a list of suggestions while a user types in another control (such as a text box). Figure 25-9 shows the AutoCompleteExtender at work on an ordinary TextBox control. As the user types, the drop-down list offers suggestions. If the user clicks one of these items in the list, the corresponding text is copied to the text box.


To create this example, you need an ordinary text box, like this:
Contact Name:<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
Next, you need to add the ScriptManager and an AutoCompleteExtender control that extends the text box with the autocomplete feature. The trick is that the list of suggestions needs to be retrieved from a specialized code routine called a web method, which you need to create in your page.

Here’s an example of how you might define the AutoCompleteExtender. It uses the TargetControlID property to bind itself to the txtName text box, and it sets the MinimumPrefixLength property to 2, which means autocomplete suggestions won’t be provided until the user has entered at least two characters of text. Finally, the ServiceMethod property indicates the web method you’re going to use is named GetNames(). Before you can run this page, you need to create that method.
<ajaxToolkit:AutoCompleteExtender ID="autoComplete1" runat="server"
TargetControlID="txtName" ServiceMethod="GetNames" MinimumPrefixLength="2">
</ajaxToolkit:AutoCompleteExtender>
The next step is to create the GetNames() web method. Here’s the basic method you need to add to the code-behind class of your web page:
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static List<string> GetNames(string prefixText, int count)
{ ... }
The web method accepts two parameters, which indicate the text the user has typed so far and the desired number of matches (which is ten by default). It returns the list of suggestions. The two attributes that precede the GetNames() method indicate that it’s a web method (meaning the client should be allowed to call it directly with HTTP requests) and that it supports JavaScript calls (which is what the AutoCompleteExtender uses).

Actually writing the code that retrieves or generates the suggestion list can be quite tedious. In this example, the code retrieves the list of name suggestions from the Northwind database. 

List<string> names = null;
// Check if the list is in the cache.
if (HttpContext.Current.Cache["NameList"] == null)
{
// If not, regenerate the list.
names = GetNameListFromDB();
// Store the name list in the cache for sixty minutes.
HttpContext.Current.Cache.Insert("NameList", names, null,
DateTime.Now.AddMinutes(60), TimeSpan.Zero);
}
else
{
// Get the name list out of the cache.
names = (List<string>)HttpContext.Current.Cache["NameList"];
}
...

With the list in hand, the next step is to cut down the list so it provides only the ten closest suggestions. In this example, the list is already sorted. This means you simply need to find the starting position—the first match that starts with the same letters as the prefix text. Here’s the code that finds the first match:
...
int index = -1;
for (int i = 0; i < names.Count; i++)
{
// Check if this is a suitable match.
if (names[i].StartsWith(prefixText))
{
index = i;
break;
}
}

// Give up if there isn't a match.
if (index == -1) return new List<string>();
...

The search code then begins at the index number position and moves through the list in an attempt to get ten matches. However, if it reaches the end of the list or finds a value that doesn’t match the prefix, the search stops.
...
List<string> wordList = new List<string>();
for (int i = index; i < (index + count); i++)
{
// Stop if the end of the list is reached.
if (i >= names.Count) break;
// Stop if the names stop matching.
if (!names[i].StartsWith(prefixText)) break;
wordList.Add(names[i]);
}
...

Finally, all the matches that were found are returned:
...
return wordList;

You now have all the code you need to create the effect shown in Figure.

No comments:
Write comments
Recommended Posts × +