Easiest Way to Create a Cascade Dropdown in ASP.NET MVC 3 with C#

Easiest way to create a cascade dropdown in ASP.NET MVC 3 with C#

As always you start with a model:

public class MyViewModel
{
public int? Year { get; set; }
public int? Month { get; set; }

public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable.Range(2000, 12).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
}

then a controller:

public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}

public ActionResult Months(int year)
{
if (year == 2011)
{
return Json(
Enumerable.Range(1, 3).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
}
return Json(
Enumerable.Range(1, 12).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
}
}

and finally a view:

@model AppName.Models.MyViewModel

@Html.DropDownListFor(
x => x.Year,
new SelectList(Model.Years, "Value", "Text"),
"-- select year --"
)

@Html.DropDownListFor(
x => x.Month,
Enumerable.Empty<SelectListItem>(),
"-- select month --"
)

<script type="text/javascript">
$('#Year').change(function () {
var selectedYear = $(this).val();
if (selectedYear != null && selectedYear != '') {
$.getJSON('@Url.Action("Months")', { year: selectedYear }, function (months) {
var monthsSelect = $('#Month');
monthsSelect.empty();
$.each(months, function (index, month) {
monthsSelect.append($('<option/>', {
value: month.value,
text: month.text
}));
});
});
}
});
</script>

Obviously you will notice that in my example I have hardcoded all the values. You should improve this logic by using notions like current year, current month, probably even fetch those values from a repository, etc... but for the purpose of the demonstration this should be enough to put you on the right track.

How to create Cascading Dropdown

How to create cascading dropdown using Ajax error handling?

Model should be:

public class Country
{
public int CountryId { get; set; }
public string? CountryName { get; set; }
}
public class State
{
public int StateId { get; set; }
public string StateName { get; set; }
public int CountryId { get; set; }
}
public class District
{
public int DistrictId { get; set; }
public string DistrictName { get; set; }
public int StateId { get; set; }
}

Note: As State depends on Country so added CountryId reference on State same goes for State and District.

Virtual data:

public static List<Country> ListOfCountry = new List<Country>()
{
new Country() { CountryId =101, CountryName ="INDIA", },
new Country() { CountryId =102, CountryName ="USA", },
new Country() { CountryId =103, CountryName ="UK", }
};
public static List<State> ListOfState = new List<State>()
{
//INDIA
new State() { CountryId =101, StateId =1, StateName = "Delhi" },
new State() { CountryId =101, StateId =2, StateName = "Haydrabad" },
new State() { CountryId =101, StateId =3, StateName = "Pune" },
//USA
new State() { CountryId =102, StateId =4, StateName = "New York" },
new State() { CountryId =102, StateId =5, StateName = "Silicon Valley" },
new State() { CountryId =102, StateId =6, StateName = "Dallaus" },
//UK
new State() { CountryId =103, StateId =7, StateName = "London" },
new State() { CountryId =103, StateId =8, StateName = "Cardif" },
new State() { CountryId =103, StateId =9, StateName = "Sundarland" },
};
public static List<District> ListOfDistrict = new List<District>()
{
//INDIA
new District() { DistrictId =101, StateId =1, DistrictName = "District Of Delhi" },
new District() { DistrictId =101, StateId =2, DistrictName = "District Of Haydrabad" },
new District() { DistrictId =101, StateId =3, DistrictName = "District Of Pune" },
//USA
new District() { DistrictId =102, StateId =4, DistrictName = "District Of New York" },
new District() { DistrictId =102, StateId =5, DistrictName = "District Of Silicon Valley" },
new District() { DistrictId =102, StateId =6, DistrictName = "District Of Dallaus" },
//UK
new District() { DistrictId =103, StateId =7, DistrictName = "District Of London" },
new District() { DistrictId =103, StateId =8, DistrictName = "District Of Cardif" },
new District() { DistrictId =103, StateId =9, DistrictName = "District Of Sundarland" },
};

Note: You can put this virtual data just inside the controller above the action. You even can fetch data from database as well. See the screenshot below:

Sample Image

Controller:

  public IActionResult Index()
{
return View();
}

[HttpGet]
public async Task<ActionResult> LoadCountry()
{
var country = ListOfCountry.ToList();

return Ok(country);

}

[HttpGet]
public async Task<ActionResult> GetState(int countryId)
{
var state = ListOfState.Where(cId => cId.CountryId == countryId).ToList() ;

return Ok(state);

}

[HttpGet]
public async Task<ActionResult> GetDistrict(int stateId)
{
var state = ListOfDistrict.Where(cId => cId.StateId == stateId).ToList();

return Ok(state);

}


[HttpPost]
public async Task<IActionResult> AddCountryStateDistrict(SubmitModel model)
{

return RedirectToAction("Index");
}

Views:



        <div class="form-group">
<label class="col-md-4 control-label">Country</label>
<div class="col-md-6">
<select class="form-control" id="ddlCountry"></select><br />
</div>
</div>

<div class="form-group">
<label class="col-md-4 control-label">State</label>
<div class="col-md-6">
<select class="form-control" id="ddlState"></select>
<br />

</div>
</div>
<br />
<div class="form-group">
<label class="col-md-4 control-label">District</label>
<div class="col-md-6">
<select class="form-control" id="ddlDistrict"></select>

</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-6">
<input id="Submit" value="Submit" class="btn btn-primary" />

</div>
</div>
</div>
<div class="col-lg-3"></div>


</div>

Scripts:

@section scripts {
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<script>

$(document).ready(function () {

var ddlCountry = $('#ddlCountry');
ddlCountry.append($("<option></option>").val('').html('Please Select Country'));
$.ajax({
url: 'http://localhost:5094/CascadingDropdown/LoadCountry',
type: 'GET',
dataType: 'json',
success: function (d) {
console.log(d);
$.each(d, function (i, country) {
console.log(i);
console.log(country);

ddlCountry.append($("<option></option>").val(country.countryId).html(country.countryName));
});
},
error: function () {
alert('Error!');
}
});

//State details by country id

$("#ddlCountry").change(function () {

//alert("On ddlCountry change");
var CountryId = parseInt($(this).val());
console.log(CountryId);
if (!isNaN(CountryId)) {
var ddlState = $('#ddlState');
ddlState.empty();
ddlState.append($("<option></option>").val('').html('Please wait ...'));


$.ajax({
url: 'http://localhost:5094/CascadingDropdown/GetState',
type: 'GET',
dataType: 'json',
data: { CountryId: CountryId },
success: function (d) {

ddlState.empty(); // Clear the please wait
ddlState.append($("<option></option>").val('').html('Select State'));
$.each(d, function (i, states) {
ddlState.append($("<option></option>").val(states.stateId).html(states.stateName));
});
},
error: function () {
alert('Error!');
}
});
}


});

//District Bind By satate id
$("#ddlState").change(function () {
var StateId = parseInt($(this).val());
if (!isNaN(StateId)) {
var ddlDistrict = $('#ddlDistrict');
ddlDistrict.append($("<option></option>").val('').html('Please wait ...'));
$.ajax({
url: 'http://localhost:5094/CascadingDropdown/GetDistrict',
type: 'GET',
dataType: 'json',
data: { stateId: StateId },
success: function (d) {


ddlDistrict.empty(); // Clear the plese wait
ddlDistrict.append($("<option></option>").val('').html('Select District Name'));
$.each(d, function (i, districts) {
ddlDistrict.append($("<option></option>").val(districts.districtId).html(districts.districtName));
});
},
error: function () {
alert('Error!');
}
});
}


});

//On Submit Method

$("#Submit").click(function(){
var ddlCountry = parseInt($("#ddlCountry").val());
var ddlState = parseInt( $("#ddlState").val());
var ddlDistrict = parseInt($("#ddlDistrict").val());

var data = {
ddlCountry: ddlCountry,
ddlState: ddlState,
ddlDistrict: ddlDistrict

};
console.log(data);
$.ajax({
url: 'http://localhost:5094/CascadingDropdown/AddCountryStateDistrict',
type: 'POST',
dataType: 'json',
data: data,
success: function (d) {
alert("Submitted To Database");
},
error: function () {
alert('Error!');
}
});

});

});
</script>
}

Output:

Sample Image

How to Cascading DropDownList using ASP.Net MVC

I would use ajax to do something like this:

<script>
$(document).ready(function () {
$("#country").change(function () {
BindStatesForDropDown();
});
});

function BindStatesForDropDown() {

var objParam = new Object();
objParam.Id = $("#country").val();

$.ajax({
type: "POST",
url: "/pageControl/getstate",
contentType: "application/json",
data: JSON.stringify(objParam),
success: function (res) {
$("#state").empty();
if (res.length > 0) {
$.each(res, function (key, data) {
$("#state").append($("<option></option>").val(data.id).html(data.name));
});
}
},
error: function (res) {
}
});
}
</script>

AJAX Cascading Dropdowns ASP.NET MVC

A colleague helped me solve this problem. Firstly, the Ajax script was using the wrong URL. Secondly, my controller functions were unnecessarily complicated.

Here is the updated AJAX script:

$(document).ready(function () {
//Dropdownlist Selectedchange event
$('#ProductLine').change(function () {
$.ajax({
url: '/SMRMaster/GetSeries',
type: 'GET',
datatype: 'JSON',
data: { productLine: $('#ProductLine').val() },
success: function (result) {
$('#SeriesID').html('');
$('#SeriesID').append($('<option>Make Selection</option>'));
$.each(result, function (i, item) {
var optionData = '<option value="' + item.Value + '">' + item.Text + '</option>';
$(optionData).appendTo('#SeriesID')
});
}
});
});
});

And here is the updated Controller:

    public JsonResult GetSeries(string productLine)
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
List<SelectListItem> series = (from s in db.Series
where s.ProductLineName == productLine
select new SelectListItem { Value = s.SeriesName, Text = s.SeriesName }).Distinct().ToList();
return Json(series, JsonRequestBehavior.AllowGet);
}

public List<ProductLine> GetProductLines()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var productLineList = (from p in db.ProductLines
select p).ToList();
return productLineList;
}


public ActionResult RequestForm()
{
var productLineList = new List<SelectListItem>();
foreach (var item in GetProductLines())
{
productLineList.Add(new SelectListItem { Text = item.ProductlineName, Value = item.ProductlineName });
}
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var requestViewModel = new RequestViewModel { SMRMaster = new SMRMaster(), Engineers = GetEngineers(), ProductLines = productLineList };
return View(requestViewModel);
}

asp.net MVC cascading dropdown lists

Your drop down id is Region but in your success function you are using Regions

Make this one small change and it will work.

Controller:

public class MyCountry
{
public int CountryCode { get; set; }
public string Country { get; set; }
}

public class Region
{
public int CountryCode { get; set; }
public string RegionName { get; set; }
}

public class ViewModel
{
public List<MyCountry> Country { get; set; }
public List<Region> Region { get; set; }
}

public class DropDownExampleController : Controller
{
public ActionResult Index()
{
var model = new ViewModel();

var c1 = new MyCountry { Country = "South Africa", CountryCode = 1 };
var c2 = new MyCountry { Country = "Russia", CountryCode = 2 };

model.Country = new List<MyCountry> { c1, c2 };

var r1 = new Region { RegionName = "Gauteng", CountryCode = 1};
var r2 = new Region { RegionName = "Western Cape", CountryCode = 1 };
var r3 = new Region { RegionName = "Siberia", CountryCode = 2 };

model.Region = new List<Region> { r1, r2,r3};
return View(model);
}

[HttpPost]
public JsonResult GetRegionsByCountryCode(string countryCode)
{
var r1 = new Region { RegionName = "Gauteng", CountryCode = 1 };
var r2 = new Region { RegionName = "Western Cape", CountryCode = 1 };
var r3 = new Region { RegionName = "Siberia", CountryCode = 2 };

var regions = new List<Region> { r1, r2, r3 };

var results = regions.Where(r => r.CountryCode == Int32.Parse(countryCode)).ToList();

return Json(results);
}
}

View:

@model MVCTutorial.Controllers.ViewModel

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#Country").change(function () {

var countryCode = $("#Country").val();
$("#Region").empty();

$.ajax({
type: 'POST',
url: '@Url.Action("GetRegionsByCountryCode")',
data: { countryCode: countryCode },
success: function (data) {
$.each(data, function (index, value) {
$("#Region").append('<option value="'
+ value.CountryCode + '">'
+ value.RegionName + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve regions.' + ex);
}
});
return false;
})
});
</script>

<div class="form-group">
Country
@Html.DropDownListFor(m => m.Country, new SelectList(Model.Country, "CountryCode", "Country"), "--Select--", new { @class = "form-control" })
</div>
<div class="form-group">
Region
@Html.DropDownListFor(m => m.Region, new SelectList(Model.Region, "CountryCode", "RegionName"), "--Select--", new { @class = "form-control" })
</div>

Cascading dropdownlists ASP.NET Core MVC

The JS that worked for me

$(document).ready(function () {

$("#models").change(function () {
$.get("/Cars/GetEnginesByModelId", { id: $("#models").val() }, function (data) {
$("#engines").empty();
$.each(data, function (index, row) {
$("#engines").append("<option value='" + row.id + "'>" + row.name + "</option>")
});
});
})

});



Related Topics



Leave a reply



Submit