Click here to Skip to main content
15,879,326 members
Articles / Web Development / ASP.NET

Using CascadingDropDown with a Database

Rate me:
Please Sign up or sign in to vote.
4.74/5 (15 votes)
21 Jan 2009CPOL3 min read 164.4K   7.1K   38   38
How to use CascadingDropDown and AjaxToolKit
default.jpg

Introduction

CascadingDropDownExtender is one of the most popular AjaxControlToolkit extenders

The sample that ships with the Toolkit uses the CascadingDropDown with an XML data store. A common question is how to use it with a database

Background

I recently found myself needing to handle a case where I had three drop down lists, and I needed to setup cascading relationship between those:

Using the CascadingDropDown extender really make this a breeze, except that I had additional requirement, the City drop down should be filtered by both MainLand and Country. So, when a MainLand is selected, all the matching Country types are filled as well as all the matching City for the MainLand. When an Country is selected, the City list should contains only the City for this Country type.

At first I tried to simply setup a new extender from City to MainLand, that worked, until I selected a value from the Country list, after which trying to unselect a value would leave me with a disabled drop down.

Notice:For Use this ToolKit Componenet you should Install The AJAX Control Toolkit

Download the AJAX Control Toolkit from The Official Microsoft ASP.NET Site

Add the AJAX Toolkit controls to the Visual Studio Toolbox

Dotnet15.jpg

In Visual Studio (or Visual Web Developer Express), right-click on the toolbox and select Add Tab

Dotnet13.jpg

Give the Tab a name

Expand the tab that was just created and right-click on the section and select Choose Items.

Dotnet18.jpg

The AJAX Toolkit controls will now appear in your toolbox:

ajaxtoolkit.jpg

Using the Code

In the default.aspx page and add some dropdowns to it:

<dropdownlist id="MainLanddd"  runat="server" width="149px"
    datasourceid="ods_Continent" datatextfield="Name" datavaluefield="Id" />
                    
<asp:DropDownList ID="MainLanddd" runat="server" 

Width="149px" DataSourceID="ods_Continent" DataTextField="Name" 

DataValueField="Id">

</asp:DropDownList>

<
<asp:ObjectDataSource ID="ods_Continent" runat="server" 

OldValuesParameterFormatString="original_{0}" 

SelectMethod="GetContinentByParentId" 

TypeName="dsContinentTableAdapters.ContinentTableAdapter"> 



<SelectParameters>

<asp:Parameter DefaultValue="0" Name="ParentId" Size="4" Type="Int32" />

</SelectParameters> 

</asp:ObjectDataSource>


<asp:DropDownList ID="Countrydd" runat="server" Width="150px">

</asp:DropDownList>
   
<asp:DropDownList ID="Citydd" runat="server" Width="150px">

</asp:DropDownList>

Now, at the top of your ASPX page, register a prefix for the reference to the toolkit:

<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit"
    tagprefix="cc1" %>

<%@ Register assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI" tagprefix="asp" %>

And then add the extender itself:

<cc1:CascadingDropDown ID="CascadingCountry" Category="MainLand" 

runat="server" ServicePath="MainLandService.asmx" 

ServiceMethod="GetCountryId" TargetControlID="Citydd" 

ParentControlID="Countrydd">

</cc1:CascadingDropDown>



<cc1:CascadingDropDown ID="CascadingContinent" Category="MainLand" 

runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetContinentId"
    TargetControlID="Countrydd" ParentControlID="MainLanddd">

</cc1:CascadingDropDown>

At runtime, the extender will make callbacks to a web service we specify (which is decorated with the System.Web.Script.Services.ScriptService attribute). In that web service, it expects a WebMethod with the following signature (note that parameter names must match tool):

[WebMethod] 
     CascadingDropDownNameValue[] GetColorsForModel(
     knownCategoryValues,string category)

The knownCategoryValues parameter will return a string containing the currently selected category values, as well as the category to retrieve values for. For example, if the extender is populating the "MainLand" field, you will be passed the values for the "Country" and "City" fields, as well as "Color" to specify the field to return values for.

The CascadingDropDown class has a helper method for unpacking the category values:

CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

This method will return a StringDictionary containing the name/value pairs of the currently selected values. So imagine you've got a database with tables for the Make (manufacturer), Model, and Color information, and you're accessing that database through a DataSet to which you've added methods for getting each set of values.

The web method to get the available colors for a given model would look like this:

StringDictionary categoryValues = 
    AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(
    knownCategoryValues);

int countryID = Convert.ToInt32(categoryValues["MainLand"]); 

List<CascadingDropDownNameValue> cascadingValues = 
    new List<CascadingDropDownNameValue>();

dsContinentTableAdapters.ContinentTableAdapter _continentAdapter =
    new dsContinentTableAdapters.ContinentTableAdapter();

foreach (DataRow _row in _continentAdapter.GetContinentByParentId(countryID))

{

cascadingValues.Add(new CascadingDropDownNameValue(_row["Name"].ToString(),
    _row["ID"].ToString()));

}

return cascadingValues.ToArray();

So it's simple to return the values. Note that the values are returned as an array of CascadaingDropDownNameValue structures. This structure also includes an isDefaultValue boolean field that allows the specification of which value should be selected when the list is first displayed.

Now let's hook up our extender:

<cc1:CascadingDropDown ID="CascadingCountry" Category="MainLand" 

runat="server" ServicePath="MainLandService.asmx" 

ServiceMethod="GetCountryId" TargetControlID="Citydd" 

ParentControlID="Countrydd">

</cc1:CascadingDropDown>

<cc1:CascadingDropDown ID="CascadingContinent" Category="MainLand" 

runat="server" ServicePath="MainLandService.asmx" ServiceMethod="GetContinentId"
    TargetControlID="Countrydd" ParentControlID="MainLanddd">

</cc1:CascadingDropDown>

Once you've completed your web service methods, your cascading drop down is complete!

Points of Interest

Notice:

in your Web Config you must add This Tags

<configuration>

<configSections>

<sectionGroup name="system.web.extensions"
    type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, 
    PublicKeyToken=31bf3856ad364e35">

<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35">

<section name="scriptResourceHandler"
    type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" requirePermission="false"
    allowDefinition="MachineToApplication"/>

<sectionGroup name="webServices"
    type="System.Web.Configuration.ScriptingWebServicesSectionGroup,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35">

<section name="jsonSerialization"
    type="System.Web.Configuration.ScriptingJsonSerializationSection,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" requirePermission="false"
    allowDefinition="Everywhere"/>

<section name="profileService"
    type="System.Web.Configuration.ScriptingProfileServiceSection,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" requirePermission="false"
    allowDefinition="MachineToApplication"/>

<section name="authenticationService"
    type="System.Web.Configuration.ScriptingAuthenticationServiceSection,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" requirePermission="false"
    allowDefinition="MachineToApplication"/>

</sectionGroup>

</sectionGroup>

</sectionGroup>

</configSections>

<appSettings/>

<connectionStrings>

<add name="ModelCascadingConnectionString"
     connectionString="Data Source=SOFTWAR\BIZ;Initial Catalog=ModelCascading;
     User ID=sa;Password=123" providerName="System.Data.SqlClient"/>

</connectionStrings>

<system.web>

<!-- 

Set compilation debug="true" to insert debugging 

symbols into the compiled page. Because this 

affects performance, set this value to true only 

during development.

-->

<pages>

<controls>

<add tagPrefix="asp" namespace="System.Web.UI"
    assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35"/>

</controls>

</pages>

<compilation debug="true">

<assemblies>

<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35"/>

<add assembly="System.Design, Version=2.0.0.0, Culture=neutral,
    PublicKeyToken=B03F5F7F11D50A3A"/>

<add assembly="System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31BF3856AD364E35"/>

<add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
    PublicKeyToken=B77A5C561934E089"/>

</assemblies>

</compilation>

<!--

The <authentication> section enables configuration 

of the security authentication mode used by 

ASP.NET to identify an incoming user. 

-->

<authentication mode="Windows"/>

<!--

The <customErrors> section enables configuration 

of what to do if/when an unhandled error occurs 

during the execution of a request. Specifically, 

it enables developers to configure html error pages 

to be displayed in place of a error stack trace.

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">

<error statusCode="403" redirect="NoAccess.htm" />

<error statusCode="404" redirect="FileNotFound.htm" />

</customErrors>

-->

<httpHandlers>

<remove verb="*" path="*.asmx"/>

<add verb="*" path="*.asmx" validate="false"
    type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions,
    Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add verb="*" path="*_AppService.axd" validate="false"
    type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions,
    Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add verb="GET,HEAD" path="ScriptResource.axd"
    type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions,
    Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    validate="false"/>

</httpHandlers>

<httpModules>

<add name="ScriptModule" type="System.Web.Handlers.ScriptModule,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35"/>

</httpModules>

</system.web>

<system.web.extensions>

<scripting>

<webServices>

<!-- Uncomment this line to customize maxJsonLength and add a custom converter -->

<!--

<jsonSerialization maxJsonLength="500">

<converters>

<add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>

</converters>

</jsonSerialization>

-->

<!-- Uncomment this line to enable the authentication service. Include requireSSL="true"
     if appropriate. -->

<!--

<authenticationService enabled="true" requireSSL = "true|false"/>

-->

<!-- Uncomment these lines to enable the profile service. To allow profile
     properties to be retrieved

and modified in ASP.NET AJAX applications, you need to add each property name
     to the readAccessProperties and

writeAccessProperties attributes. -->

<!--

<profileService enabled="true"

readAccessProperties="propertyname1,propertyname2"

writeAccessProperties="propertyname1,propertyname2" />

-->

</webServices>

<!--

<scriptResourceHandler enableCompression="true" enableCaching="true" />

-->

</scripting>

</system.web.extensions>

<system.webServer>

<validation validateIntegratedModeConfiguration="false"/>

<modules>

<add name="ScriptModule" preCondition="integratedMode"
    type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
    Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</modules>

<handlers>

<remove name="WebServiceHandlerFactory-Integrated"/>

<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
    preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35"/>

<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd"
     preCondition="integratedMode"
     type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions,
     Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD"
    path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler,
    System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35"/>

</handlers>

</system.webServer>

</configuration>

License

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


Written By
Web Developer PascalSystem,is located in Iran-Isfahan
Iran (Islamic Republic of) Iran (Islamic Republic of)
I was graduated from Esfahan unversity(BS Applied Mathematics)
Master of Computer Science at Saarland University

Comments and Discussions

 
QuestionCasacding dropdwon list - Database remains blank Pin
dir.rsrb13-Dec-12 22:28
dir.rsrb13-Dec-12 22:28 
QuestionHow do you UPDATE a record in a database using cascading approach whithout 'Not in list' problems? Pin
asdrog25-Sep-12 22:13
asdrog25-Sep-12 22:13 
AnswerRe: How do you UPDATE a record in a database using cascading approach whithout 'Not in list' problems? Pin
farzaneh ansari22-Oct-12 4:50
farzaneh ansari22-Oct-12 4:50 
QuestionMy Vote of 5 Pin
Musthafa (Member 379898)17-Sep-12 15:20
Musthafa (Member 379898)17-Sep-12 15:20 
AnswerRe: My Vote of 5 Pin
farzaneh ansari22-Oct-12 4:51
farzaneh ansari22-Oct-12 4:51 
GeneralMy vote of 3 Pin
bhimsenpardeshi18-May-12 21:54
bhimsenpardeshi18-May-12 21:54 
QuestionQuestion Pin
sumeetkumar12324-Apr-12 1:26
sumeetkumar12324-Apr-12 1:26 
AnswerRe: Question Pin
Nandakishor Arun Gaikwad19-Jun-12 20:09
Nandakishor Arun Gaikwad19-Jun-12 20:09 
AnswerRe: Question Pin
Nandakishor Arun Gaikwad19-Jun-12 20:11
Nandakishor Arun Gaikwad19-Jun-12 20:11 
QuestionMy vote of 5 Pin
Uday P.Singh19-Nov-11 7:43
Uday P.Singh19-Nov-11 7:43 
GeneralMy vote of 5 Pin
Sunasara Imdadhusen2-Sep-11 0:58
professionalSunasara Imdadhusen2-Sep-11 0:58 
GeneralRe: My vote of 5 Pin
farzaneh ansari11-Sep-11 19:53
farzaneh ansari11-Sep-11 19:53 
GeneralHI farzaneh ansari Pin
sebastin33321-Dec-10 17:55
sebastin33321-Dec-10 17:55 
Rose | [Rose] Rose | [Rose] Rose | [Rose] Rose | [Rose] Rose | [Rose]
Thanks for this code blog
But i need some more help
GeneralRe: HI farzaneh ansari Pin
farzaneh ansari23-Dec-10 6:28
farzaneh ansari23-Dec-10 6:28 
GeneralYou look pretty Pin
Mogamboo_Khush_Hua20-Apr-10 19:29
Mogamboo_Khush_Hua20-Apr-10 19:29 
GeneralRe: You look pretty Pin
Sunasara Imdadhusen2-Sep-11 0:57
professionalSunasara Imdadhusen2-Sep-11 0:57 
GeneralRe: You look pretty Pin
farzaneh ansari11-Sep-11 19:55
farzaneh ansari11-Sep-11 19:55 
Generalthanks Pin
abbaspour4-Dec-09 2:28
abbaspour4-Dec-09 2:28 
GeneralRe: thanks Pin
farzaneh ansari7-Dec-09 0:20
farzaneh ansari7-Dec-09 0:20 
GeneralRe: thanks Pin
farzaneh ansari29-Jun-12 14:05
farzaneh ansari29-Jun-12 14:05 
QuestionHow to pass selectedItem.Text to webmethod? Pin
sundermagar22-Jun-09 22:22
sundermagar22-Jun-09 22:22 
AnswerRe: How to pass selectedItem.Text to webmethod? Pin
farzaneh ansari24-Jun-09 19:02
farzaneh ansari24-Jun-09 19:02 
GeneralThanks for the code Pin
anydie2-May-09 17:59
anydie2-May-09 17:59 
Questionhow would you get text? Pin
dsmportal25-Apr-09 15:46
dsmportal25-Apr-09 15:46 
AnswerRe: how would you get text? Pin
farzaneh ansari25-Apr-09 18:54
farzaneh ansari25-Apr-09 18:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.