Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Cascading Dropdown Lists with jQuery (Parent/Child Select Options)

4.00/5 (1 vote)
2 Apr 2011CPOL2 min read 18.1K  
Cascading Dropdown Lists with jQuery (Parent/Child select options)

Recently, I was tasked with merging 3 similar screens into one. I took stock of the commonalities and decided a Category and Subcategory dropdown list would suffice. As you’d expect, the contents of the Subcategory dropdown depend on the selected Category. Obviously, I wanted to avoid postbacks so I first looked to the Ajax Control Toolkit’s CascadingDropDown extender to link the parent to the child. In my case, there were only a dozen subcategories so a webservice seemed like overkill.

After attending Tech-Ed 2008 and seeing Microsoft throwing its weight behind jQuery, I decided to have a look. So what follows is my first foray into jQuery and I’m quite pleased with the results.

First, we define an enum in the codebehind which can be used for bitwise operations.

JavaScript
public enum Category
{
Invoice     = 1,
Order       = 2,
Shipment    = 4   //Fourth item would be 8, then 16, 32, …
}

Next, I wanted to be able to use the enum to specify the Category (only specifying one) and Subcategory items (bitwise OR any combination).

JavaScript
_DropDownCategory.Items.Add(GenerateListItem("Orders", Category.Order, false));
_DropDownCategory.Items.Add(GenerateListItem("Invoices", Category.Invoice, false));
_DropDownCategory.Items.Add(GenerateListItem("Shipments", Category.Shipment, false));
_DropDownSubcategory.Items.Add(GenerateListItem("Purchase Orders", 
    Category.Invoice | Category.Order | Category.Shipment, false));
_DropDownSubcategory.Items.Add(GenerateListItem("Quote Number", Category.Order, false));
_DropDownSubcategory.Items.Add(GenerateListItem("Customer Project Number", 
    Category.Shipment, true));
…

The enum was converted to a number and added as a custom attribute to the new list item in GenerateListItem():

JavaScript
li.Attributes.Add("Category", ((int)eCat).ToString());

Enter jQuery, first we’re going to need to keep a copy of all the available Subcategory items. Each time we change the Category, we will be showing a subset of this array which we must keep separate in memory.

JavaScript
var optSubCat = null;
$(function() {
//Make a copy in memory of all the subcat options
optSubCat = $("#_DropDownSubcategory").children().clone();
//Default subcat to "Orders"
ddSubcategoryUpdate(2);
});

Then, we need an event to fire when the Category is changed.

JavaScript
$(function() {
$("#_DropDownCategory")
.bind("change", function(event) {
var eCat = this[this.selectedIndex].attributes("Category").value;
ddSubcategoryUpdate(eCat);
});
});

Note how jQuery allows us to wire up DOM events after the fact to our .NET controls. Here, we add an onchange event dynamically rather than injecting this via the codebehind which forces us to put JavaScript code in the wrong place. All we’re doing is pulling the value of the enum from the selected Category and then passing it to a function which will update the Subcategory items.

JavaScript
function ddSubcategoryUpdate(eCat) {
//Remove all items from drop down
$("#_DropDownSubcategory").children().remove();
//For each subcat item: test if it belongs in eCat, if so add it
$(optSubCat).each(function() {
if (($(this).attr("Category") & eCat) > 0) {
$("#_DropDownSubcategory").append($(this).clone()[0]);
}
});
}

And finally, in the if statement, we see we test each Subcategory item previously saved in memory to see if it matches the enum value of the Category.

What we’ve ended up with is a very powerful yet simple mechanism for cascading dropdowns using enums in our codebehind. It’s easier to wire up than what the Ajax Control Toolkit provides, it's all script so the UI looks good, and while this could have been done in straight JavaScript, it demonstrates the power and simplicity of the jQuery library.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)