Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Creating Auto-Suggest Textbox Using ASP.NET 2.0 Client Callbacks

4.58/5 (15 votes)
15 Jun 20073 min read 2   1.6K  
Implementing an auto-completion feature using ASP.NET 2.0 client callbacks

Introduction

Auto-Completion is a very interesting feature that was primarily made popular by Google. I have already written a couple of articles that explain how to implement this feature. In this article, I will implement the auto-completion feature using ASP.NET 2.0 client callbacks.

Database design

I will be using the Northwind database, which is the default database for SQL SERVER 7 and SQL SERVER 2000.

Class diagram

I tried to keep the code organized and implemented different classes. Take a look at the class diagram below:

Screenshot - tn_AutoSuggestUsingCallbacks1.jpg

Explanation

  • Product: The Product class is a simple entity class which exposes ProductName as the public property.
  • ProductRepository: ProductRepository is responsible for performing the CRUD operations on the products.
  • CacheRepository: CacheRepository is used to hold the data into the HttpCache object. This will prevent from unnecessary database access.
  • HTMLTableHelper: This class is responsible for creating the HTML table.
  • DataAccess: The DataAccess class is used to access the database.
  • The GetProduct method: The GetProduct method is responsible for retrieving the products.

Let's check out the code:

C++
public static IList<Product> GetProducts(string criteria)
{
    string key = "Products_" + criteria[0];
    IList<Product> list = CacheRepository.GetObjects<Product>(key);
    if (list == null || list.Count == 0)
    {
        list = DataAccess.GetProducts(criteria);
        CacheRepository.SaveObject(key, list);
    }

    // return the list based on the criteria
    List<Product> productList = list as List<Product>;       
    list = productList.FindAll(delegate(Product product)
    {
        return product.ProductName.ToLower().StartsWith(criteria.ToLower());
    });
    return list;
}

The GetProducts method takes the string variable criteria as an input parameter. After that, a key is generated that is based on the keyword Products and the first character of criteria. This means that if you type "C" then the generated key will be Products_C. CacheRepository uses the key to find the products in the cache. If the products are not found in the cache, then they are retrieved from the database. Otherwise, the matching products are returned from the cache. I have used the anonymous method to search for the matching items in the list.

C++
list = productList.FindAll(delegate(Product product)
{
    return product.ProductName.ToLower().StartsWith(criteria.ToLower());
});

CacheRepository simply saves and retrieves the items from the cache. Take a look at the two methods exposed by it:

C++
public static IList<T> GetObjects<T>(string key)
{
    IList<T> list = (IList<T>) HttpContext.Current.Cache[key];
    return list;       
}

public static void SaveObject(string key, object obj)
{
    HttpContext.Current.Cache.Insert(key, obj);
}

Registering client callbacks

In order to use the ASP.NET 2.0 Client Callbacks feature, you will first need to register it. Take a look at the code below, which registers the client callbacks.

C++
private void RegisterClientCallbacks()
{
    string callbackRef = ClientScript.GetCallbackEventReference(this, "arg", 
        "RecieveServerData", "context");
    string script = String.Empty;
    if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))
    {
        script = "function CallServer(arg,context) { " + callbackRef + "}";
        ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", 
            script, true);
    }
}

Implementing the client script

Now, let's check out the client code that is used to trigger the server-side method. The callback method is fired when the user types some text in the textbox. The textbox onKeyDown event is responsible for calling the server method.

Enter Search Text: <input type="text" onkeydown="return GetProducts(event)" id="txtSearch" name="txtSearch" />

The JavaScript GetProducts function sends the request to the appropriate functions depending on the keystroke.

C++
function GetProducts(e)
{
    var keynum
    var keychar
    var numcheck

    if(window.event) // IE
    {
        keynum = e.keyCode
    }
    
    else if(e.which) // Netscape/Firefox/Opera
    {
        keynum = e.which
    }

    keychar = String.fromCharCode(keynum)
    numcheck = /\d/

    // If the down key is pressed

    if(keynum == DOWN)
    {  
        MoveCursorDown();   
        return;
    }
    
    else if(keynum == UP)
    {  
        MoveCursorUp();   
        return;
    }

    else if(keynum == ENTER)
    {
        if(IsFireFox())
        {
            document.getElementById("txtSearch").value = 
                selectedRow.childNodes[1].innerHTML;
        }

    else
    {
        document.getElementById("txtSearch").value = selectedRow.innerText;
    }

    document.getElementById("results").innerHTML = '';

    // false is returned so that the postback won't occur when 
    // the return key is pressed
    return false;
}

if(keynum != DOWN && keynum != UP && keynum >= 65 && keynum <= 90)
{
    word = word + keychar;
}

else if(keynum == BACKSPACE)
{
    word = word.substring(0,word.length-1);
}

// Call the server side method
CallServer(word,'');
}

Let's check out the MoveCursorDown function, which is fired when the user presses the down arrow key from the keyboard.

C++
function MoveCursorDown()
{
    selectedRow = null;
    table = document.getElementById("MyTable");
    if(table == null) return;
    rows = table.getElementsByTagName("TR");
    if(index < rows.length)
    {  
        if(index < rows.length -1)
        {
            index++;      
            SetDefaultRowColor();         
            selectedRow = rows[index];
            selectedRow.className = 'HighlightRow';  
        }
    }
}

As you can see in the above code, first I check if the index is less than the total number of rows minus 1. If that is the case, then the selectedRow is highlighted with a different color. Take a look at the screenshot below:

Screenshot - tn_AutoSuggestUsingCallbacks2.jpg

There is a lot more JavaScript code used in this demo. All of the code is available for download at the top of this article.

Similar articles

Conclusion

Auto-completion is a very handy feature for any website. It gives users the ability to search thousands of records without iterating through them incrementally.

History

  • 15 June, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here