Cascading DropDownLists With ASP.NET and jQuery

Posted by: Malcolm Sheridan , on 11/18/2009, in Category jQuery and ASP.NET
Views: 46476
Abstract: The following article demonstrates how to use ASP.NET and jQuery to create cascading down drop down lists.
Cascading DropDownLists With ASP.NET and jQuery
 
Cascading drop down lists is a really nice feature for web developers. I thought it was time to write an article on how to do this using ASP.NET and jQuery. Well here’s one way of doing it. Before we get started, this example uses the latest version of jQuery which is 1.3.2. That can be downloaded from here
Open Visual Studio 2008 and create a new Web Application. For this article I’m not going to connect to a database. I’ve created two classes, Employee and EmployeeCars, which will store the data. Create two new classes and add the following code:

C#
public class Employee
   {
        public int Id { get; set; }
        public string GivenName { get; set; }
        public string Surname { get; set; }
 
        public List<Employee> FetchEmployees()
        {
            return new List<Employee>
                       {
                           new Employee {Id = 1, GivenName = "Tom", Surname = "Hanks"},
                           new Employee {Id = 2, GivenName = "Tiger", Surname = "Woods"},
                           new Employee {Id = 3, GivenName = "Pat", Surname = "Cash"}
                       };
        }
 
        public Employee FetchEmployee(int id)
        {
            var employees = FetchEmployees();
            return (from p in employees
                    where p.Id == id
                    select p).First();
        }
    }
 
public class EmployeeCar
    {
        public int Id { get; set; }
        public string Car { get; set; }
 
        private static List<EmployeeCar> LoadData()
        {
            return new List<EmployeeCar>
                       {
                           new EmployeeCar {Id = 1, Car = "Ford"},
                           new EmployeeCar {Id = 1, Car = "Holden"},
                           new EmployeeCar {Id = 1, Car = "Honda"},
                           new EmployeeCar {Id = 2, Car = "Toyota"},
                           new EmployeeCar {Id = 2, Car = "General Motors"},
                           new EmployeeCar {Id = 2, Car = "Volvo"},
                           new EmployeeCar {Id = 3, Car = "Ferrari"},
                           new EmployeeCar {Id = 3, Car = "Porsche"},
                           new EmployeeCar {Id = 3, Car = "Ford"}
                       };
        }
 
        public List<EmployeeCar> FetchEmployeeCars(int id)
        {
            return (from p in LoadData()
                    where p.Id == id
                    select p).ToList();
        }
    }
VB.NET
Public Class Employee
            Private privateId As Integer
            Public Property Id() As Integer
                  Get
                        Return privateId
                  End Get
                  Set(ByVal value As Integer)
                        privateId = value
                  End Set
            End Property
            Private privateGivenName As String
            Public Property GivenName() As String
                  Get
                        Return privateGivenName
                  End Get
                  Set(ByVal value As String)
                        privateGivenName = value
                  End Set
            End Property
            Private privateSurname As String
            Public Property Surname() As String
                  Get
                        Return privateSurname
                  End Get
                  Set(ByVal value As String)
                        privateSurname = value
                  End Set
            End Property
 
            Public Function FetchEmployees() As List(Of Employee)
                  Return New List(Of Employee)
                                       Dim Employee As New
                                             "Tom", Surname = "Hanks"
                                             1, GivenName = "Tom", Surname
                                             Id = 1, GivenName
                                     , New Employee
                                             "Tiger", Surname = "Woods"
                                             2, GivenName = "Tiger", Surname
                                             Id = 2, GivenName
                                     , New Employee
                                             "Pat", Surname = "Cash"}
                                             3, GivenName = "Pat", Surname
                                             Id = 3, GivenName
 
            public Employee FetchEmployee(Integer id)
                  Dim employees = FetchEmployees()
                  Return ( _
                      From p In employees _
                      Where p.Id = id _
                      Select p).First()
            End Function
 
