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

Introduction: 

Auto-Completion is a very interesting feature which was primarily made popular by Google. I have already written couple of articles which explains 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:

 

 

Explanation:

 

Product: 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:

 

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 which is based on the keyword “Products” and the first character of the criteria. This means if you type “C” then the generated key will be “Products_C”. The 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.

 

        list = productList.FindAll(delegate(Product product)

        {

            return product.ProductName.ToLower().StartsWith(criteria.ToLower());

        });

 

 

CacheRepository:

 

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

 

   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.

 

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 which 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.

 

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.

 

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 that 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 different color.

 

Take a look at the screen shot below:

 

 

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

 

Similar Articles:

 

1)    Auto Suggest Using AJAX.NET Library

2)    Google Suggest Functionality Using AJAX

 

Conclusion:

 

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

 

[Download Sample]