Understanding Asp .Net CascadingDropDown AjaxControlToolkit Tutorial


Populating DropDown is a common process in web application. We can set dropdown listitem manually or load from array / database.

Sometimes we deal with more than one dropdown that related to each other. It calls Cascading DropDown.

Many ways to create Cascading DropDown with asp .net which are using autopostback that page refresh everytime dropdown item selected, plain asp .net ajax that only reload partially and using CascadingDropDown Ajaxcontroltoolkit that also use ajax process.

The benefit of using CascadingDropDown Ajaxcontroltoolkit are increasing productivity due to a lot of design work has been done in its functionality and also the web page doesnt have to reload a whole page since its process is using ajax.

CascadingDropDown AjaxControlToolkit Description

Tag example:
<ajaxToolkit:CascadingDropDown ID=”CascadingDropDown1″ runat=”server” TargetControlID=”DropDownList1″
Category=”category” PromptText=”….” LoadingText=”[Loading …]”
ServiceMethod=”GetDropDownContents” />

Description taken from Url: http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/CascadingDropDown/CascadingDropDown.aspx :

  • TargetControlID – The ID of the DropDownList to populate.
  • Category – The name of the category this DropDownList represents.
  • PromptText – Optional text to display before the user has selected a value from the DropDownList.
  • PromptValue – Optional value set when PromptText is displayed.
  • EmptyText – Optional text to display when the DropDownList has no data to display.
  • EmptyValue – Optional value set when EmptyText is displayed.
  • LoadingText – Optional text to display while the data for the DropDownList
    is being loaded.
  • ServicePath – Path to a web service that returns the data used to populate
    the DropDownList. This property should be left null if ServiceMethod refers to a page method.
    The web service should be decorated with the System.Web.Script.Services.ScriptService
    attribute.
  • ServiceMethod – Web service method that returns the data used to populate
    the DropDownList. The signature of this method must match the following:

    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public CascadingDropDownNameValue[] GetDropDownContents(
           string knownCategoryValues, string category) { ... }

    Note that you can replace “GetDropDownContents” with a naming of your choice, but the return
    type and parameter name and type must exactly match, including case.

  • ContextKey – User/page specific context provided to an optional overload of the
    web method described by ServiceMethod/ServicePath. If the context key is used, it should have the
    same signature with an additional parameter named contextKey of type string:

    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public CascadingDropDownNameValue[] GetDropDownContents(
           string knownCategoryValues, string category, string contextKey) { ... }
    

    Note that you can replace “GetDropDownContents” with a name of your choice, but the return type
    and parameter name and type must exactly match, including case.

  • UseContextKey – Whether or not the ContextKey property should be used. This
    will be automatically enabled if the ContextKey property is ever set (on either the client or
    the server). If the context key is used, it should have the same signature with an additional
    parameter named contextKey of type string (as described above).
  • ParentControlID – Optional ID of the parent DropDownList that controls the
    contents of this DropDownList.
  • SelectedValue – Optional value to select by default. This needs to exactly
    match the string representation of a value in the DropDownList.

Notes

Add reference to AjaxControlToolkit and register the control with <%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”ajaxToolkit” %>

CascadingDropDown has some level like parent child relation. Every CascadingDropDown ajaxtoolkit have TargetControlID to specify the related DropDownList. If we have three dropdown then the second and third cascading control has ParentControlID attribute. ParentControlID is an ID of parent DropDown.
Other attribute like ServiceMethod is a code behind or web service function name to populate a dropdown.

Dropdown population function specified in ServiceMethod attribute must have arguments string knownCategoryValues, string category, string contextKey but contextKey argument is optional.

Category argument in that function has value of Category attribute in CascadingDropDown ajaxtoolkit tag. knownCategoryValues argument has value of selected parent and related child dropdown item. This knownCategoryValues has to be parsed with CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues) method in order to extract its value. knownCategoryValues combines parent and child selected value.

Example to show Category and knownCategoryValues Value