Public Class EmployeeCar
            Private privateId As Integer
            Public Property Id() As Integer
                  Get
                        Return privateId
                  End Get
                  Set(ByVal value As Integer)
                        privateId = value
                  End Set
            End Property
            Private privateCar As String
            Public Property Car() As String
                  Get
                        Return privateCar
                  End Get
                  Set(ByVal value As String)
                        privateCar = value
                  End Set
            End Property
 
            Private Shared Function LoadData() As List(Of EmployeeCar)
                  Return New List(Of EmployeeCar)
                                       Dim EmployeeCar As New
                                             1, Car = "Ford"
                                             Id = 1, Car
                                     , New EmployeeCar
                                             1, Car = "Holden"
                                             Id = 1, Car
                                     , New EmployeeCar
                                             1, Car = "Honda"
                                             Id = 1, Car
                                     , New EmployeeCar
                                             2, Car = "Toyota"
                                             Id = 2, Car
                                     , New EmployeeCar
                                             2, Car = "General Motors"
                                             Id = 2, Car
                                     , New EmployeeCar
                                             2, Car = "Volvo"
                                             Id = 2, Car
                                     , New EmployeeCar
                                             3, Car = "Ferrari"
                                             Id = 3, Car
                                     , New EmployeeCar
                                             3, Car = "Porsche"
                                             Id = 3, Car
                                     , New EmployeeCar
                                             3, Car = "Ford"}
                                             Id = 3, Car
 
            public List(Of EmployeeCar) FetchEmployeeCars(Integer id)
                  Return ( _
                      From p In LoadData() _
                      Where p.Id = id _
                      Select p).ToList()
            End Function
That’s all the work to store the data. The next step is to open the Default.aspx code behind. I need to add code to the page load event to fill the drop down list with the employees. I’ll also need a method that can be called through jQuery to update the employee’s cars when the user changes the selected employee. Add the following code to the Default.aspx.cs page:
C#
[WebMethod]
public static List<EmployeeCar> FetchEmployeeCars(int id)
{
var emp = new EmployeeCar();
      return emp.FetchEmployeeCars(id);
}
 
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
      {
            var employees = new Employee();
            ddlEmployee.DataSource = employees.FetchEmployees();
            ddlEmployee.DataTextField = "Surname";
            ddlEmployee.DataValueField = "Id";
            ddlEmployee.DataBind();
}
}
VB.NET
<WebMethod> _
Public Shared Function FetchEmployeeCars(ByVal id As Integer) As List(Of EmployeeCar)
Dim emp = New EmployeeCar()
       Return emp.FetchEmployeeCars(id)
End Function
 
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If (Not IsPostBack) Then
             Dim employees = New Employee()
                  ddlEmployee.DataSource = employees.FetchEmployees()
                  ddlEmployee.DataTextField = "Surname"
                  ddlEmployee.DataValueField = "Id"
                  ddlEmployee.DataBind()
End If
End Sub
The FetchEmployeeCars method has been decorated with the WebMethod attribute and it’s static. This will allow the call from jQuery using the Ajax method. Let’s turn our attention to the HTML now. To begin with add the following JavaScript to the <head> HTML tag:
<script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>      
    <script language="javascript" type="text/javascript">
        $(function() {
            var $ddl = $("select[name$=ddlEmployee]");
            var $ddlCars = $("select[name$=ddlEmployeeCars]");
            $ddl.focus();
            $ddl.bind("change keyup", function() {
                if ($(this).val() != "0") {
                    loadEmployeeCars($("select option:selected").val());                   
                    $ddlCars.fadeIn("slow");
                } else {
                    $ddlCars.fadeOut("slow");
                }
            });
        });
 
        function loadEmployeeCars(selectedItem) {
            $.ajax({
                type: "POST",
                url: "Default.aspx/FetchEmployeeCars",
                data: "{id: " + selectedItem + "}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: true,
                success: function Success(data) {
                    printEmployeeCars(data.d);
                }
            });
        }       
 
        function printEmployeeCars(data) {
            $("select[name$=ddlEmployeeCars] > option").remove();
            for (var i = 0; i < data.length; i++) {
                $("select[name$=ddlEmployeeCars]").append(
                    $("<option></option>").val(data[i].Id).html(data[i].Car)
                );
            }
        }      
    </script>
I’ll break down the code above into smaller chunks. When the page loads, the code looks for the DropDownList named ddlEmployee (I haven’t added that yet):
var $ddl = $("select[name$=ddlEmployee]");
It binds the change & keyup events to a function. These events will be triggered when the user selects a different employee. If they have selected an employee, the loadEmployeeCars function will be called. If they choose the default value, (Please Select), the employee cars drop down list will disappear:
 $ddl.bind("change keyup", function() {
if ($(this).val() != "0") {
loadEmployeeCars($("select option:selected").val());                   
      $ddlCars.fadeIn("slow");
} else {
$ddlCars.fadeOut("slow");
}
});
 
The loadEmployeeCars function accepts the selected employee as an argument. It performs the Ajax call to the FetchEmployeeCars method. 
function loadEmployeeCars(selectedItem) {
$.ajax({
            type: "POST",
            url: "Default.aspx/FetchEmployeeCars",
            data: "{id: " + selectedItem + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            async: true,
            success: function Success(data) {
                  printEmployeeCars(data.d);
}
});
}       
Once the employee’s car details are returned, it passes the data to the printEmployeeCars function. This function clears the items from the ddlEmployeeCars drop down list, and then adds the new items to the list:
function printEmployeeCars(data) {
$("select[name$=ddlEmployeeCars] > option").remove();
      for (var i = 0; i < data.length; i++) {
            $("select[name$=ddlEmployeeCars]").append(
$("<option></option>").val(data[i].Id).html(data[i].Car)
);
}
}      
Lastly here’s the drop down lists:
<asp:DropDownList ID="ddlEmployee" runat="server" AppendDataBoundItems="true">
<asp:ListItem Text="(Please Select)" Value="0" Selected="True" />
</asp:DropDownList>
<asp:DropDownList ID="ddlEmployeeCars" runat="server">
</asp:DropDownList>
If you run the code you’ll see by default there’s only a drop down list containing employees:
PleaseSelect
Once you select an employee, the employee’s list of cars will be displayed:
Hanks

This functionality can be used if you have more than two drop down lists. I hope you enjoyed reading this article. The entire source code of this article can be downloaded over here

Give me a +1 if you think it was a good article. Thanks!
Recommended Articles
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Amit Kar on Sunday, December 27, 2009 12:53 AM
Well written. thanks for sharing
Comment posted by Ramani Sandeep on Monday, January 25, 2010 6:20 AM
Nice Article...
Comment posted by Tim on Monday, January 25, 2010 8:22 AM
Nice, I've been looking to learn how to do this. Very clearcut and easy to follow examples. Thanks!
Comment posted by Vinoth on Tuesday, January 26, 2010 1:05 PM
Thank you, it was very useful for a beginner.
I got an error Employee does not contain a constructor that takes 2 arguments.
Comment posted by Rahul on Friday, February 26, 2010 6:09 AM
Great Article
Comment posted by Kaiser on Tuesday, June 15, 2010 6:40 PM
When I place all the javaScript <script> function in the default.aspx page enclosing <head>..</head>. I get following error on running the default.aspx page:

Server Error in '/' Application.
--------------------------------------------------------------------------------

Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: Only Content controls are allowed directly in a content page that contains Content controls.

Source Error:


Line 1:  
Line 2:  <head>
Line 3:  <script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>      
Line 4:      <script language="javascript" type="text/javascript">
Line 5:          $(function () {


Source File: /Default.aspx    Line: 3

>> Anybody knows solution to this?
--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
Comment posted by Deepak on Wednesday, December 22, 2010 5:51 AM
It's great article. Thanks for sharing brother.

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel