Click here to Skip to main content
15,882,017 members
Articles / Programming Languages / C#

Simple Implementation of MVC Cascading Ajax Drop Down

Rate me:
Please Sign up or sign in to vote.
4.89/5 (17 votes)
21 Sep 2011CPOL3 min read 116.2K   29   22
Here is a simple implementation of MVC cascading Ajax dropdown

Don’t you miss developing the traditional way where you can just use Update Panels and Auto Post backs? It was so easy to develop the UI before where you can see it in the design view and interact with the objects in a rich manner. But that was the past, now we have MVC where we are presented with a different way of developing things in the proper way. If you are starting to use MVC like me, then you might be thinking how do I make cascading dropdowns without the Auto Post back and Update Panels. Read further as this is how I implemented it in the easiest way.

Let's start! Let's say you have the following structure below:

Image 1

You need to have models for each of them.

Image 2

Now you need a controller to perform all of the operations. Let's call it CascadingDropDown.cs, we need 3 Actions Results - one for the Index which will Load the page and populate the Category DropDown, Select Category to populate Sub Category Drop Down and Select Sub Category to populate Products Drop Down. If you notice the name might be confusing that is because it is named after an Action Result not action to perform, which means what Action was invoked for this to happen. Below is a sample code.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    using Models;

    public class CascadingDropDownController : Controller
    {
        public ActionResult Index()
        {
            ProductCatalog productCatalog = new ProductCatalog();
            productCatalog.Categories = ProductCatalog.GetCategories();

            return View(productCatalog);
        }

        [HttpPost]
        public ActionResult SelectCategory(int? selectedCategoryId)
        {
            ProductCatalog productCatalog = new ProductCatalog();
            productCatalog.SubCategories = new List<SubCategory>();

            if (selectedCategoryId.HasValue)
            {
                productCatalog.SubCategories = (from s in ProductCatalog.GetSubCategories()
                                                where s.CategoryId == selectedCategoryId
                                                orderby s.Name
                                                select s).ToList();            }

            return PartialView("SubCategoriesUserControl", productCatalog);
        }

        [HttpPost]
        public ActionResult SelectSubCategory(int? selectedSubCategoryId)
        {
            ProductCatalog productCatalog = new ProductCatalog();
            productCatalog.Products = new List<Product>();

            if (selectedSubCategoryId.HasValue)
            {
                productCatalog.Products = (from s in ProductCatalog.GetProducts()
                                           where s.SubCategoryId == selectedSubCategoryId
                                           orderby s.Name
                                           select s).ToList();
            }

            return PartialView("ProductsUserControl", productCatalog);
        }
    }
}

Take note that we use partial view on the SelectCategory and SelectSubCategory as we will send a partial view to the response. While on the Index. we need the full rendering to the response. Now that you have your controller, we need to create those views. We need 1 view for Index and 3 partial views for the 3 dropdowns.

Now let's create the Index view, all you have to do is to right-click on the Index method on your controller, then you can start coding. This view will display all of the dropdowns.

Image 3

Index.cshtml

HTML
@model MvcApplication1.Models.ProductCatalog
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<table cellpadding="0" cellspacing="4" border="0">
    <tr>
        <td>Category </td>
        <td> :</td>
        <td>@Html.Partial("CategoriesUserControl", Model)</td>
    </tr>
    <tr>
        <td>Sub - Category </td>
        <td> :</td>
        <td><div id="SubCategories">@Html.Partial
        ("SubCategoriesUserControl", Model)</div></td>
    </tr>
    <tr>
        <td>Products </td>
        <td> :</td>
        <td><div id="Products">@Html.Partial
        ("ProductsUserControl", Model)</div></td>
    </tr>
</table>

Now let's create partial views and for those who do not know how, just right-click on the parent folder where your Index view is and Select Add -> View, then tick the “create as a partial view”.

Image 4

Now for the codes.

CategoriesUserControl.cshtml

HTML
@model MvcApplication1.Models.ProductCatalog
@using (Ajax.BeginForm("SelectCategory", "CascadingDropDown", 
new AjaxOptions { UpdateTargetId = "SubCategories" }))
{ 
    @Html.DropDownListFor(
            m => m.SelectedCategoryId,
            new SelectList(Model.Categories, "Id", "Name"),
           string.Empty
        )
}
<script type="text/javascript">
    $('#SelectedCategoryId').change(function () {
        $(this).parents('form').submit();
    });
</script>

SubCategoriesUserControl.cshtml

HTML
@model MvcApplication1.Models.ProductCatalog
@if (Model.SubCategories != null && Model.SubCategories.Count() > 0)
{
    using (Ajax.BeginForm("SelectSubCategory", "CascadingDropDown", 
          new AjaxOptions { UpdateTargetId = "Products" }))
    { 
    @Html.HiddenFor(m => m.SelectedCategoryId)
    @Html.DropDownListFor(
            m => m.SelectedSubCategoryId,
            new SelectList(Model.SubCategories, "Id", "Name"),
            string.Empty
            )
    }
}
<script type="text/javascript">
    $('#SelectedSubCategoryId').change(function () {
        $(this).parents('form').submit();
    });   
</script>

ProductsUserControl.cshtml

HTML
@model MvcApplication1.Models.ProductCatalog
@if (Model.Products != null && Model.Products.Count() > 0)
{
    @Html.DropDownList(
        "Products",
            new SelectList(Model.Products, "Id", "Name"),
            string.Empty
            )
}

If you notice instead of Html.BeginForm, we use Ajax.BeginForm using the parameters below:

Image 5

  • actionName will be the name of your method in your controller
  • controllerName will be the name of your controller
  • AjaxOptions as the name says AjaxOptions, at this point we only need the UpdateTargetId which we defined as in the index.cshtml file.

If you notice there are jQuery scripts below CategoriesUserControl.cshtml and SubCategoriesUserControl.cshtml, they will handle the auto postback on the partially rendered HTML.

Also on your _Layout.cshtml, add this on the header if you haven’t done it yet.

HTML
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

Note: If you are using ASP.NET MVC3, then by default, it uses unobtrusive jquery so you need to remove all MicrosoftAjax scripts and use only those two above, otherwise the onchange event will open a new page instead of partially rendering it.

Note: If you are using Telerik MVC Controls, then you only need the unobtrusive Ajax. The other script is already referenced by default if you are using Telerik.

Make sure also on your web.config you have the following lines:

HTML
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

At this point, you have done everything you need and you are ready to roll.

Image 6

If you need the full source code, you can download it here.

License

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


Written By
Technical Lead
New Zealand New Zealand
http://nz.linkedin.com/in/macaalay
http://macaalay.com/

Comments and Discussions

 
QuestionRequirement :To display some-text in a Display-Box,when user changes values in a Dropdownlist.For this purpose i used PartialView, Ajax.BeginForm and Jquery.change function. Pin
Member 118009206-Jul-15 20:49
Member 118009206-Jul-15 20:49 
Issue : In the main-View* i am using **@html.Beginform() and @Ajax.BeginForm is used in partial view, so while i changes the value in Dropdownlist, Jquery Form submit is calling @html.Beginform() in main-View other than @Ajax.BeginForm

Expected Behavior:Jquery Form submit should call @Ajax.BeginForm in partial View


kindly check this link :Simple Implementation of MVC Cascading Ajax Drop Down is not working[^]
QuestionVery Nice Pin
Joseph T13-Jan-15 9:26
Joseph T13-Jan-15 9:26 
QuestionPlease, Somebody help me. Pin
AboShehab_FCIS10-Nov-14 22:19
AboShehab_FCIS10-Nov-14 22:19 
QuestionConcern Action is not hitting it is going to create action Pin
Member 1064425015-Jul-14 22:21
Member 1064425015-Jul-14 22:21 
Question5 Stars :) Pin
Chams25-Oct-13 22:54
Chams25-Oct-13 22:54 
AnswerRe: 5 Stars :) Pin
Chams27-Oct-13 10:12
Chams27-Oct-13 10:12 
AnswerRe: 5 Stars :) Pin
AboShehab_FCIS10-Nov-14 22:22
AboShehab_FCIS10-Nov-14 22:22 
GeneralMy vote of 5 Pin
Rubol26-Sep-13 3:56
professionalRubol26-Sep-13 3:56 
GeneralRe: My vote of 5 Pin
AboShehab_FCIS10-Nov-14 22:22
AboShehab_FCIS10-Nov-14 22:22 
GeneralMy vote of 5 Pin
Rubol18-Sep-13 18:15
professionalRubol18-Sep-13 18:15 
GeneralMy vote of 1 Pin
mamoorkhan16-Sep-13 1:25
mamoorkhan16-Sep-13 1:25 
QuestionSimple Implementation of MVC Cascading Ajax Drop Down works for 3 but not for 4 dropdowns Pin
Zaveed Abbasi19-Jun-13 3:08
Zaveed Abbasi19-Jun-13 3:08 
AnswerRe: Simple Implementation of MVC Cascading Ajax Drop Down works for 3 but not for 4 dropdowns Pin
AboShehab_FCIS10-Nov-14 22:23
AboShehab_FCIS10-Nov-14 22:23 
QuestionOther Behavior Pin
Patrick Harris15-Oct-12 13:50
Patrick Harris15-Oct-12 13:50 
GeneralMy vote of 5 Pin
Patrick Harris12-Oct-12 8:31
Patrick Harris12-Oct-12 8:31 
GeneralRe: My vote of 5 Pin
AboShehab_FCIS10-Nov-14 22:23
AboShehab_FCIS10-Nov-14 22:23 
BugVery easy excellent approch, Fixed a little error to run. Pin
ankitCsharpAsp6-Oct-12 5:03
ankitCsharpAsp6-Oct-12 5:03 
GeneralRe: Very easy excellent approch, Fixed a little error to run. Pin
AboShehab_FCIS10-Nov-14 22:24
AboShehab_FCIS10-Nov-14 22:24 
GeneralMy vote of 5 Pin
ankitCsharpAsp6-Oct-12 4:52
ankitCsharpAsp6-Oct-12 4:52 
GeneralRe: My vote of 5 Pin
AboShehab_FCIS10-Nov-14 22:24
AboShehab_FCIS10-Nov-14 22:24 
SuggestionNice tutorial, fixed 404 Pin
frenettej8-Sep-12 8:44
professionalfrenettej8-Sep-12 8:44 
GeneralMy vote of 5 Pin
k.ashoksingh28-Jul-12 8:35
k.ashoksingh28-Jul-12 8:35 

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.