CODEDIGEST
Home » Articles
Search
 

Technologies
 

Sponsored links
 

CodeDigest Navigation
 

Technology News
No News Feeds available at this time.
 

Community News
No News Feeds available at this time.
 
Building Cascading DropDownList in ASP.Net Using jQuery and JSON

By Satheesh Babu
Posted On Mar 27,2009
Article Rating:
Average Rating: 4.5
No of Ratings: 2
No of Comments: 53
Category: jQuery
Print this article.

Building Cascading DropDownList in ASP.Net Using jQuery and JSON

 

Cascading DropDownList is a technique where we populate a child DropDownList based on the parent DropDownList selection. For example, when we select a state in States DropDownList, it will populate the City DropDownList based on the state selected for a personal information input form. In .Net world, we can achieve this by populating the child DropDownList from the SelectedIndex changed event of parent.

Refer the below figure for a sample cascading DropDownList,

 

Well, there are multiple ways to implement this in AJAX world. One way is to keep both the DropDownList in an UpdatePanel and populate the child in SelectedIndex changed event of parent. Another way is to use the CascadingDropDown extender in AJAXControlToolkit. Since these 2 techniques uses ASP.Net AJAX framework, the communication is still bulky.

 

In this article, we will implement the same using the ajax method in jQuery by using JSON. Before moving into the actual article, it is required to know some of the basics.

 

jQuery

jQuery is a light weight JavaScript library that simplifies the client side DOM manipulation, event handling, ajax communication easier and faster.  Read my previous article which will give you a introduction about jQuery and integrating it with our project - Using JQuery in ASP.Net AJAX Applications – Part 1

 

JSON

JSON means JavaScript Object Notation. It is a simple text based, human readable data format that is widely used in AJAX application to transfer data as an alternative to XML format. In simple words, it is simply key- value pairs, separated by commas and enclosed in curly braces. 

 

Moving forward, in this article we will build cascading DropDownList by using the above technologies. We will take the same example we discussed earlier in this article i.e. a state DropDownList and a Cities DropDownList which gets filled when a state is selected.

In particular, we will implement an HttpHandler that can return the collection of cities available in a state in JSON format by accepting state as a query string parameter. This HttpHandler will be called using jQuery getJSON() method when a state is selected in the parent DropDownList and it will populate the child DropDownList using JSON data.

 

Building Cascading DropDownList

1.      You can create a new Asp.Net website project in your Visual Studio 2008 using the language of your choice. I have used C# as the language of my choice.

2.      Drag DropDownList control from the toolbox and change its ID to ddlStates.

3.      For easy understanding and simplicity, I will hardcode the ListItems.  You can bind it from database in your case. This DropDownList will be the parent.

4.      Drag another DropDownList control and rename its ID to ddlCities. This will be child DropDownList control.

<table>

       <tr>

        <td>State</td>

        <td>

            <asp:DropDownList ID="ddlStates" runat="server">

            <asp:ListItem Value="0">Select</asp:ListItem>

            <asp:ListItem Value="1">Tamil Nadu</asp:ListItem>

            <asp:ListItem Value="2">Karnataka</asp:ListItem>

            </asp:DropDownList>

        </td>

        </tr>

        <tr>

        <td>Cities</td>

        <td>

            <asp:DropDownList ID="ddlCities" runat="server">

            </asp:DropDownList>

        </td>

        </tr>

</table>

 

Next, we will construct an HttpHandler which can accept the stateID and give back the list of cities available in that state in JSON format.

 




To do this, Right click the project in solution and click “Add New Item”. Select “Generic Hanlder”. I have named it as LoadCities.ashx. The HttpHanlder will accept StateID as a query string parameter to fetch the cities from database.  Here, I have hard-coded the cities based on the state id for easy understanding. Next, the cities should be returned back in JSON format from the HttpHandler. To know more about JSON and JSON format, please visit the JSON site referenced in JSON section (Move Top) of this article.

 

To understand better, i will give a sample JSON data format that should be returned for a stateid.

 

[{"City":"Chennai","ID":"1"},{"City":"Coimbatore","ID":"2"}]

 

As I said earlier, JSON format is simply key- value pairs, separated by commas and enclosed in curly braces.  Thus, each city is enclosed in curly braces. So, in HttpHanlder we need to construct the data in JSON format and return it back to the caller.

 

Refer the below code,

 

<%@ WebHandler Language="C#" Class="LoadCities" %>

 

using System;

using System.Web;

using System.Text;

 

public class LoadCities : IHttpHandler {

   

    public void ProcessRequest (HttpContext context) {

        string StateID = context.Request.QueryString["StateID"];       

        //Contact Database to get th elist of cities based on StateID

        StringBuilder strCities = new StringBuilder();

        if (StateID == "1")

        {

            strCities.Append("[");

 

            strCities.Append("{");

            strCities.Append("\"City\":\"Chennai\",");

            strCities.Append("\"ID\":\"1\"");

            strCities.Append("},");

 

            strCities.Append("{");

            strCities.Append("\"City\":\"Coimbatore\",");

            strCities.Append("\"ID\":\"2\"");

            strCities.Append("}");

 

            strCities.Append("]");

        }

        else if (StateID == "2")

        {

            strCities.Append("[");

 

            strCities.Append("{");

            strCities.Append("\"City\":\"Bangalore\",");

            strCities.Append("\"ID\":\"1\"");

            strCities.Append("},");

 

            strCities.Append("{");

            strCities.Append("\"City\":\"Belgaum\",");

            strCities.Append("\"ID\":\"2\"");

            strCities.Append("}");

 

            strCities.Append("]");

        }

        context.Response.ContentType = "application/json";

        context.Response.ContentEncoding = Encoding.UTF8;

        context.Response.Write(strCities.ToString());

        context.Response.End();

    }

    public bool IsReusable {

        get {

            return false;

        }

    }

}

 

I have hard coded only for 2 states, you can loop through the result set from database and give back the data in JSON format.

 

Calling HttpHanlder from jQuery

 

There are some handful of Ajax methods available in jQuery for AJAX communications. Here, I am going to use getJSON method to get the result back from HttpHanlder and bind the DropDownList control.

Read my previous article Using JQuery in ASP.Net AJAX Applications – Part 1.

 This will show you how to integrate jQuery and use Visual Studio intellisense with our project.

 

We will declare an onchange event for the parent DropDownList which will make the AJAX call to the server to fetch the JSON data. Refer the below code,

 

<script src="_scripts/jquery-1.2.6.js" type="text/javascript"></script>

    <script language="javascript">

        $(document).ready(function() {

            $("#ddlStates").change(function() {

                $("#ddlCities").html("");

                var StateID = $("#ddlStates > option[@selected]").attr("value");

                if (StateID != 0) {                 

      

  $.getJSON('LoadCities.ashx?StateID=' + StateID, function(cities) {

                        $.each(cities, function() {                        

 

                            $("#ddlCities").append($("<option></option>").val(this['ID']).html(this['City']));

 

                        });

                    });

                }

            });

 

        });

    </script>

 

Update

If you are using jQuery library 1.3.2, @ character in selector expression have to be removed since the use of @ with the attribute is deprecated. So, change the stateid selection like,

var StateID = $("#ddlStates > option[selected]").attr("value");

The getJSON method will be called for every state selection except for the value of “select” in parent DropDownList. When the JSON result is returned it will call the call-back function(2nd argument of getJSON method) which will populate the child DropDownList control.

 

Execute the page and you can see Cascading DropDownList in action.

 

So far so good, now when we try to save the data again or if there is any postback to the server after the above step, we will get an exception with a message,

 

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

 

What is the reason for the above exception?

ASP.Net performs a validation on every postback called EventValidation which records the values, controls at every render and it will check the data and control that is generating the event or postback is in the list recorded in the last render. For example, if a dropdown with values 1, 2, 3 is rendered to the client, for the next postback event if someone tries to add a fourth option say “4” in the client (using JavaScript) and post it to the server the validation fails and the runtime will throw an exception. ASP.Net will predict it as an attack by default since the content are different and will throw an exception. Since, the child DropDownList is loaded in client side without a normal postback it is considered as an attack and the validation will fail. The result is the above exception.

 

Resolutions

There are several ways to prevent the above exception. You can see some of the resolution which can be done to prevent the above exception below.

 

1.      To resolve the above issue, we can disable the enableEventValidation either in web.config or in page level.

<pages enableEventValidation="false"/> in Web.Config or,

<%@ Page EnableEventValidation="false" %> in a page attribute.

2.      The risk in above approach is, we are by-passing the security validation which may result in intruder attacking our system. Alternate way to resolve the above issue will be using RegisterForEventValidation() Methods in ClientScriptManager class. Read my article, Using JavaScript Effectively in ASP.Net 2.0 – PART 2 to know more about it. Refer the RegisterForEventValidation() Methods section in the article.

3.      An Alternate and easiest way will be replacing the child DropDownList as a HTML select control by setting runat attribute to server. This is the very easiest way to prevent the above exception.  So, the child DropDownList can be re-written as,

<select ID="ddlCities" runat="server">

</select>

 

Download the source code packed with this article in Download section to see Cascading DropDownList in action.

To Access the selected value from server side

Response.Write(Request["ddlCities"]);

Downloads

Download Source 


Conclusion

Thus, we have understood an alternate way to build a cascading DropDownList control which is light weight when compared to ASP.Net AJAX communication. Download the code and see it in action.

Happy Coding!!

Similar Articles
You can contribute to CodeDiget.Com:
Donate to CodeDigest.com
Article Feedback
Comments
disable/enable cities
how to add here feature to enable cities list only after it is filled? I tried $("[id$='_ddlCities']") .disabled = false;
but it did not work
Contentpage (solved)
with master/contentpages issue solved :) must reference items like
$("[id$='_ddlStates']")
$("[id$='_ddlCities']")
this woks :)

question remains still about postback. how to keep cities list after postback?
Contentpage
great sample. thank you. everything works fine for me on normal page. But when I have a Master and Content page I can't get to work. I have DropDownList and Select on contentpage. How to get this Javascript working on contentpage?
JSON
Everything is fine. I have used same code as u mentioned above, but i am getting error at the line
" $("#ddlCity").append($("<option></option>").val(this['ID']).html(this['Name'])); "


and the error is
"Microsoft JScript runtime error: Object doesn't support this property or method".

can u please tell me.

but dropdownlist was loaded.
Here i am using VS2010
JSON
Everything is fine. I have used same code as u mentioned above, but i am getting error at the line
" $("#ddlCity").append($("<option></option>").val(this['ID']).html(this['Name'])); "


and the error is
"Microsoft JScript runtime error: Object doesn't support this property or method".

can u please tell me.

but dropdownlist was loaded.
Here i am using VS2010
How to retain items in city dropdown
...as we have populated the city dropdown using clientsite script items are not available after postback. What is the best way to keep city dropdown populated after postback as my page might have some other operation to do (which require postback) before finally saving data to backend?
When we select the Item from the Dropdownlist i am facing 'length' is null or not an object Error. We are using jquery-1.4.js
We have to use only JQuery1.4 or higher version.Because our application in production is running with Jquery1.4 . we should not use lower version.
'length' is null or not an object
Sample Code:
$("#ddlSubjectID > option:selected").attr("value");
When we select the Item from the Dropdownlist i am facing 'length' is null or not an object Error. We are using jquery-1.4.js
We have to use only JQuery1.4 or higher version.Because our application in production is running with Jquery1.4 . we should not use lower version.
'length' is null or not an object
Sample Code:
$("#ddlSubjectID > option:selected").attr("value");
DropDownList Items Do not Persist
Very well done, but as I believe that dropdownlist items added in Javascript are not part of viewstate and therefore 'disappear' after a postback. The only solution I can think of is to repopulate the child dropdownlist after the postback - Is there a work around?
Your effort is really commendable
You have done a wonderful job and break it down to the finest way possible.
Keep it up
I found the answer
If using a master page asp.net will generate a new client id such as ctl00_MainContent_ddlStates. I replaced statements like $("#ddlStates") with $("[id$='_ddlStates']") to search for the control. I also used var StateID = $("[id$='_ddlStates']").val(); to find the StateID.
JQuery not recognizing asp controls
Great example but I'm having a problem. JQuery does not recognize asp controls. When I change the dropdownlist to html select it works. I'm not sure what I'm doing wrong. Any ideas would be appreciated. Thanks.
work in jquery1.4.x
when you use jQuery 1.4.x , the code row
var StateID = $("#ddlStates > option[@selected]").attr("value");

