Dynamically Bind The DropDownList On Change Event In ASP.NET MVC 5

I am going to create two tables. Suppose there is a client having more than one site, so we will create one table for the client information and another table with Foreign Key relationship to store the multiple site information because one client can contribute or write articles on the multiple portals.
 
Step 1 - Create tables, using the scripts, given below- 
  1. CREATE TABLE [dbo].[ClientDetails](  
  2.     [Id] [int] IDENTITY(1,1) NOT NULL,  
  3.     [Name] [varchar](150) NULL,  
  4.     [Website] [varchar](50) NULL,  
  5.     [Phone] [nvarchar](50) NULL,  
  6.     [Mobile] [nvarchar](50) NULL,  
  7.     [Address] [varchar](200) NULL  
  8.  CONSTRAINT [PK_ClientDetails] PRIMARY KEY CLUSTERED   
  9. (  
  10.     [Id] ASC  
  11. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]  
  12. ON [PRIMARY]  
  13.   
  14.   
  15. CREATE TABLE [dbo].[ClientSiteDetails](  
  16.     [Id] [int] IDENTITY(1,1) NOT NULL,  
  17.     [ClientId] [intNOT NULL,  
  18.     [SiteName] [nvarchar](200) NULL,  
  19.     [SiteAddress] [nvarchar](500) NULL  
  20.  CONSTRAINT [PK_ClientSiteDetails] PRIMARY KEY CLUSTERED   
  21. (  
  22.     [Id] ASC  
  23. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]  
  24. ON [PRIMARY]  
  25.   
  26. GO  
  27.   
  28. ALTER TABLE [dbo].[ClientSiteDetails]  WITH CHECK ADD  CONSTRAINT [FK_ClientSiteDetails_ClientDetails] FOREIGN KEY([ClientId])  
  29. REFERENCES [dbo].[ClientDetails] ([Id])  
  30. GO  
  31.   
  32. ALTER TABLE [dbo].[ClientSiteDetails] CHECK CONSTRAINT [FK_ClientSiteDetails_ClientDetails]  
  33. GO 
Step 2 - Create new MVC Empty project, using VS 2013. Here, we are going to use ViewModel and will declare the properties in IndexViewModel, given below-  
  1. public class IndexViewModel  
  2.     {  
  3.         public IndexViewModel() { }  
  4.         public List<Infrastructure.ClientDetail> clientDetail { getset; }  
  5.         public List<Infrastructure.ClientSiteDetail> clientSiteDetail { getset; }  
  6.   
  7.         public IndexViewModel(Infrastructure.ClientDetail client)  
  8.         {  
  9.             Id = client.Id;  
  10.             Name = client.Name;  
  11.             Website = client.Website;  
  12.             Phone = client.Phone;  
  13.             Mobile = client.Mobile;  
  14.             Address = client.Address;  
  15.         }  
  16.   
  17.         public IndexViewModel(ClientSiteDetail site)  
  18.         {  
  19.             SiteId = site.Id;  
  20.             SiteName = site.SiteName;  
  21.             CurrentClientName = site.ClientDetail.Name;  
  22.             SiteAddress = site.SiteAddress;  
  23.         }  
  24.   
  25.   
  26.         /// <summary>  
  27.         /// Added to create properties of client details  
  28.         /// </summary>  
  29.         public int Id { getset; }  
  30.         [Required(ErrorMessage = "Enter Name")]  
  31.         public string Name { getset; }  
  32.         [Required(ErrorMessage = "Enter Website")]  
  33.         public string Website { getset; }  
  34.         [DataType(DataType.PhoneNumber)]  
  35.         public string Phone { getset; }  
  36.         public string Mobile { getset; }  
  37.         public string Address { getset; }  
  38.        
  39.         /// <summary>  
  40.         /// Added to create properties of client Site details  
  41.         /// </summary>  
  42.         public int SiteId { getset; }  
  43.         public int ClientFKId { getset; }  
  44.         [Required(ErrorMessage = "Enter Name")]  
  45.         public string SiteName { getset; }  
  46.         [Required(ErrorMessage = "Enter Address")]  
  47.         public string SiteAddress { getset; }  
  48.          
  49.         /// <summary>  
  50.         /// Added for create drop down list of client names  
  51.         /// </summary>  
  52.         public int ClientId { getset; }  
  53.         public int ClientName { getset; }  
  54.         [Required(ErrorMessage = "Please Select Client Name")]  
  55.         public string CurrentClientName { getset; }  
  56.     } 
Step 3 - Now, add one controller to controller folder. Add the code, given below, to insert client details and site details into the database. Here, I am going to Generic repository unit of work pattern. Refer my old article for more information, use the link, given below-
  1. public class ClientDetailsController : Controller  
  2.     {  
  3.         protected UnitOfWork UnitoffWork { getprivate set; }  
  4.         public ClientDetailsController()  
  5.         {  
  6.           UnitoffWork = new UnitOfWork();  
  7.         }  
  8.         public ActionResult Index()  
  9.         {  
  10.             var client = UnitoffWork.ClientDetailsRepository.GetAll().Select(c =>   
  11.   
  12. new IndexViewModel(c));  
  13.             return View(client);  
  14.         }  
  15.         public ActionResult Add()  
  16.         {  
  17.             IndexViewModel obj = new IndexViewModel();  
  18.             return PartialView("_Add", obj);  
  19.         }  
  20.   
  21.         [HttpPost]  
  22.         public ActionResult Create(IndexViewModel client)  
  23.         {  
  24.             ClientDetail objClient = new ClientDetail();  
  25.             if (client.Name != null)  
  26.             {  
  27.                 var count = UnitoffWork.ClientDetailsRepository.GetAll().Where(a =>   
  28.   
  29. a.Name == client.Name).Count();  
  30.                 if (count == 0)  
  31.                 {  
  32.                     objClient.Name = client.Name.ToString();  
  33.                     objClient.Website = client.Website.ToString();  
  34.                     objClient.Phone = client.Phone.ToString();  
  35.                     objClient.Mobile = client.Mobile.ToString();  
  36.                     objClient.Address = client.Address.ToString();  
  37.                     UnitoffWork.ClientDetailsRepository.Insert(objClient);  
  38.                     UnitoffWork.ClientDetailsRepository.Save();  
  39.                 }  
  40.             }  
  41.             return RedirectToAction("Index");  
  42.         }  
  43.   
  44.         [HttpGet]  
  45.         public ActionResult List()  
  46.         {  
  47.             var client = UnitoffWork.ClientDetailsRepository.GetAll().Select(c =>   
  48.   
  49. new IndexViewModel(c));  
  50.             return PartialView("_List", client);  
  51.         }  
  52.   
  53.   
  54.         public ActionResult ClientSite()  
  55.         {  
  56.             var clientSites = UnitoffWork.ClientSiteDetailsRepository.GetAll  
  57.   
  58. (navigationPropeties: np => np.ClientDetail).Select(x => new IndexViewModel(x));  
  59.             return View("ClientSiteDetails", clientSites);  
  60.         }  
  61.   
  62.         public ActionResult AddClientSite()  
  63.         {  
  64.             IndexViewModel obj = new IndexViewModel();  
  65.             IEnumerable<ClientDetail> listClients =   
  66.   
  67. UnitoffWork.ClientDetailsRepository.GetAll();  
  68.             var listToClient = listClients.Select(p => new { p.Name, p.Id   
  69.   
  70. }).ToList();  
  71.             var items = listToClient.Select(i => new SelectListItem { Text =   
  72.   
  73. i.Name, Value = i.Id.ToString() });  
  74.             ViewBag.ClientListNames = items;  
  75.   
  76.             return PartialView("_AddClientSite");  
  77.         }  
  78.   
  79.         public ActionResult CreateClientSite(IndexViewModel clientSite)  
  80.         {  
  81.             if (clientSite != null)  
  82.             {  
  83.                 ClientSiteDetail objSites = new ClientSiteDetail();  
  84.                 objSites.ClientId = Convert.ToInt32(clientSite.ClientName);  
  85.                 objSites.SiteName = clientSite.SiteName.ToString();  
  86.                 objSites.SiteAddress = clientSite.SiteAddress;  
  87.                 UnitoffWork.ClientSiteDetailsRepository.Insert(objSites);  
  88.                 UnitoffWork.ClientSiteDetailsRepository.Save();  
  89.             }  
  90.             return RedirectToAction("ClientSite");  
  91.         }  
  92.     } 
Step 4 - Create Partial View _Add for Add action method as, 
  1. @model WebApp.ViewModel.Client.IndexViewModel  
  2.   
  3. @{  
  4.     Layout = "~/Views/Shared/_LayoutMenu.cshtml";  
  5. }  
  6.   
  7. <title>Add Client</title>  
  8. <script src="~/Scripts/External/jquery.min.js"></script>  
  9. <script src="~/Scripts/External/jquery.validate.min.js"></script>  
  10. <script src="~/Scripts/External/jquery.validate.unobtrusive.min.js"></script>  
  11.   
  12. @using (Html.BeginForm("Create""ClientDetails", FormMethod.Post))  
  13. {  
  14.     @Html.AntiForgeryToken()  
  15.     <div class="form-horizontal">  
  16.         <h4>Add Client</h4>  
  17.         <hr />  
  18.         @Html.ValidationSummary(true)  
  19.         <div class="form-group">  
  20.             @Html.Label("Name"new { @class = "control-label col-sm-2" })  
  21.             <div class="col-sm-8">  
  22.                 @Html.EditorFor(model => model.Name)  
  23.                 @Html.ValidationMessageFor(model => model.Name)  
  24.             </div>  
  25.         </div>  
  26.         <br />  
  27.         <div class="form-group">  
  28.             @Html.Label("Website"new { @class = "control-label col-sm-2" })  
  29.             <div class="col-sm-8">  
  30.                 @Html.EditorFor(model => model.Website)  
  31.             </div>  
  32.         </div>  
  33.         <br />  
  34.         <div class="form-group">  
  35.             @Html.Label("Phone"new { @class = "control-label col-sm-2" })  
  36.             <div class="col-sm-8">  
  37.                 @Html.EditorFor(model => model.Phone)  
  38.                 @Html.ValidationMessageFor(model => model.Phone)  
  39.             </div>  
  40.         </div>  
  41.         <br />  
  42.         <div class="form-group">  
  43.             @Html.Label("Mobile"new { @class = "control-label col-sm-2" })  
  44.             <div class="col-sm-8">  
  45.                 @Html.EditorFor(model => model.Mobile)  
  46.                 @Html.ValidationMessageFor(model => model.Mobile)  
  47.             </div>  
  48.         </div>  
  49.         <br />  
  50.         <div class="form-group">  
  51.             @Html.Label("Office Address"new { @class = "control-label col-sm-2" })  
  52.             <div class="col-sm-8">  
  53.                 @Html.TextAreaFor(model => model.Address)  
  54.                 @Html.ValidationMessageFor(model => model.Address)  
  55.             </div>  
  56.         </div>  
  57.         <div class="form-group">  
  58.             <div class="col-md-offset-2 col-md-10">  
  59.                 <input type="submit" value="Add" class="btn btn-default" />  
  60.             </div>  
  61.         </div>  
  62.     </div>  
  63. }  
  64.   
  65. <br />  
  66. <a href="@Url.Action("Index", "ClientDetails")" id="">Back To List</a> 

Step 5 - Create Partial View _List to show the list of the client names.
  1. @model IEnumerable<WebApp.ViewModel.Client.IndexViewModel>  
  2. <div>  
  3.     <table style="border:1px solid; width:100%">  
  4.         <thead>  
  5.             <tr>  
  6.                 <th width="15%" style="text-align:center">Name</th>  
  7.                 <th width="15%" style="text-align:center">Website</th>  
  8.                 <th width="10%" style="text-align:center">Phone</th>  
  9.                 <th width="10%" style="text-align:center">Mobile</th>  
  10.                 <th width="30%" style="text-align:center">Office Address</th>  
  11.             </tr>  
  12.         </thead>  
  13.         <tbody style="border:1px solid;">  
  14.             @if (Model != null)  
  15.             {  
  16.                 foreach (var item in Model)  
  17.                 {  
  18.                     <tr>  
  19.                         <td style="text-align:center">  
  20.                             @item.Name  
  21.                         </td>  
  22.                         <td style="text-align:center">  
  23.                             @item.Website  
  24.                         </td>  
  25.                         <td style="text-align:center">  
  26.                             @item.Phone  
  27.                         </td>  
  28.                         <td style="text-align:center">  
  29.                             @item.Mobile  
  30.                         </td>  
  31.                         <td style="text-align:center">  
  32.                             @item.Address  
  33.                         </td>                          
  34.                     </tr>  
  35.                 }  
  36.             }  
  37.         </tbody>  
  38.     </table>  
  39. </div> 
I am going to call this partial view, shown above, on Index view to show a list of all the clients, given below-
  1. @model IEnumerable<WebApp.ViewModel.Client.IndexViewModel>  
  2. @{  
  3.     ViewBag.Title = "Add Client";  
  4.     Layout = "~/Views/Shared/_LayoutMenu.cshtml";  
  5. }  
  6.   
  7. <a href="@Url.Action("Add", "ClientDetails")" id="addNew">Add New</a>  
  8.   
  9. @{ Html.RenderPartial("~/Views/ClientDetails/_List.cshtml"); }  
 
Step 6 - Create Partial View __AddClientSite to add the site details of each client. 
  1. @model WebApp.ViewModel.Client.IndexViewModel  
  2. @{  
  3.     ViewBag.Title = "Add Client Site";  
  4.     Layout = "~/Views/Shared/_LayoutMenu.cshtml";  
  5. }  
  6.   
  7. <a href="@Url.Action("Add", "ClientDetails")" id="addNew">Add New</a>  
  8.   
  9. @{ Html.RenderPartial("~/Views/ClientDetails/_List.cshtml"); }  
  10.   
  11. <title>Add Site Details</title>  
  12. <script src="~/Scripts/External/jquery.min.js"></script>  
  13. <script src="~/Scripts/External/jquery.validate.min.js"></script>  
  14. <script src="~/Scripts/External/jquery.validate.unobtrusive.min.js"></script>  
  15.   
  16. @using (Html.BeginForm("CreateClientSite""ClientDetails", FormMethod.Post))  
  17. {  
  18.     @Html.AntiForgeryToken()  
  19.     <div class="form-horizontal">  
  20.         <h4>Add Site Details</h4>  
  21.         <hr />  
  22.         @Html.ValidationSummary(true)  
  23.         <div class="form-group">  
  24.             @Html.Label("Client Name"new { @class = "control-label col-sm-2" })  
  25.             <div class="col-sm-4">  
  26.                 @Html.DropDownList("CurrentClientName", ViewBag.ClientListNames as   
  27.   
  28. IEnumerable<SelectListItem>, "-Select-"new { @id = "ClientId", @class = "form-  
  29.   
  30. control" })  
  31.                 @Html.HiddenFor(m => m.ClientName)  
  32.                 @Html.ValidationMessageFor(model => model.CurrentClientName)  
  33.             </div>  
  34.         </div>  
  35.   
  36.         <br />  
  37.             <div class="form-group">  
  38.             @Html.Label("Site Name"new { @class = "control-label col-sm-2" })  
  39.             <div class="col-sm-8">  
  40.                 @Html.EditorFor(model => model.SiteName)  
  41.                 @Html.ValidationMessageFor(model => model.SiteName)  
  42.             </div>  
  43.         </div>  
  44.   
  45.         <br />  
  46.         <div class="form-group">  
  47.             @Html.Label("Site Address"new { @class = "control-label col-sm-2" })  
  48.             <div class="col-sm-8">  
  49.                 @Html.TextAreaFor(model => model.SiteAddress)  
  50.                 @Html.ValidationMessageFor(model => model.SiteAddress)  
  51.             </div>  
  52.         </div>  
  53.   
  54.         <div class="form-group">  
  55.             <div class="col-md-offset-2 col-md-10">  
  56.                 <input type="submit" value="Add" class="btn btn-default" />  
  57.             </div>  
  58.         </div>  
  59.     </div>  
  60. }  
  61.   
  62. <br />  
  63. <a href="@Url.Action("ClientSite", "ClientDetails")" id="">Back To List</a>  
  64. <script>  
  65. $("#ClientId").change(function () {  
  66.     var cID = $("#ClientId").val();      
  67.     $("input[id='ClientName']").val(cID);  
  68. });  
  69. </script> 
 

Step 7 - 
Create partial view __ListClientSites to show a list of all the client sites, given below- 
  1. @model IEnumerable<WebApp.ViewModel.Client.IndexViewModel>  
  2. <div>  
  3.     <table style="border:1px solid; width:100%">  
  4.         <thead>  
  5.             <tr>  
  6.                 <th width="25%" style="text-align:center">Client Name</th>  
  7.                 <th width="20%" style="text-align:center">Site Name</th>  
  8.                 <th width="30%" style="text-align:center">Site Address</th>  
  9.             </tr>  
  10.         </thead>  
  11.         <tbody style="border:1px solid;">  
  12.             @if (Model != null)  
  13.             {  
  14.                 foreach (var item in Model)  
  15.                 {  
  16.                     <tr>  
  17.                         <td style="text-align:center">  
  18.                             @item.CurrentClientName  
  19.                         </td>  
  20.                         <td style="text-align:center">  
  21.                             @item.SiteName  
  22.                         </td>  
  23.                         <td style="text-align:center">  
  24.                             @item.SiteAddress  
  25.                         </td>  
  26.                    </tr>  
  27.                 }  
  28.             }  
  29.         </tbody>  
  30.     </table>  
  31. </div> 
I am going to call partial view, shown above, on main view i.e. ClientSiteDetails to show all the lists. 
  1. @model IEnumerable<WebApp.ViewModel.Client.IndexViewModel>  
  2. @{  
  3.     ViewBag.Title = "Client Sites";  
  4.     Layout = "~/Views/Shared/_LayoutMenu.cshtml";  
  5. }  
  6.   
  7. <a href="@Url.Action("AddClientSite", "ClientDetails")" id="addNew">Add New</a>  
  8.   
  9. @{ Html.RenderPartial("~/Views/ClientDetails/_ListClientSites.cshtml"); }   

Step 8 - Now, create another controller and action method. Here, I am going to show three dopdownlists Select client names, another two will automatically bind the office address and site addresses in it, given below-
  1.   public ActionResult Index()  
  2.         {  
  3.          List<SelectListItem> li = new List<SelectListItem>();  
  4.          ViewBag.DdlSiteAddress = li;  
  5.          ViewBag.AddressList = li;  
  6.          return View();  
  7.         }  
  8.    [HttpPost]  
  9.         public ActionResult BindAddress(string clientNo)  
  10.         {  
  11.             int id = Convert.ToInt32(clientNo);  
  12.             IEnumerable<ClientDetail> lst =   
  13.   
  14. UnitoffWork.ClientDetailsRepository.GetAll().Where(s => s.Id == Convert.ToInt32  
  15.   
  16. (clientNo));  
  17.             var listAdd = lst.Select(a => new { a.Address, a.Id }).ToList();  
  18.             var addressList = listAdd.Select(i => new SelectListItem { Text =   
  19.   
  20. i.Address, Value = i.Id.ToString() });  
  21.   
  22.             IEnumerable<ClientSiteDetail> l =   
  23.   
  24. UnitoffWork.ClientSiteDetailsRepository.GetAll(s => s.ClientId == id);  
  25.             var lstSiteAdd = l.Select(a => new { a.SiteAddress, a.Id }).ToList();  
  26.             var siteList = lstSiteAdd.Select(i => new SelectListItem { Text =   
  27.   
  28. i.SiteAddress, Value = i.Id.ToString() });  
  29.   
  30.             var bindingAddresses = new  
  31.             {  
  32.                 OffAdd = addressList,  
  33.                 siteAdd = siteList  
  34.             };  
  35.             return Json(new { bindingAddresses, JsonRequestBehavior.AllowGet });  
  36.         } 
Step 9 - Create View for Index action, shown above, method as-
  1. @using (Html.BeginForm("Create""Demo", FormMethod.Post))  
  2. {  
  3.     @Html.AntiForgeryToken()  
  4.     <div class="form-horizontal">         
  5.         <hr />  
  6.         @Html.ValidationSummary(true)         
  7.         
  8.         <div class="form-group">  
  9.             @Html.Label("Client Name"new { @class = "control-label col-sm-2" })  
  10.             <div class="col-sm-2">  
  11.                 @Html.DropDownList("CurrentClientName", ViewBag.ClientList as   
  12.   
  13. IEnumerable<SelectListItem>, "-Select-"new { @id = "ClientId", @class = "form-  
  14.   
  15. control" })  
  16.                 @Html.HiddenFor(m => m.ClientName)  
  17.                 @Html.ValidationMessageFor(model => model.CurrentClientName)  
  18.             </div>  
  19.         </div>  
  20.          
  21.         <div class="form-group">  
  22.             @Html.Label("Office Address"new { @class = "control-label col-sm-2"   
  23.   
  24. })  
  25.             <div class="col-sm-4">  
  26.                 @Html.DropDownList("OfficeAddress", ViewBag.AddressList as   
  27.   
  28. IEnumerable<SelectListItem>, "-Select-"new { @id = "OfficeId", @class = "form-  
  29.   
  30. control" })  
  31.                 @Html.HiddenFor(m => m.OfficeName)  
  32.                 @Html.ValidationMessageFor(model => model.OfficeAddress)  
  33.             </div>          
  34.         </div>  
  35.   
  36.         <div class="form-group">  
  37.             @Html.Label("Site Address"new { @class = "control-label col-sm-2" })  
  38.             <div class="col-sm-4">  
  39.                 @Html.DropDownList("DdlSiteAddress", ViewBag.DdlSiteAddress as   
  40.   
  41. IEnumerable<SelectListItem>, "-Select-"new { @id = "SiteId", @class = "form-  
  42.   
  43. control" })  
  44.                 @Html.HiddenFor(m => m.DdlSiteAddress)  
  45.                 @Html.ValidationMessageFor(model => model.DdlSiteAddress)  
  46.             </div>  
  47.         </div>  
  48.   
  49.          <div class="form-group">  
  50.             <div class="col-md-offset-2 col-md-10">  
  51.                 <input type="submit" value="Add" class="btn btn-default" />  
  52.             </div>  
  53.         </div>  
  54.     </div>  

JavaScript code, given below, will bind the values in office address and site address dynamically on the selection of the client name from the dropdownlist. 
  1. <script>  
  2. $("#ClientId").change(function () {  
  3.     var clientNo = $("#ClientId").val();  
  4.     if (clientNo == null || clientNo == "") {  
  5.         alert("Please Select Client");  
  6.         return;  
  7.     }  
  8.     $("input[id='ClientName']").val(clientNo);  
  9.     if (clientNo != null || clientNo != "") {  
  10.         $.ajax({  
  11.             url: "/Demo/BindAddress",  
  12.             type: "POST",  
  13.             data: JSON.stringify({ 'clientNo': clientNo }),  
  14.             dataType: "json",  
  15.             traditional: true,  
  16.             contentType: "application/json; charset=utf-8",  
  17.             success: function (result) {  
  18.                 //debugger;  
  19.                 var listItems = "";  
  20.                 var list = "";  
  21.                 var a = result.bindingAddresses.OffAdd;  
  22.                 var s = result.bindingAddresses.siteAdd;  
  23.                 for (i in a) {  
  24.                     listItems += "<option value='" + a[i].Value + "'>" + a[i].Text   
  25.   
  26. "</option>";  
  27.                 }  
  28.                 $("#OfficeId").html(listItems);  
  29.   
  30.                 for (j in s) {  
  31.                     list += "<option value='" + s[j].Value + "'>" + s[j].Text +   
  32.   
  33. "</option>";  
  34.                 }  
  35.                 $("#SiteId").html(list);  
  36.             },  
  37.             error: function () {  
  38.                 alert("An error has occured!!!");  
  39.             }  
  40.         });  
  41.     }  
  42. });  
  43. </script>   

Suppose, if I select a client name as Rupesh Kahane, other two dropdownlists are dynamically bound, given bellow-


Suppose, if I select the client name as Vithal Wadje, other two dropdownlists are dynamically bound, given bellow-

Summary - This article will help the fresher candidates learn how to dynamically bind the dropdownlist on the change event.