I make this example to know and show what exactly Category and knownCategoryValues are.
Basic.aspx:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Basic.aspx.vb" Inherits="Basic" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" EnablePartialRendering="true">
        </ajaxToolkit:ToolkitScriptManager>

        Category Value: <asp:DropDownList ID="ddl1" runat="server"></asp:DropDownList><br /><br />
        knownCategoryValues Value (ddl2 depends on its parent which is ddl1 selectedvalue): <asp:DropDownList ID="ddl2" runat="server"></asp:DropDownList><br /><br />
        CascadingDropDown.ParseKnownCategoryValuesString Value (ddl3 depends on its parent which is ddl2 selectedvalue): <asp:DropDownList ID="ddl3" runat="server"></asp:DropDownList>

        <ajaxToolkit:CascadingDropDown id="cdd1" runat="server" TargetControlID="ddl1" Category="Category 1"
         PromptText="Please select an option" LoadingText="loading options" ServiceMethod="getoptions"></ajaxToolkit:CascadingDropDown>

        <ajaxToolkit:CascadingDropDown id="cdd2" runat="server" TargetControlID="ddl2" Category="Category 2" ParentControlID="ddl1"
         PromptText="Please select an option" LoadingText="loading options" ServiceMethod="getoptions"></ajaxToolkit:CascadingDropDown>

         <ajaxToolkit:CascadingDropDown id="cdd3" runat="server" TargetControlID="ddl3" Category="Category 3" ParentControlID="ddl2"
         PromptText="Please select an option" LoadingText="loading options" ServiceMethod="getoptions"></ajaxToolkit:CascadingDropDown>
    </div>
    </form>
</body>
</html>

Here we have ToolkitScriptManager, three DropDownList and three CascadingDropDown ajaxToolkit. ToolkitScriptManager is a must to enable ajaxtoolkit. ddl1 is a parent of ddl2 and ddl2 is a parent of ddl3.

cdd1 is a cascadingdropdown ajaxtoolkit of ddl1 and so others ajaxtoolkit to ddl2 and ddl3 respectively. All have TargetControlID to connect to related DropDownList. cdd2 and cdd3 have ParentControlID attribute to specify its parent.

We have ServiceMethod="getoptions" attribute value so that we have to make getoptions method to populate the DropDownList value

The Code behind file:

Imports System.Web.Services
Imports AjaxControlToolkit
Partial Class Basic
    Inherits System.Web.UI.Page

    <WebMethod()> _
    <Script.Services.ScriptMethod()> _
    Public Shared Function getoptions(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
        Dim res() As CascadingDropDownNameValue
        ReDim res(0)
        Select Case category
            Case "Category 1"

                res(0) = New CascadingDropDownNameValue(category, "categ1opt")
            Case "Category 2"

                res(0) = New CascadingDropDownNameValue(knownCategoryValues, "categ2opt")
            Case "Category 3"
                Dim sd As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

                res(0) = New CascadingDropDownNameValue(sd.Item("Category 2"), sd.Item("Category 2"))
        End Select

        Return res
    End Function
End Class

Imports System.Web.Services and AjaxControlTollkit due to we need them to set function attributes withWebMethod(), Script.Services.ScriptMethod() and also we useCascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues) to extract knownCategoryValues value.

This getoptions() method have to return CascadingDropDownNameValue class array. The array size must be match with its implementation otherwise error raises.

CascadingDropDownNameValue class is like a key value pair to set DropDown ListItem. It has name and value to set html option element attribute value.

Run above web application to know both returning value.

DropDown of Category, Sub Category and Product Database Example

I use AdventureWorks in SQL Server 2005. One Category has many Sub Categories and one SubCategory has many products. So Category is a parent of Sub Categories and SubCatagory is a parent of products.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ProductCategory.aspx.vb" Inherits="ProductCategory" EnableEventValidation="false" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
   
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"  EnablePartialRendering="true">
        </ajaxToolkit:ToolkitScriptManager>
        Categories: <asp:DropDownList ID="ddlcategory" runat="server"></asp:DropDownList><br /><br />
        Sub Categories: <asp:DropDownList ID="ddlsubcategory" runat="server"></asp:DropDownList><br /><br />
        Products: <asp:DropDownList id="ddlproduct" runat="server" AutoPostBack="true"></asp:DropDownList><br /><br />
        <asp:Label ID="msg" runat="server"></asp:Label>
     
        <ajaxToolkit:CascadingDropDown ID="cdd1" Category="category" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select category" LoadingText="Loading categories.." TargetControlID="ddlcategory"></ajaxToolkit:CascadingDropDown>
        <ajaxToolkit:CascadingDropDown ID="cdd2" Category="subcategory" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select sub category" LoadingText="Loading sub categories.." TargetControlID="ddlsubcategory" ParentControlID="ddlcategory"></ajaxToolkit:CascadingDropDown>
        <ajaxToolkit:CascadingDropDown ID="cdd3" Category="product" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select product" LoadingText="Loading products.." TargetControlID="ddlproduct" ParentControlID="ddlsubcategory"></ajaxToolkit:CascadingDropDown>
    </div>
    </form>
</body>
</html>

Code behind file:

Imports System.Web.Services
Imports System.Data.SqlClient
Imports AjaxControlToolkit
Partial Class ProductCategory
    Inherits System.Web.UI.Page

    <WebMethod()> _
    <System.Web.Script.Services.ScriptMethod()> _
    Public Shared Function GetDDLContent(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
        Dim knownCategoryValuesDictionary As StringDictionary

        Dim conn As New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=true")
        conn.Open()
        Dim comm As New SqlCommand()
        comm.Connection = conn
        Select Case category
            Case "category"
                comm.CommandText = "select ProductCategoryID, Name from Production.ProductCategory"
            Case "subcategory"
                Dim categoryid As String
                knownCategoryValuesDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
                categoryid = knownCategoryValuesDictionary.Item("category")
                comm.CommandText = "select ProductSubcategoryID, Name from Production.ProductSubcategory where ProductCategoryID=" & categoryid
            Case "product"
                Dim subcategoryid As String
                knownCategoryValuesDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
                subcategoryid = knownCategoryValuesDictionary.Item("subcategory")
                comm.CommandText = "select ProductID, Name from Production.Product where ProductSubcategoryID=" & subcategoryid
        End Select
        Dim da As New SqlDataAdapter(comm)
        Dim dt As New Data.DataTable()
        da.Fill(dt)

        Dim arrddl(dt.Rows.Count - 1) As CascadingDropDownNameValue
        Dim i As Integer = 0
        For Each dr As Data.DataRow In dt.Rows
            arrddl(i) = New CascadingDropDownNameValue(dr(1).ToString(), dr(0).ToString())
            i = i + 1
        Next
        da.Dispose()
        comm.Dispose()
        conn.Close()
        Return arrddl
 
    Protected Sub ddlproduct_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlproduct.SelectedIndexChanged
        msg.Text = "You selected category: " & ddlcategory.SelectedItem.Text & ", sub category: " & ddlsubcategory.SelectedItem.Text & " and product: " & ddlproduct.SelectedItem.Text
    End Sub
End Class

This Database Populated DropDownList shows selected AdventureWorks Product Category, Sub Category and Product Name in a label control.

We have AutoPostBack="true" inside ddlproduct DropDownList tag because we want to set label text when selected item changed. Also we need to set EnableEventValidation="false" in Page Directive to prevent EventValidation error.


There is one thing to consider, when ddlproduct selected item is changed the whole web page reloaded. This is not fully ajax.

We have to put <UpdatePanel /> and <ContentTemplate /> Tag covering all DropDownList, label and CascadingDropDown ajaxToolkits to make all process in async mode.

Edit the productcategory.aspx file:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ProductCategory.aspx.vb" Inherits="ProductCategory" EnableEventValidation="false" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
   
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"  EnablePartialRendering="true">
        </ajaxToolkit:ToolkitScriptManager>
		<updatepanel id="updpanel" runat="server">
		<contenttemplate>
        Categories: <asp:DropDownList ID="ddlcategory" runat="server"></asp:DropDownList><br /><br />
        Sub Categories: <asp:DropDownList ID="ddlsubcategory" runat="server"></asp:DropDownList><br /><br />
        Products: <asp:DropDownList id="ddlproduct" runat="server" AutoPostBack="true"></asp:DropDownList><br /><br />
        <asp:Label ID="msg" runat="server"></asp:Label>
     
        <ajaxToolkit:CascadingDropDown ID="cdd1" Category="category" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select category" LoadingText="Loading categories.." TargetControlID="ddlcategory"></ajaxToolkit:CascadingDropDown>
        <ajaxToolkit:CascadingDropDown ID="cdd2" Category="subcategory" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select sub category" LoadingText="Loading sub categories.." TargetControlID="ddlsubcategory" ParentControlID="ddlcategory"></ajaxToolkit:CascadingDropDown>
        <ajaxToolkit:CascadingDropDown ID="cdd3" Category="product" runat="server" ServiceMethod="GetDDLContent"
         PromptText="Please select product" LoadingText="Loading products.." TargetControlID="ddlproduct" ParentControlID="ddlsubcategory"></ajaxToolkit:CascadingDropDown>
		 </contenttemplate>
		 </updatepanel>
    </div>
    </form>
</body>
</html>

Run this app again and the web page reload partially because now all process run with ajax mode.

Regards,
Agung Gugiaji

Advertisements

2 responses to “Understanding Asp .Net CascadingDropDown AjaxControlToolkit Tutorial

  1. It’s a really very informative information. It’s very useful and knowledgeable for me. i was stuck while coding this. I will bookmark this page for coding help.

  2. FINALLY someone who explained how to get PACK to the page after something is selected on the LAST drop down! Simply “AutoPostback=’true'”! Thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s