must be changed like this.

var StateID = $("#ddlStates > option:selected").attr("value");
correcion
in the new version of jquery you need to use option:selected instead of option[selected].
thank you for the great tutorial
Good tutorial
Hello Satheesh Babu

I am Cristian from Argentina. Thanks for this tutorial, is very good. However, most important it is very clear and easy to understend.

I like very much if you can publish some article using jquery asp.net with gidview, because is very common in asp.net using gridview, but I can not find some articule that show how paging, editing, etc gridview using jquery.

Thanks Satheesh Babu!!!
Cristian
RE:Does not work
Please note the changes for jQuery version 1.3.2.
Try downloading the code attached in this article and let me know!
Does not work
Looked at this for about 2 hours, code compiles, but does not work, second drop down does not populate after picking something in first drop down
Error
I am getting this error when debuging this code

Microsoft JScript runtime error: Object expected

Can you please help me on this
Selected Item
haha never mind.. fixed...

$("#PricePointID").append($("<option></option>").val(this['ID']).html(this['Code']).attr("selected","selected"));

my attr was outside the append call...
Selected Item
Hello,
Great article it really helped me get what I was looking to accomplish.. I'm running in to one issue right now where i need to pre-select the second drop down that is being populated by the JSON call... Here is where I'm stuck..

// Get the Price Points for this Program Code
$.getJSON('../Administration/Load_PricePoints.ashx?ProgramCodeID=' + ProgramCodeID, function(PricePoint) {

$.each(PricePoint, function() {
if (SelectValue == this['ID']) {
$("#PricePointID").append($("<option></option>").val(this['ID']).html(this['Code'])).attr("selected","selected");
} else {
$("#PricePointID").append($("<option></option>").val(this['ID']).html(this['Code']));
}

});
});

What I need to do is set the selected attr to selected when the ID's match... I've gotten it to hit the true portion of the if statement i'm kinda lost on how to get the attr to work correctly...
RE: pre-populate drop downs?
one obvious solution I overlooked is just binding them on the server while loading the page. As long as my handler takes advantage of the same code to get the data, I won't have to duplicate.
Jeremy
pre-populate drop downs?
does anyone have any code written to pre-populate the drop downs when the values are already known? THanks, Jeremy.
Nice Article
Nice article,
Runs at the first shot.
For those who cannot access the value of selected city in codebehind, we can write a javascript function on the onchange event of ddlCities like onchange="selctedCity();"
to populate a textbox . for ex
function selctedCity()
{
document.getElementById("TextBox1").value = document.getElementById("ddlCities").value;
}

With this the selected city value can be caught from the testbox after postback.

Thanks.

Using MasterPages
When using master pages in order to access the value on poastback you need to do this...

c# = Request[this.ddlCities.Name]
or
vb.net = Request(me.ddlCities.Name)

Good Article
Good explanation
Good explanation, it is very helpful for the beginners who are trying to use jquery and json.
Great article
Hi!
This is the best article on subject I was able to find and got it working!
One correction I made, though:
var StateID = $("#ddlStates > option[selected]").attr("value"); - did not work for me.
I just changed it to
var StateID = $("#ddlStates").attr("value");

Thanks!
Great Saviour !
Hi Sathish

Wonderful article !. you saved us man.

Everything went OK. One thing is troubling though. How to get the Text of the selected item? i'm getting the ID part with your guidance Request("ddlCities"), but not the text. I need to get both ID and Text. Please help.
good
good
Fetch values in code behind
Hi,

Nice article, but i would like to fetch all the values of the drop down list in the code behind. How can I do this??? One more thing after successful populating the drop down list I checked the view source of the page but the select tags remains empty why so?? where does it stores all the values then...
RE:Doesen't work
Hi Arif,
If you use MasterPages, you can't select server control directly using the ID in the client side as asp.net appends container ID to the control's ID. So, make the selection by,
$("#<%=ddlStates.ClientID %>").change(function()
{
...

Make sure, you make the selection by same way in other places as well
Doesen't work
This dosen't work.. whenIam using masterpages..
how can i fix this?
RE:Radiobuttonlist
@vijay sharma,

Please read the article,
http://www.codedigest.com/Articles/jQuery/259_Populating_RadioButtonList_Using_jQuery_JSON_in_ASPNet.aspx
RE:Not working with JQuery 1.3.2
As Ron pointed out, from jquery 1.3.2 the use of @ with the attribute is removed. In order to work with 1.3.2 version please select stateid like,
var StateID = $("#ddlStates > option[selected]").attr("value");

Thanks!
RE:SelectedValue
@MH,@Nushahi,
You can get the selected value by,
Response.Write(Request["ddlCities"]);

And if you require the listitems to be available after the postback you need to rebind the dropdownlist in the postback and set the selected value again.
SelectedValue
There seems to be a problem after the postback getting the SelectedValue of the ASP.NET dropdown if it is populated from Json?
Not working with JQuery 1.3.2
This script code is not updated. it;s not working with jQuery 1.3.2 .
very helpful article
very nice article.. thats the alternate way of doing.. great
Get Selected Value
How can i get the selected value of Cities after postback clears ddlCities
RE:Why not using library to serialize object to JSON?
Hi Gary,

Thanks for your comment!
I meant the DataContractJsonSerializer class in .net 3.5,
Read more here,
http://www.west-wind.com/WebLog/posts/218001.aspx
Very helpful article
Thanks a lot. I have found this article very useful for me, a beginner to jquery and json.
RE:Why not using library to serialize object to JSON?
To Satheesh----

It's pretty straight forward approach that you can even implement with .net 1.1 There's no need for .net 3.5
RE:Why not using library to serialize object to JSON?
Ofcourse, You can do that. But, it requires .Net 3.5 installed on the server.
You can also do this with the JavaScriptSerializer class packed in System.Web.Script.Serialization namespace(Again, with ASP.Net ajax required on the server).
I prefered this approach to not have extra dependency on any thing..
@sshah,
Lookout in the codedigest section, i will post one soon!

Thanks for your comment guys!
Why not using library to serialize object to JSON?
Why not using library to serialize object to JSON?

The DataContractJsonSerializer
Radiobuttonlist
Hi - i was trying to populate radiobuttonlist dynamically using jquery and httphandlers. can you help me figure out how i can accomplish similarly as we are doing with dropdownlist

Thanks
JSON
Great and Nice Explanation....Keep it Up..
RE:dropdownlist
Hi vijay
i assume you are stuck with dynamically loading ddl from DB.
Refer this article,
http://www.codedigest.com/CodeDigest/7-Binding-DropDownList-from-CodeBehind-and-ASPX-by-Fetching-Data-From-Database.aspx
dropdownlist
but i want that my DDL wraped its data from database at runtime,& top most entry for specific value that i want to disable in asp.net with c# in .net 2005
RE:did not work
Hi Andrew,

Did you tried downloading the project from Download section?
did not work
The cities does not fire.
I get a Microsoft JScript runtime error: Object expected error.

How do I debug this?
RE:2 corrections
Thanks for the feedback Ron!

Since, i have not used masterpage i prevented "dd_city.ClientID". yeah, its good practise if we do like this.But the dd_city.ClientID will not work if we have jquery code in a seperate file.

Regarding using '@', thanks for sharing this info..
2 corrections
First, thanx for the article, it is very useful.

first: what about using ClientID ? as it is, it will never work. Or am i missing something? everywhere in your jquery code you should say <%=dd_city.ClientID%> instead of dd_city.

Second: they have changed the rules (again).
in Jquery 1.3, instead of option[@selected], you should go option[selected] . yes, the @ was ditched, for some reason.

Other then that - good stuff.

Ron

RE:is callback
Hi smays,
I guess your query is about the serverside implementation to fetch data from DB. I have not used webmethod here which is also a option to achieve the above. I have used a generic HttpHandler which fetches the data from DB and forms a JSON. This JSON is captured in the client and added to the child dropdown using jQuery. Refer the code in the article.
is callback
Is the method used is a principle callback or webmethod and how to deal with the get data from the database??