Friday 18 May 2012

Cascading DropDownLists With ASP.NET and jQuery

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

No comments:

Post a Comment