Country - State - City Dropdown - Binding - Change Event using JQuery Ajax
Here I have created blog, how to use dropdown cascading like, country, state and city.
I have use some generic code.
To bind state and city dropdown I have used ajax call.
/****** Object: Table [dbo].[Country] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Country](
[CountryId] [uniqueidentifier] NOT NULL,
[CountryName] [nvarchar](50) NOT NULL,
[CountryCode] [nvarchar](5) NULL,
[CountryPhoneCode] [nvarchar](7) NULL,
[Status] [nvarchar](10) NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_Country_CreatedDate] DEFAULT (getdate()),
[UpdatedBy] [uniqueidentifier] NULL,
[UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_Country_UpdatedDate] DEFAULT (getdate()),
CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED
(
[CountryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[State] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[State](
[StateId] [uniqueidentifier] NOT NULL,
[CountryId] [uniqueidentifier] NOT NULL,
[StateName] [nvarchar](50) NOT NULL,
[StateCode] [nvarchar](5) NULL,
[Status] [nvarchar](10) NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_State_CreatedDate] DEFAULT (getdate()),
[UpdatedBy] [uniqueidentifier] NULL,
[UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_State_UpdatedDate] DEFAULT (getdate()),
CONSTRAINT [PK_QState] PRIMARY KEY CLUSTERED
(
[StateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[City] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
[CityId] [uniqueidentifier] NOT NULL,
[StateId] [uniqueidentifier] NOT NULL,
[CityName] [nvarchar](50) NOT NULL,
[CityCode] [nvarchar](5) NULL,
[CityPhoneCode] [nvarchar](7) NULL,
[Status] [nvarchar](10) NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_City_CreatedDate] DEFAULT (getdate()),
[UpdatedBy] [uniqueidentifier] NULL,
[UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_City_UpdatedDate] DEFAULT (getdate()),
CONSTRAINT [PK_City] PRIMARY KEY CLUSTERED
(
[CityId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[City] WITH CHECK ADD CONSTRAINT [FK_City_State] FOREIGN KEY([StateId])
REFERENCES [dbo].[State] ([StateId])
GO
ALTER TABLE [dbo].[City] CHECK CONSTRAINT [FK_City_State]
GO
ALTER TABLE [dbo].[State] WITH CHECK ADD CONSTRAINT [FK_State_Country] FOREIGN KEY([CountryId])
REFERENCES [dbo].[Country] ([CountryId])
GO
ALTER TABLE [dbo].[State] CHECK CONSTRAINT [FK_State_Country]
GO
ALTER TABLE [dbo].[State] WITH CHECK ADD CONSTRAINT [FK_State_QDevCountry] FOREIGN KEY([CountryId])
REFERENCES [dbo].[Country] ([CountryId])
GO
ALTER TABLE [dbo].[State] CHECK CONSTRAINT [FK_State_QDevCountry]
GO
/****** Object: Table [dbo].[Users] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
[UserId] [uniqueidentifier] NOT NULL,
[usertype] [nvarchar](10) NOT NULL,
[Username] [nvarchar](50) NOT NULL,
[Password] [nvarchar](100) NOT NULL,
[FirstName] [nvarchar](40) NULL,
[LastName] [nvarchar](30) NOT NULL,
[AddressLine1] [nvarchar](150) NULL,
[AddressLine2] [nvarchar](150) NULL,
[CityId] [uniqueidentifier] NULL,
[EmailId] [nvarchar](50) NULL,
[MobileNumber] [nvarchar](15) NULL,
[HomePhoneNumber] [nvarchar](15) NULL,
[WorkPhoneNumber1] [nvarchar](15) NULL,
[WorkPhoneNumber2] [nvarchar](15) NULL,
[Status] [nvarchar](8) NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreatedDate] [datetime] NULL CONSTRAINT [DF_Users_CreatedDate] DEFAULT (getdate()),
[UpdatedBy] [uniqueidentifier] NULL,
[UpdatedDate] [datetime] NULL CONSTRAINT [DF_Users_UpdatedDate] DEFAULT (getdate()),
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
View Model
namespace Demo.ViewModel { public class VMCountry { public System.Guid CountryId { get; set; } [Required] [DisplayName("Country Name")] public string CountryName { get; set; } [Required] [DisplayName("Country Code")] public string CountryCode { get; set; } public string CountryPhoneCode { get; set; } public string Status { get; set; } public System.Guid CreatedBy { get; set; } public System.DateTime CreatedDate { get; set; } public Nullable<System.Guid> UpdatedBy { get; set; } public System.DateTime UpdatedDate { get; set; } } }
namespace Demo.ViewModel { public class VMState { public System.Guid StateId { get; set; } public System.Guid CountryId { get; set; } public string StateName { get; set; } public string StateCode { get; set; } public string Status { get; set; } public System.Guid CreatedBy { get; set; } public System.DateTime CreatedDate { get; set; } public Nullable<System.Guid> UpdatedBy { get; set; } public System.DateTime UpdatedDate { get; set; } public List<SelectListItem> CountryList { get; set; } } }
namespace Demo.ViewModel { public class VMCity { public System.Guid CityId { get; set; } public System.Guid StateId { get; set; } public string CityName { get; set; } public string CityCode { get; set; } public string CityPhoneCode { get; set; } public string Status { get; set; } public System.Guid CreatedBy { get; set; } public System.DateTime CreatedDate { get; set; } public Nullable<System.Guid> UpdatedBy { get; set; } public System.DateTime UpdatedDate { get; set; } public List<SelectListItem> CountryList { get; set; } public List<SelectListItem> StateList { get; set; } public System.Guid CountryId { get; set; } } }
namespace Demo.ViewModel { public class VMUser { public System.Guid UserId { get; set; } public string usertype { get; set; } [Required] [DisplayName("Username")] public string Username { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Required] [DisplayName("First Name")] public string FirstName { get; set; } [DisplayName("Last Name")] public string LastName { get; set; } public string AddressLine1 { get; set; } public string AddressLine2 { get; set; } public Nullable<System.Guid> CityId { get; set; } [DisplayName("Email Id")] public string EmailId { get; set; } [DisplayName("Mobile Number")] public string MobileNumber { get; set; } public string Status { get; set; } public System.Guid CreatedBy { get; set; } public Nullable<System.DateTime> CreatedDate { get; set; } public Nullable<System.Guid> UpdatedBy { get; set; } public Nullable<System.DateTime> UpdatedDate { get; set; } //Extra Properties for page view public List<SelectListItem> CountryList { get; set; } public List<SelectListItem> StateList { get; set; } public List<SelectListItem> CityList { get; set; } public Nullable<System.Guid> Country { get; set; } public Nullable<System.Guid> State { get; set; } } }
Use Automapper to map data model and view model.
namespace Demo.Business { public static class AutoMapperConfig { public static void RegisterMappings() { Mapper.Initialize(cfg => { cfg.CreateMap<VMCountry, Country>(); cfg.CreateMap<Country, VMCountry>(); cfg.CreateMap<VMState, State>(); cfg.CreateMap<State, VMState>(); cfg.CreateMap<VMCity, City>(); cfg.CreateMap<City, VMCity>(); }); } } }
Setup with Automapper config in global.asax
namespace Demo.Web { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AutoMapperConfig.RegisterMappings(); } } }
Setup Generic class and properties.
namespace Demo.Common { public class ResultResponse<T> { public bool Success { get; set; } = true; public string Message { get; set; } public DTResult<T> Data { get; set; } public T Datas { get; set; } public Dictionary<string, string> Exceptions { get; set; } } public class ResultResponses<T> { public bool Success { get; set; } = true; public string Message { get; set; } public T Data { get; set; } public Dictionary<string, string> Exceptions { get; set; } } public class ResultResponseSingle<T> { public bool Success { get; set; } = true; public string Message { get; set; } public T Data { get; set; } public Dictionary<string, string> Exceptions { get; set; } } }
Business Layer
namespace Demo.Business { public class BLCountry { public static ResultResponses<List<VMCountry>> GetCountryListforDDL() { var exceptions = new Dictionary<string, string>(); List<VMCountry> data = new List<VMCountry>(); try { AnroAppEntities db = new AnroAppEntities(); var datas = db.Countries.AsQueryable().OrderBy(c=>c.CountryName).ToList(); var Datas = AutoMapper.Mapper.Map<List<Country>, List<VMCountry>>(datas); data = Datas; } catch (SqlException sqlException) { exceptions.Add("SqlException", sqlException.Message); } catch (TaskCanceledException taskCanceledException) { exceptions.Add("TaskCanceledException", taskCanceledException.Message); } catch (Exception ex) { exceptions.Add("Exception", ex.Message); } return new ResultResponses<List<VMCountry>> { Exceptions = exceptions, Data = data }; } } }
namespace Demo.Business { public class BLStates { public static ResultResponses<List<VMState>> GetStateListforDDL(string CountryId) { var exceptions = new Dictionary<string, string>(); List<VMState> Data = new List<VMState>(); try { AnroAppEntities db = new AnroAppEntities(); Guid countryId = new Guid(CountryId); var datas = db.States.AsQueryable().Where(a => a.CountryId == countryId).OrderBy(c => c.StateName).ToList(); var Datas = AutoMapper.Mapper.Map<List<State>, List<VMState>>(datas); Data = Datas; } catch (SqlException sqlException) { exceptions.Add("SqlException", sqlException.Message); } catch (TaskCanceledException taskCanceledException) { exceptions.Add("TaskCanceledException", taskCanceledException.Message); } catch (Exception ex) { exceptions.Add("Exception", ex.Message); } return new ResultResponses<List<VMState>> { Exceptions = exceptions, Data = Data }; } } }
namespace Demo.Business { public class BLCity { public static ResultResponses<List<VMCity>> GetCityListforDDL(string StateId) { var exceptions = new Dictionary<string, string>(); List<VMCity> Data = new List<VMCity>(); try { AnroAppEntities db = new AnroAppEntities(); Guid stateId = new Guid(StateId); var datas = db.Cities.AsQueryable().Where(a => a.StateId == stateId).OrderBy(c => c.CityName).ToList(); var Datas = AutoMapper.Mapper.Map<List<City>, List<VMCity>>(datas); Data = Datas; } catch (SqlException sqlException) { exceptions.Add("SqlException", sqlException.Message); } catch (TaskCanceledException taskCanceledException) { exceptions.Add("TaskCanceledException", taskCanceledException.Message); } catch (Exception ex) { exceptions.Add("Exception", ex.Message); } return new ResultResponses<List<VMCity>> { Exceptions = exceptions, Data = Data }; } } }
namespace Demo.Business { public class BLUsers { public static ResultResponse<string> Save(VMUser objData, string AddorUpdate) { string returnMessage = ""; var exceptions = new Dictionary<string, string>(); try { using (var db = new AnroAppEntities()) { var user = AutoMapper.Mapper.Map<VMUser, User>(objData); if (AddorUpdate == "add") db.Users.Add(user); else db.Entry(user).State = System.Data.Entity.EntityState.Modified; var i = db.SaveChanges(); if (i == 1) returnMessage = "success"; else returnMessage = "Something wrong"; } } catch (System.Data.Entity.Validation.DbEntityValidationException dbEx) { Exception raise = dbEx; foreach (var validationErrors in dbEx.EntityValidationErrors) { foreach (var validationError in validationErrors.ValidationErrors) { string message = string.Format("{0}:{1}", validationErrors.Entry.Entity.ToString(), validationError.ErrorMessage); raise = new InvalidOperationException(message, raise); } } throw raise; } catch (SqlException sqlException) { exceptions.Add("SqlException", sqlException.Message); } catch (TaskCanceledException taskCanceledException) { exceptions.Add("TaskCanceledException", taskCanceledException.Message); } catch (Exception ex) { exceptions.Add("Exception", ex.Message); } return new ResultResponse<string> { Exceptions = exceptions, Message = returnMessage }; } } }
Common Controller
using Demo.Business; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; namespace Demo.Web.Controllers { public class CommonController : Controller { public static List<SelectListItem> BindCountryList() { List<SelectListItem> items = new List<SelectListItem>(); var list = BLCountry.GetCountryListforDDL(); var statuslist = list.Data.ToList(); items = statuslist.Select(a => new SelectListItem { Text = a.CountryName, Value = a.CountryId.ToString() }).ToList(); return items; } public static List<SelectListItem> BindStateList(string id) { List<SelectListItem> items = new List<SelectListItem>(); var list = BLStates.GetStateListforDDL(id); var statuslist = list.Data.ToList(); items = statuslist.Select(a => new SelectListItem { Text = a.StateName, Value = a.StateId.ToString() }).ToList(); return items; } public static List<SelectListItem> BindCityList(string id) { List<SelectListItem> items = new List<SelectListItem>(); var list = BLCity.GetCityListforDDL(id); var statuslist = list.Data.ToList(); items = statuslist.Select(a => new SelectListItem { Text = a.CityName, Value = a.StateId.ToString() }).ToList(); return items; } public JsonResult GetStates(string id) { List<SelectListItem> datas = new List<SelectListItem>(); var list = BLStates.GetStateListforDDL(id).Data.ToList(); datas = list.Select(a => new SelectListItem { Text = a.StateName, Value = a.StateId.ToString() }).ToList(); datas.Insert(0, new SelectListItem { Text = "Select State", Value = "select" }); return Json(new SelectList(datas, "Value", "Text")); } public JsonResult GetCity(string id) { List<SelectListItem> datas = new List<SelectListItem>(); var list = BLCity.GetCityListforDDL(id).Data.ToList(); datas = list.Select(a => new SelectListItem { Text = a.CityName, Value = a.CityId.ToString() }).ToList(); datas.Insert(0, new SelectListItem { Text = "Select City", Value = "select" }); return Json(new SelectList(datas, "Value", "Text")); } public ActionResult refreshdata() { return Json(new { message = "success" }, JsonRequestBehavior.AllowGet); } } }
User Controller with Register Action and Save action
namespace Demo.Web.Controllers { public class UserController : Controller { public ActionResult Register() { VMUser model = new VMUser(); model.CountryList = CommonController.BindCountryList(); model.CountryList = CommonController.BindCountryList(); var countryid = model.CountryList.Where(a => a.Text.ToLower() == "india").FirstOrDefault().Value; model.Country = countryid != null ? new Guid(countryid) : Guid.NewGuid(); model.StateList = CommonController.BindStateList(countryid != null ? countryid : Guid.NewGuid().ToString()); var statedata = model.StateList.Where(s => s.Text.ToLower() == "gujarat").FirstOrDefault(); var stateid = statedata != null ? statedata.Value : null; model.State = stateid != null ? new Guid(stateid) : Guid.NewGuid(); model.CityList = CommonController.BindCityList(stateid != null ? stateid : Guid.NewGuid().ToString()); var citydata = model.CityList.Where(s => s.Text.ToLower() == "ahmedabad").FirstOrDefault(); var cityid = citydata != null ? citydata.Value : null; model.CityId = cityid != null ? new Guid(cityid) : Guid.NewGuid(); return View(model); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(VMUser model) { try { if (ModelState.IsValid) { model.UserId = Guid.NewGuid(); model.Status = "Active"; model.CreatedBy = Guid.NewGuid(); model.CreatedDate = DateTime.Now; model.UpdatedBy = null; model.UpdatedDate = DateTime.Now; var data = BLUser.Save(model, "add"); if (data.Exceptions.Count > 0) { string error = ""; foreach (var keyValuePair in data.Exceptions) { error += keyValuePair.Value; } ModelState.AddModelError("", error); } return RedirectToAction("Index"); } return View(model); } catch (Exception ex) { ModelState.AddModelError("", ex.Message); return View(model); } } } }
View page
@model Demo.ViewModel.VMUser @{ ViewBag.Title = "Register"; } <section class="content"> <div class="box"> <div class="box-header with-border"> <h3 class="box-title">User - Register</h3> </div> <!-- /.box-header --> <div class="box-body"> <div class="col-md-8"> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="row"> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger validation-msg " }) </div> </div> </div> <div class="row"> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger validation-msg " }) </div> </div> </div> <div class="row"> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.EmailId, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.EmailId, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.EmailId, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.MobileNumber, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.MobileNumber, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.MobileNumber, "", new { @class = "text-danger validation-msg " }) </div> </div> </div> <div class="row"> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.AddressLine1, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.AddressLine1, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.AddressLine1, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.AddressLine2, htmlAttributes: new { @class = "control-label" }) @Html.EditorFor(model => model.AddressLine2, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.AddressLine2, "", new { @class = "text-danger validation-msg " }) </div> </div> </div> <div class="row"> <div class="col-md-4"> <div class="form-group"> @Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label" }) @Html.DropDownListFor(model => model.Country, Model.CountryList, "Please select a Country", htmlAttributes: new { @class = "form-control select2", @id = "countryid" }) @Html.ValidationMessageFor(model => model.Country, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-4"> <div class="form-group"> @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label" }) @Html.DropDownListFor(model => model.State, Model.StateList, "Please select a State", htmlAttributes: new { @class = "form-control select2", @id = "stateid" }) @Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger validation-msg " }) </div> </div> <div class="col-md-4"> <div class="form-group"> @Html.LabelFor(model => model.CityId, htmlAttributes: new { @class = "control-label" }) @Html.DropDownListFor(model => model.CityId, Model.CityList, "Please select a City", htmlAttributes: new { @class = "form-control select2", @id = "cityid" }) @Html.ValidationMessageFor(model => model.CityId, "", new { @class = "text-danger validation-msg " }) </div> </div> </div> <div class="row"> <div class="col-md-10"> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> @Html.ActionLink("Back to List", "Index", null, new { @class = "btn btn-default" }) </div> </div> </div> </div> } </div> </div> </div> </section> <script src="~/Content/CustomJS/User.js"></script>
User.js - Ajax call
var sitename = '/demo.web'; $(document).ready(function () { //Country Dropdownlist Selectedchange event $("#countryid").change(function () { $("#stateid").empty(); $("#cityid").empty(); $.ajax({ type: 'POST', url: sitename + '/Common/GetStates', dataType: 'json', data: { id: $("#countryid").val() }, success: function (states) { $.each(states, function (i, state) { $("#stateid").append('<option value="' + state.Value + '">' + state.Text + '</option>'); }); $("#cityid").append('<option value="select">Select City</option>'); }, error: function (ex) { alert('Failed to retrieve states.' + ex); } }); return false; }); //State Dropdownlist Selectedchange event $("#stateid").change(function () { $("#cityid").empty(); $.ajax({ type: 'POST', url: sitename + '/Common/GetCity', dataType: 'json', data: { id: $("#stateid").val() }, success: function (states) { $.each(states, function (i, state) { $("#cityid").append('<option value="' + state.Value + '">' + state.Text + '</option>'); }); }, error: function (ex) { alert('Failed to retrieve states.' + ex); } }); return false; }); });