In the last article Client Callbacks in ASP.NET 2.0 I introduced the concept of remote scripting in ASP.NET 2.0. This article takes one step further and set up a real world problem and solves that problem by using Client Callbacks. This article focus on DropDownList dependencies. Consider a situation that you display a list of categories to the user and on user selection you populate another DropDownList (child list). This is a basic scenario when you select a category from a DropDownList and want to display the corresponding products in the child DropDownList. You can achieve this easily by doing a postback on the server and fetching the products from the database. However, this approach is not considered good since if there are bunch of other controls on the page then the user have to wait for the whole page to load in order to see the result. This article is focused on how you can create DropDownList dependencies without any postbacks.

Introduction:

In the last article Client Callbacks in ASP.NET 2.0 I introduced the concept of remote scripting in ASP.NET 2.0. This article takes one step further and set up a real world problem and solves that problem by using Client Callbacks. This article focus on DropDownList dependencies. Consider a situation that you display a list of categories to the user and on user selection you populate another DropDownList (child list). This is a basic scenario when you select a category from a DropDownList and want to display the corresponding products in the child DropDownList. You can achieve this easily by doing a postback on the server and fetching the products from the database. However, this approach is not considered good since if there are bunch of other controls on the page then the user have to wait for the whole page to load in order to see the result. This article is focused on how you can create DropDownList dependencies without any postbacks.

Populating the Category DropDownList: 

The first task is to populate the categories DropDownList. This can be done easily using a DataSet or a DataTable. Take a look at the code below.

private void PopulateCategoryList()

{

string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true";

SqlConnection myConnection = new SqlConnection(connectionString);

SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Categories",myConnection);

DataSet ds = new DataSet();

ad.Fill(ds);

ddlCategory.DataSource = ds;

ddlCategory.DataTextField = "CategoryName";

ddlCategory.DataValueField = "CategoryID";

ddlCategory.DataBind();

}

The code above populate the categories DropDownList.

Setting Up the Callback Function:

The next step is to set up the callback function which will receive the data returned from the server. You can do this in the Page_Load method of the Page class. Take a look at the code below.

protected void Page_Load(object sender, EventArgs e)

{

string sbReference = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");

string cbScript = String.Empty;

// check if the script is already registered or not

if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))

{

cbScript = @" function CallServer(arg,context) { " + sbReference + "}";

ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);

}

}

The ClientScript.GetCallbackEventReference is used to mark a JavaScript function which will receive the data or the result from the server. The ClientScript.IsClientScriptBlockRegistered is used to check that if the script has already been registered or not. If the script is not registered then the function CallServer is registered using the ClientScript.RegisterClientScriptBlock method. The CallServer method takes two arguments which is the argument and the context.  

After registering the ClientScript you need to implement the GetCallback and RaiseCallback events. The RaiseCallback event is fired whenever you make a call to the CallServer method which we have injected into the page inside the Page_Load event.

// protected variable

protected string returnValue;

public void RaiseCallbackEvent(string eventArgument)

{

if (!String.IsNullOrEmpty(eventArgument))

{

returnValue = eventArgument;

}

else

{

// Set a flag so that the GetCallbackResult is not called.

}

}

The RaiseCallbackEvent takes a single parameter which is the eventArgument. In this case we will be passing the categoryID as the eventArgument so that we can get all the products from the Products table based on the categoryID.

The next method that is fired is the GetCallbackResult. This method is responsible for sending the data back to the client. The only limitation of the ASP.NET 2.0 client callbacks is that it can only return the string data back to the client.

public string GetCallbackResult()

{

return GetProductsByCategoryID(Int32.Parse(argumentValue));

}

The GetProductsbyCategoryID returns the products based on the categoryID. Let's take a look at this method.

private string GetProductsByCategoryID(int categoryID)

{

string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true";

SqlConnection myConnection = new SqlConnection(connectionString);

SqlCommand myCommand = new SqlCommand("SELECT * FROM Products WHERE CategoryID = @CategoryID", myConnection);

myCommand.Parameters.AddWithValue("@CategoryID", categoryID);

SqlDataAdapter ad = new SqlDataAdapter(myCommand);

DataSet ds = new DataSet();

ad.Fill(ds);

DropDownList ddlProducts = new DropDownList();

ddlCategory.ID = "ddlProducts";

ddlProducts.DataSource = ds;

ddlProducts.Attributes.Add("onChange", "PopSelectedProductID(this.value)");

ddlProducts.DataTextField = "ProductName";

ddlProducts.DataValueField = "ProductID";

ddlProducts.DataBind();

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

ddlProducts.RenderControl(htw);

return sw.ToString();

}

The code above simply goes to the Products table and gets all the products based on the categoryID. In my last article Client Callbacks in ASP.NET 2.0 I presented a reason that why I used HtmlTextWriter and StringWriter instead of building up the HTML control by appending strings. You can view the reason at this link.

Implementing the JavaScript Functions:

The last step is to implement the JavaScript functions that will send and receive the data from the server side methods. Here is the HTML code:

<div class="CategoryDropDownList">

Select a category:

<asp:DropDownList ID="ddlCategory" onChange="GetSelectedProducts(this.value)" runat="server" />

</div>

<div class="ProductsDropDownList">

<table>

<tr>

<td colspan="2">

Select a product: </td><td> <div id="MyDiv"></div>

<script language="javascript" type="text/javascript">

function GetSelectedProducts(selectedValue)

{

CallServer(selectedValue,'');

}

function RecieveServerData(rValue)

{

document.getElementById("MyDiv").innerHTML = rValue;

}

</script>

Conclusion:

ASP.NET 2.0 Client Callbacks is a very strong feature that enables the developers to create a smooth experience for the user. There is much more to cover on client callbacks and which we will see in the later articles.

I hope you liked the article, happy coding!