How to update the ListBox Web server control value by using asynchronous callbacks depending on the TextBox control value
To update a
ListBox Web server control value by using asynchronous callbacks, follow these steps:
- Register callback handlers by using the Page.ClientScript.GetCallbackEventReference method.
- Add an appropriate attribute to the TextBox Web server control to instantiate the asynchronous callback.
- Retrieve the ListBox control's data based on the TextBox control value that is passed as an argument-string from the client-function, and then return the data to the client in the form of a string.
- Write a script to parse the Document Object Model (DOM) in the browser.
- Update the contents.
The following example uses a
TextBox Web server control and a
ListBox Web server control to display the new functionality. This sample uses the Northwind sample database's Employees table. When you start entering text for the
LastName field in the
TextBox control, asynchronous callbacks occur. The value of the
TextBox control is passed back to the server. The employee's first name is fetched from the Employees database table depending on the text that is passed, and the data is returned to the client in a formatted string. There is a client-side JavaScript function that processes the string value and appends it to the
ListBox control.
In the following code sample, the asynchronous ClientCallback script is registered to the
TextBox control's
OnKeyUp event in the
Page_Load event of the page.
txtLastName.Attributes["OnKeyUp"] = TextBoxEventScript;
This lets the
ListBox control values be retrieved based on the text that is entered in the
TextBox control.
In the
RaiseCallbackEvent method, the field values that match the LastName value that is passed to the server are retrieved from the database. The results of the database call are built into a pipe-delimited list in the following format:
FirstName | EmployeeID || FirstName | EmployeeID
The resulting string is sent back to the client through the
GetCallbackResult function. The
ReceiveServerData JavaScript function retrieves values from the delimited string and appends the values to the
ListBox control.
lstFirstName.appendChild(option);
ASPX markup<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpdateListboxBasedOnTextbox.aspx.cs" Inherits="UpdateListboxBasedOnAnotherListbox" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<!�JavaScript function that will run when the OnKeyUp event of the TextBox control runs on the client. -->
<script language="javascript">
function ReceiveServerData(arg,context)
{
var lstFirstName = document.forms[0].elements['lstFirstName'];
lstFirstName.innerHTML= "";
var rows = arg.split('||');
for (var i = 0; i < rows.length - 1; ++i)
{
var fields = rows[i].split('|');
var firstname = fields[0];
var employeeid = fields[1];
var option = document.createElement("option");
option.value = employeeid;
option.innerHTML = firstname;
lstFirstName.appendChild(option);
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtLastName" runat="server"
Style="z-index: 100; left: 160px; position: absolute; top: 88px" Width="152px" >
</asp:TextBox>
<asp:ListBox ID="lstFirstName" runat="server"
Style="z-index: 101; left: 160px; position: absolute;top: 112px" Width="160px">
</asp:ListBox>
<asp:Label ID="lblLastName" runat="server" Height="16px"
Style="z-index: 102; left: 32px; position: absolute; top: 88px" Text="Enter Last Name:"
Width="120px">
</asp:Label>
<asp:Label ID="lblFirstName" runat="server"
Style="z-index: 103; left: 64px; position: absolute;top: 112px" Text="First Name:" Width="88px">
</asp:Label>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [firstname], [lastname] FROM [Employees]">
</asp:SqlDataSource>
<asp:Label ID="lblText" runat="server" Font-Names="Arial" Font-Size="Small" Font-Underline="True"
Style="z-index: 106; left: 32px; position: absolute; top: 56px"
Text="Enter Employee's LastName in textbox and FirstName in Listbox Will Be Updated Asynchronously"
Width="600px">
</asp:Label>
</div>
<asp:Label ID="lblTitle" runat="server" Font-Bold="True" Font-Names="Verdana"
Style="z-index: 105;left: 8px; position: absolute; top: 16px"
Text="Updating ListBox Control Asynchronously"
Width="488px">
</asp:Label>
<span id="message">
</span>
</form>
</body>
</html>
Code behindusing System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Data.SqlClient;
using System.Web.Configuration;
public partial class UpdateListboxBasedOnAnotherListbox : System.Web.UI.Page,ICallbackEventHandler
{
//This object is used to build the results of the callback function
StringBuilder arg;
protected void Page_Load(object sender, EventArgs e)
{
//Do not process Page_Load if it is a clientscript callback.
if (IsCallback)
return;
if (!Page.IsPostBack)
{
//Generate an HTML script that can instantiate an asynchronous callback onKeyUp event of
//txtLastName
string TextBoxEventScript = Page.ClientScript.GetCallbackEventReference(this, "document.all['txtLastName'].value", "ReceiveServerData", "null");
txtLastName.Attributes["OnKeyUp"] = TextBoxEventScript;
}
}
// ********************************************************************
// Implement the RaiseCallbackEvent function of the callback interface
// ********************************************************************
public void RaiseCallbackEvent(String eventArgument)
{
//Connect to the database and look up the employee based on the value passed to the server.
//In this case, the textbox value is passed in the eventArgument.
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
try
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "Select firstname,employeeid from Employees where LastName like @LastName";
cmd.Parameters.Add(new SqlParameter("@LastName", SqlDbType.NVarChar, 50));
cmd.Parameters["@LastName"].Value = eventArgument.ToString() + "%" ;
cmd.Connection = con;
con.Open();
arg = new StringBuilder();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
arg.Append(reader["firstname"]);
arg.Append("|");
arg.Append(reader["employeeid"]);
arg.Append("||");
}
reader.Close();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
con.Close();
}
}
// ********************************************************************
// Implement the GetCallbackResult function of the callback interface
// ********************************************************************
public string GetCallbackResult()
{
return arg.ToString();
}
}
How to update the DropDownList Web server control value by using asynchronous callbacks depending on another DropDownList control value
To update the
DropDownList Web server control value by using asynchronous callbacks depending on another
DropDownList control value, follow these steps:
- Register callback handlers by using the Page.ClientScript.GetCallbackEventReference method.
- Add appropriate attributes to the first DropDownList Web server control to instantiate asynchronous callbacks.
- Retrieve the second DropDownList control's data based on the DropDownList control value that is passed from the client-side JavaScript function.
- Return the values to the client in the form of a delimited string.
- Write a script to parse the DOM in the browser, and then update the contents.
The following code sample uses two
DropDownList controls,
drpEmployeeId and
drpEmployeeName. This sample uses the sample Northwind database's Employees table. The
drpEmployeeId control is data-bound to the EmployeeId column. When you select a value from the
drpEmployeeId control, an asynchronous callback occurs. The value of the
drpEmployeeId control is passed back to the server. The employee's first name is retrieved from the Employees table based on the EmployeeId data that was passed from the client. The value is returned to the client in a delimited string. The client-side JavaScript function processes the string value, and then appends the values to the
drpEmployeeNameDropDownList control.
ASPX markup<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpdateDropDownboxBasedOnAnotherDropDownBox.aspx.cs" Inherits="UpdateDropDownboxBasedOnAnotherListbox" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Asynchronous Callback - DropDownList</title>
<script language="javascript">
function ReceiveServerData(arg,context)
{
var drpEmployeeName = document.forms[0].elements['drpEmployeeName'];
drpEmployeeName.innerHTML= "";
var rows = arg.split('||');
for (var i = 0; i < rows.length - 1; ++i)
{
var fields = rows[i].split('|');
var firstname = fields[0];
var employeeid = fields[1];
var option = document.createElement("option");
option.value = employeeid;
option.innerHTML = firstname;
drpEmployeeName.appendChild(option);
document.getElementById('lblMessage').innerText = "You selected employeeid: " + employeeid + " for which FirstName is " + firstname ;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="drpEmployeeId" runat="server" DataSourceID="SqlDataSource1"
DataTextField="employeeid" DataValueField="employeeid" Style="z-index: 100; left: 144px;
position: absolute; top: 112px">
</asp:DropDownList>
<asp:DropDownList ID="drpEmployeeName" runat="server" Style="z-index: 101; left: 144px;
position: absolute; top: 136px">
</asp:DropDownList>
<asp:Label ID="lblEmployeeId" runat="server" Style="z-index: 102; left: 48px; position: absolute;
top: 112px" Text="EmployeeID:" Width="88px"></asp:Label>
<asp:Label ID="lblFirstName" runat="server" Style="z-index: 103; left: 48px; position: absolute;
top: 136px" Text="First Name" Width="88px"></asp:Label>
<asp:Label ID="lblText" runat="server" Font-Names="Arial" Font-Size="Small" Style="z-index: 104;
left: 48px; position: absolute; top: 80px" Text="Select EmployeeId from first DropDown and Second DropDown Will Be Updated Asynchronously"
Width="600px" Font-Underline="True"></asp:Label>
<asp:Label ID="lblTitle" runat="server" Font-Bold="True" Font-Names="Verdana" Style="z-index: 105;
left: 24px; position: absolute; top: 24px" Text="Updating DropDownListBox Control Asynchronously"
Width="488px"></asp:Label>
</div>
<asp:Label ID="lblMessage" runat="server" Style="z-index: 107; left: 48px; position: absolute;
top: 192px" Width="592px" Font-Names="Arial" Font-Size="Small" ForeColor="MediumBlue"></asp:Label>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [employeeid], [firstname] FROM [Employees]">
</asp:SqlDataSource>
</form>
</body>
</html>
Code behindusing System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Configuration;
using System.Text;
using System.Data.SqlClient;
public partial class UpdateDropDownboxBasedOnAnotherListbox : System.Web.UI.Page, ICallbackEventHandler
{
StringBuilder arg;
protected void Page_Load(object sender, EventArgs e)
{
//Do not process Page_Load if it is a clientscript callback.
if (IsCallback)
return;
if (!Page.IsPostBack)
{
//Generate an HTML script that can instantiate an asynchronous callback on the click of
//the first DropDownListBox, and add it to the "onClick" attribute of the same.
string FirstDropDownCallbackScript = Page.ClientScript.GetCallbackEventReference(this, "document.all['drpEmployeeId'].value", "ReceiveServerData", "null");
drpEmployeeId.Attributes["onClick"] = FirstDropDownCallbackScript;
}
}
// *******************************************************
// Implement the callback interface
public void RaiseCallbackEvent(String eventArgument)
{
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
try
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "Select firstname,employeeid from Employees where employeeid= @EmployeeId";
cmd.Parameters.Add(new SqlParameter("@EmployeeId", SqlDbType.Int, 4));
cmd.Parameters["@EmployeeId"].Value = Int32.Parse(eventArgument);
cmd.Connection = con;
arg = new StringBuilder();
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
arg.Append(reader["firstname"]);
arg.Append("|");
arg.Append(reader["employeeid"]);
arg.Append("||");
}
reader.Close();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
con.Close();
}
}
public string GetCallbackResult()
{
return arg.ToString() ;
}
// *******************************************************
}
How to increment a value in a Label control that is based on a button click in asynchronous callbacks
In the following code sample, a counter is incremented on each button click, and the value of the counter is placed in a
Label control. The count value is maintained in a Session variable that is named Count to track the value across requests.
This sample uses session state to store the counter because there is no support for controlling the
ViewState property in asynchronous callbacks. When you implement page properties or control properties that need to be updated during script callback operations, avoid using the
ViewState property.
ASPX markup<%@ Page Language="C#" AutoEventWireup="true" CodeFile="IncrementingCountInLabelControl.aspx.cs" Inherits="IncrementingCountInLabelControl" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Asynchronous Callback - Label</title>
<script language="javascript">
function ReceiveServerData(arg,context)
{
document.getElementById('lblCounter').innerText = arg;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblCount" runat="server" Style="z-index: 100; left: 48px; position: absolute;
top: 80px" Text="Count :" Width="56px" Font-Names="Arial"></asp:Label>
<asp:Label ID="lblTitle" runat="server" Font-Bold="True" Font-Names="Verdana" Style="z-index: 101;
left: 8px; position: absolute; top: 16px" Text="Incrementing Count on each Button-Click Asynchronously"
Width="552px"></asp:Label>
<input id="btnClickMe" style="z-index: 104; left: 48px; position: absolute; top: 104px"
type="button" onclick="CallServer('', '')" value="Click Me" />
<asp:Label ID="lblText" runat="server" Font-Names="Arial" Font-Size="Small" Font-Underline="True"
Style="z-index: 102; left: 32px; position: absolute; top: 48px" Text="Click Button and Observe count:"
Width="600px"></asp:Label>
<asp:Label ID="lblCounter" runat="server" Font-Names="Arial" Font-Size="Large" Style="z-index: 105;
left: 104px; position: absolute; top: 80px" Text="0" Width="24px"></asp:Label>
</div>
</form>
</body>
</html>
Code behindusing System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
public partial class IncrementingCountInLabelControl : System.Web.UI.Page,ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
//Do not process Page_Load if it is a clientscript callback.
if (IsCallback)
return;
if (!Page.IsPostBack)
{
Session["Count"] = "0";
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "");
String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
}
}
// *******************************************************
// Implement the callback interface
public void RaiseCallbackEvent(String eventArgument)
{
Session["Count"] = int.Parse((Session["Count"].ToString())) + 1;
}
public string GetCallbackResult()
{
return Session["Count"].ToString();
}
// *******************************************************
}
Conclusion
Although asynchronous callbacks are limited in terms of passing the values from the client to the server as a string and requiring you to write some Javascript, it is possible to update Web server controls other than the
GridView control and the
TreeView control asynchronously. A little extra effort can enhance the user experience to a great extent!
Related links
For more information, visit the following Microsoft Web sites:
For more information about DOM HTML, visit the following World Wide Web Consortium (W3C) Web site: