Easy Cascading Dropdowns

cloudscribe.Web.Common provides unobtrusive javascript to easily wire up cascading dropdown lists. This example comes from the CompanyInfo.cshtml view in cloudscribe Core. There we have a country list and a state list, when the selected country is changed, unobtrusive ajax is used to fetch the state list for the selected country. In that view we have this:

<div class="form-group">
	<label asp-for="CompanyCountry" class="col-md-2 control-label">@sr["Country"]</label>
	<div class="col-md-10">
		<select id="CompanyCountry" asp-for="CompanyCountry"
				asp-items="Model.AvailableCountries" class="form-control"></select>
		<span asp-validation-for="CompanyCountry" class="text-danger"></span>
	</div>
</div>
<div class="form-group">
	<label asp-for="CompanyRegion" class="col-md-2 control-label">@sr["State"]</label>
	<div class="col-md-10">
		<select id="CompanyRegion" class="form-control"
				asp-for="CompanyRegion"
				asp-items="Model.AvailableStates"
				data-cascade-childof="CompanyCountry"
				data-cascade-serviceurl='@Url.Content("~/CoreData/GetStatesJson/?countryCode=")'
				data-cascade-orig-val="@Model.CompanyRegion"
				data-cascade-select-label="-Please select-"></select>
		<span asp-validation-for="CompanyRegion" class="text-danger"></span>
	</div>
</div>

@{ await Html.RenderPartialAsync("_CascadeScriptsPartial"); }

the data-cascade-childof attribute point to the parent dropdownlist and when it changes it triggers the ajax request to the provided service url that return json data for the selected state. In this example the country list is populated server side and the initial state list is also populated server side based on the default or current country selection.

The GetStatesJson method is in the CoreDataController in cloudscribe Core, and that method looks like this:

[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> GetStatesJson(
   string countryCode)
{
	var country = await dataManager.FetchCountry(countryCode);
	List<IGeoZone> states;
	if (country != null)
	{
		states = await dataManager.GetGeoZonesByCountry(country.Id);
	}
	else
	{
		states = new List<IGeoZone>(); //empty list
	}

	var selecteList = new SelectList(states, "Code", "Name");

	return Json(selecteList);

}

You can see the _CascadeScriptsPartial references cloudscribe-cascade-unobtrusive.js which wires things up for you based on the data- attributes

Comments