There are several ways to do this without forcing you to store all possible data elements in the model, but I prefer to use Javascript / JQuery. The following is an example of cascading a country / state:
Javascript is used to get states when choosing a country:
<script type="text/javascript"> function AppendUrlParamTokens(url, params) { for (var param in params) { if (params[param] == null) { delete params[param]; } } return url + "?" + jQuery.param(params); } function OnCountriesChange(ddl) { jQuery.getJSON(AppendUrlParamTokens('@Url.Action("GetStates", "Data")', { countryId: ddl.options[ddl.selectedIndex].value }), function (result) { var target = jQuery('#states_ddl'); target.empty(); jQuery(result).each(function() { jQuery(document.createElement('option')) .attr('value', this.Value) .text(this.Text) .appendTo(target); }); }); }; </script>
Country dropdown menu:
@Html.DropDownListFor(model => model.Country, new SelectList(Model.Countries, "Value", "Text", Model.PreviousCountrySelected), "(Select One)", new { id = "countries_ddl", onchange = "OnCountriesChange(this)" })
Status Dropdown Menu:
Html.DropDownListFor(model => model.State, Model.States != null ? new SelectList(Model.States, "Value", "Text", Model.PreviousStateSelected) : new SelectList(new List<SelectListItem>(), "Value", "Text"), new { id = "states_ddl" })
Controller method for retrieving states:
public ActionResult GetStates(short? countryId) { if (!countryId.HasValue) { return Json(new List<object>(), JsonRequestBehavior.AllowGet); } var data = GetAllStatesForCountry(countryId.Value).Select(o => new { Text = o.StateName, Value = o.StateId }); return Json(data, JsonRequestBehavior.AllowGet); }
The idea is that when you select dropdown 1, you use ajax to get the second value of the dropdown.
Edit: Forgot to enable the utility method for creating urls