Creating Dependent DropDownLists...
Forcing the contents of one DropDownList to change based upon the selection of a value from another DropDownList was often a little messy in clasic ASP. In .NET it is far easier.
Forcing the contents of DropDownList2 to change based upon the selection made from DropDownList1 is a fairly common requirement of dynamic web pages. .NET makes this fairly simple to handle by using the OnSelectedIndexChanged event and setting AutoPostBack to True. To do this dynamically, retrieving the contents of DropDownList2 from a database table, you need a key - foreign key relationship as the value of each DropDownList.
In this example program we will use the Authors, TitleAuthor, and Titles tables of the Pubs database. In the Page_Load event we will fill the first DropDownList with Author names as text, and author ID as the value. Upon selection of an Author from the Authors DropDownList, we will, using the OnSeledtedIndexChanged event, use the selected au_id value in the WHERE clause of SQL statement to populate the second DropDownList with Title ID's. We will then use the OnSelectedIndexChanged event of the title id's DropDownList to fill a TextBox with the Title of the book from the Titles table.
The DependentDropDowns.aspx page is shown below. Notice that setting up the OnSelectedIndexChanged events in both dropdowns, and that AutoPostBack is set to true for each.
|
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="DependentDropDowns.aspx.vb" Inherits="DotNetJohn.DependentDropDowns"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <title>DependentDropDowns</title> <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1"> <meta name=vs_defaultClientScript content="JavaScript"> <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <table border="0" cellspacing="2" cellpadding="2"> <tr> <td>Authors</td> <td>Title_ID</td> <td>Title</td> </tr> <tr> <td><asp:DropDownList ID="ddlAuthors" runat="server" AutoPostBack="True" OnSelectedIndexChanged="FillTitleAuthor" /></td> <td><asp:DropDownList ID="ddlTitleAuthor" Runat="server" AutoPostBack="True" OnSelectedIndexChanged="FillTitles" /></td> <td><asp:TextBox ID="txtTitles" Runat="server" Columns="50" ReadOnly="True" /></td> </tr> </table> </form> </body> </HTML> |
Following is the codebehind file presented in two parts. This first part includes the Page_Load event where we are first filling the Authors dropdown with the last and first names of the authors.
|
Imports System.Data Imports System.Data.SqlClient Imports System.Configuration Public Class DependentDropDowns Inherits System.Web.UI.Page ' - Web Form Designer Generated Code Omitted - Private strConnection As String = ConfigurationSettings.AppSettings("PubsConnection") Private strSql As String Private objConn As SqlConnection Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not IsPostBack Then 'Fill Authors DropDown strSql = "SELECT au_id, au_lname + ', ' + au_fname [FullName] FROM Authors ORDER BY au_lname" objConn = New SqlConnection(strConnection) Dim objCmd As New SqlCommand(strSql, objConn) Dim _reader As SqlDataReader Try objConn.Open() _reader = objCmd.ExecuteReader With ddlAuthors .DataSource = _reader .DataValueField = "au_id" .DataTextField = "FullName" .DataBind End With ddlAuthors.Items.Insert(0, "-Select-") Catch ex As SqlException Response.Write(ex.ToString) Finally _reader.Close() objConn.Dispose() End Try End If End Sub |
The remainder of the codebehind file is presented below. It first contains the FillTitleAuthor() subroutine called by the OnSelectedIndexChange event of the authors dropdown. Notice the WHERE clause in the SQL statement. There we are populating au_id with the author id associated with the selected Author from the first dropdown. The resulting SQL statement is used to populate the second DropDownList. (Many of the Authors have only one title_id but the principal is the same no matter how many there are.)
A similar process is then used to get the title for the TextBox using the title_id selected from the second DropDownList.
|
Protected Sub FillTitleAuthor(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddlAuthors.SelectedIndexChanged 'Clear Titles Textbox txtTitles.Text = "" 'Fill TitleAuthor DropDown strSql = "SELECT au_id, title_id FROM TitleAuthor " & _ "WHERE au_id='" & ddlAuthors.SelectedValue() & "'" & _ " ORDER BY title_id" objConn = New SqlConnection(strConnection) Dim objCmd As New SqlCommand(strSql, objConn) Dim _reader As SqlDataReader Try objConn.Open() _reader = objCmd.ExecuteReader With ddlTitleAuthor .DataSource = _reader .DataValueField = "title_id" .DataTextField = "title_id" .DataBind End With ddlTitleAuthor.Items.Insert(0, "-Select-") Catch ex As SqlException Response.Write(ex.ToString) Finally _reader.Close() objConn.Dispose() End Try End Sub Protected Sub FillTitles(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddlTitleAuthor.SelectedIndexChanged 'Clear Titles Textbox txtTitles.Text = "" 'Fill Titles TextBox strSql = "SELECT title FROM Titles " & _ "WHERE title_id='" & ddlTitleAuthor.SelectedValue() & "'" objConn = New SqlConnection(strConnection) Dim objCmd As New SqlCommand(strSql, objConn) Dim _reader As SqlDataReader Try objConn.Open() _reader = objCmd.ExecuteReader(CommandBehavior.SingleRow) If _reader.Read Then txtTitles.Text = _reader("title") End If Catch ex As SqlException Response.Write(ex.ToString) Finally _reader.Close() objConn.Dispose() End Try End Sub End Class |
You may run the example program here.
You may download the code here.