Click here to Skip to main content
Click here to Skip to main content

Using CascadingDropDown with a Database

, 21 Jan 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
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)

Share

About the Author

farzaneh ansari
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 Pinmemberdir.rsrb13-Dec-12 22:28 
QuestionHow do you UPDATE a record in a database using cascading approach whithout 'Not in list' problems? Pinmemberasdrog25-Sep-12 22:13 
AnswerRe: How do you UPDATE a record in a database using cascading approach whithout 'Not in list' problems? Pinmemberfarzaneh ansari22-Oct-12 4:50 
QuestionMy Vote of 5 PinmemberMusthafa (Member 379898)17-Sep-12 15:20 
AnswerRe: My Vote of 5 Pinmemberfarzaneh ansari22-Oct-12 4:51 
GeneralMy vote of 3 Pinmemberbhimsenpardeshi18-May-12 21:54 
QuestionQuestion Pinmembersumeetkumar12324-Apr-12 1:26 
AnswerRe: Question PinmemberNandakishorGaikwad19-Jun-12 20:09 
AnswerRe: Question PinmemberNandakishorGaikwad19-Jun-12 20:11 
QuestionMy vote of 5 PinmemberUday P.Singh19-Nov-11 7:43 
GeneralMy vote of 5 PinmemberSunasara Imdadhusen2-Sep-11 0:58 
GeneralRe: My vote of 5 Pinmemberfarzaneh ansari11-Sep-11 19:53 
GeneralHI farzaneh ansari Pinmembersebastin33321-Dec-10 17:55 
GeneralRe: HI farzaneh ansari Pinmemberfarzaneh ansari23-Dec-10 6:28 
GeneralYou look pretty PinmemberMogamboo_Khush_Hua20-Apr-10 19:29 
GeneralRe: You look pretty PinmemberSunasara Imdadhusen2-Sep-11 0:57 
GeneralRe: You look pretty Pinmemberfarzaneh ansari11-Sep-11 19:55 
Generalthanks Pinmemberabbaspour4-Dec-09 2:28 
GeneralRe: thanks Pinmemberfarzaneh ansary7-Dec-09 0:20 
GeneralRe: thanks Pinmemberfarzaneh ansari29-Jun-12 14:05 
QuestionHow to pass selectedItem.Text to webmethod? Pinmembersundermagar22-Jun-09 22:22 
AnswerRe: How to pass selectedItem.Text to webmethod? Pinmemberfarzaneh ansary24-Jun-09 19:02 
GeneralThanks for the code Pinmemberanydie2-May-09 17:59 
Questionhow would you get text? Pinmemberdsmportal25-Apr-09 15:46 
AnswerRe: how would you get text? Pinmemberfarzaneh ansary25-Apr-09 18:54 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 21 Jan 2009
Article Copyright 2009 by farzaneh ansari
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid