Creating Cascading DropDownList In ASP.NET MVC

I have used Entity Framework to fetch the values and used Database First approach. I would also write an article on an Entity Framework but today, I would just show you how to bind the cascading dropdown list in this blog.

I have two dropdownlists. One is for state and the other for city. I would populate the city, which is based on the state selection. You can add as many dropdownlists, as you want. For simplicity, I am using only two dropdowns.

Create table scripts

tblState 

  1. CREATE TABLE [dbo].[tblState](  
  2.     [stateid] [intNOT NULL,  
  3.     [statename] [nvarchar](50) NULL,  
  4. PRIMARY KEY CLUSTERED   
  5. (  
  6.     [stateid] ASC  
  7. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  8. ON [PRIMARY]  
  9.   
  10. GO   

tblCity 

  1. CREATE TABLE [dbo].[tblCity](  
  2.     [Cityid] [intNOT NULL,  
  3.     [CityName] [nvarchar](50) NULL,  
  4.     [stateid] [intNOT NULL  
  5. ON [PRIMARY]  
  6.   
  7. GO  
  8.   
  9. ALTER TABLE [dbo].[tblCity]  WITH CHECK ADD FOREIGN KEY([stateid])  
  10. REFERENCES [dbo].[tblState] ([stateid])  
  11. GO   

I have tblState and tblCity, where I have stateid as Primary key in the tblState table and stateid as the Foreign key in tblCity table. You can insert states and cities from the database as you wish.

Now, with Entity Framework; create your EDMX file. In my case, I have named it ModelDemo.edmx.

Model

I have created a Model and named it Registration. This is not directly required but since I used a strongly typed View, so I have created Model. You can also add Model because if you write the httppost method to save the values to the database, then you would need the model. 

  1. public class Registration  
  2. {  
  3. [Required(ErrorMessage = "Enter State")]  
  4.         public string State { get; set; }  
  5. [Required(ErrorMessage = "Enter City")]  
  6.         public string City { get; set; }  
  7. }   

Controller

Now, this is my Controller code. 

  1. [HttpGet]  
  2. public ActionResult Details()  
  3.         {  
  4.             bindState();  
  5.             return View();  
  6.         }  
  7. --------------------------------  
  8. public void bindState()  
  9.         {  
  10.             var state = objEF.tblStates.ToList();  
  11.             List<SelectListItem> li = new List<SelectListItem>();  
  12.             li.Add(new SelectListItem { Text = "--Select State--", Value = "0" });  
  13.   
  14.             foreach (var m in state)  
  15.             {  
  16.   
  17.   
  18.                 li.Add(new SelectListItem { Text = m.statename, Value = m.stateid.ToString() });  
  19.                 ViewBag.state = li;  
  20.   
  21.             }  
  22.         }  
  23. ----------------------------------  
  24. public JsonResult getCity(int id)  
  25.         {  
  26.             var ddlCity = objEF.tblCities.Where(x => x.stateid == id).ToList();  
  27.             List<SelectListItem> licities = new List<SelectListItem>();  
  28.   
  29.             licities.Add(new SelectListItem { Text = "--Select State--", Value = "0" });  
  30.             if (ddlCity != null)  
  31.             {  
  32.                 foreach (var x in ddlCity)  
  33.                 {  
  34.                     licities.Add(new SelectListItem { Text = x.CityName, Value = x.Cityid.ToString() });  
  35.                 }  
  36.             }  
  37.             return Json(new SelectList(licities, "Value""Text", JsonRequestBehavior.AllowGet));  
  38.         }   

Now, if you see my Controller code, I have a httpget method Details(). I am then calling a non-action method bindState() to bind the state ddl. On selection of the state ddl, the getCity() method will be called to bind the city ddl. I have used jQuery to get the Id of the selected item and have passed it to the getCity method to get the cites for the selected state.

I have also used LINQ to get my desired select value w.r.t the Id passed.

View

Right click on action method Details(), followed by clicking Add View. I always prefer a strongly typed View and I have also created a strongly typed View in this case. The name of my View is Details.cshtml.

You need jQuery min.js. Just download it from the NuGet Package, if it’s not there. 

  1. <script src="~/Scripts/jquery-1.10.2.min.js"></script>  
  2. <script type="text/javascript">  
  3.   
  4.   
  5.     $(document).ready(function () {  
  6.   
  7.         $("#State").change(function () {  
  8.             $("#City").empty();  
  9.             $.ajax({  
  10.                 type: 'POST',  
  11.                 url: '@Url.Action("getcity")',  
  12.                 dataType: 'json',  
  13.                 data: { id: $("#State").val() },  
  14.                 success: function (city) {  
  15.   
  16.                     $.each(city, function (i, city) {  
  17.                         $("#City").append('<option value="'  
  18.                                                    + city.Value + '">'  
  19.                                              + city.Text + '</option>');  
  20.                     });  
  21.                 },  
  22.                 error: function (ex) {  
  23.                     alert('Failed.' + ex);  
  24.                 }  
  25.             });  
  26.             return false;  
  27.         })  
  28.     });  
  29. </script>   

I have added the jQuery-min.js. From the code given above, we get the Id of the state ddl. 

  1. <div class="form-group">  
  2. @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-2" })  
  3.             <div class="col-md-10">  
  4.                 @Html.DropDownListFor(model => model.State, ViewBag.state as List<SelectListItem>, new { style = "width: 200px;" })  
  5.   
  6.                 @Html.ValidationMessageFor(model => model.State, ""new { @class = "text-danger" })  
  7.             </div>  
  8.         </div>  
  9.   
  10.         <div class="form-group">  
  11.  @Html.LabelFor(model => model.City, htmlAttributes: new { @class =     "control-label col-md-2" })  
  12.             <div class="col-md-10">  
  13.       @Html.DropDownListFor(model => model.City, new SelectList(string.Empty, "Value""Text"), "--Select City--"new { style = "width:200px" })  
  14.   
  15.                 @Html.ValidationMessageFor(model => model.City, ""new { @class = "text-danger" })  
  16.             </div>    

I have used jQuery to get the ID of the state DDL on .change function and passed it to bind the city ddl.

Now, just run your Application and you should get the output given below and if you do not get it, then check that if you are getting any values in an Id in getCity() method. If not, then check for Id mis-match.

output