Reputation: 149
I have three dropdown (cascaded) in a View. First dropdown elements come from the ViewModel. I'm populating 2nd dropdown elements when 1st dropdown changes. and same for the 3rd dropdown. Classic cascading dropdownlist example you can find on anywhere (ex: http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/ )
Problem occurs when user submits the form. If ModelState is invalid, 2nd and 3rd dropdown loses their items and 1st dropdown conserves its state. I understand why they behave like that but can't figure it out how to populate them again with the users selected values.
/Country/Index
page loaded
, user selects CountryId DropDownList
Country Id
to method and if result is not null, load StateId DropDownList
.PostalCode Textbox
and submit form.CountryId DropDownlist
is filled and selected but StateId ropdownlist
is empty.//HTML Code
//...
@Html.DropDownListFor(m => m.CountryId, ViewBag.Country as IEnumerable<SelectListItem>, "Select Country")
@Html.DropDownListFor(m => m.StateId, new SelectList(string.Empty, "Value", "Text"), "Select State")
@Html.DropDownListFor(m => m.CityId, new SelectList(string.Empty, "Value", "Text"), "Select City")
@Html.TextBoxFor(m=> m.PostalCode)
<script type="text/javascript">
var countryDDL = $("#CountryId");
countryDDL.change(function () {
$.ajax({
type: 'POST',
url: '@Url.Action("LoadStateList")',
dataType: 'json',
data: { countryId: countryDDL.val() },
success: function myfunction(states) {
$("#StateId").empty();
$.each(states, function (i, state) {
$("#StateId").append('<option value="' + state.Value + '">' + state.Text + '</option>');
}); }
});
return false;
});
//Code for 2nd (state) dropdownlist.change() method.
//...
</script>
public ActionResult Index()
{
ViewBag.CountryList = LoadCountryList();
return View();
}
[HttpPost]
public ActionResult Index(CountryViewModel cvm)
{
if(ModelState.IsValid)
{
//Save or do whatever you want
}
ViewBag.CountryList = LoadCountryList();
return View();
}
public class CountryViewModel
{
public int CountryId {get;set;}
public int StateId {get;set;}
public int CityId {get;set;}
[Required]
public string PostalCode {get;set;}
}
Upvotes: 3
Views: 1756
Reputation: 239400
The actual select options are not posted (nor should they be). Therefore, when you get to the post action, your select list is empty. The solution? Simply repopulate it the same as you would in your get action. Granted, here, you're not populating those in the get action, but rather retrieving them via AJAX. You could technically do it the same way on post, if you wanted. You'd just have to run the AJAX calls on page load to refetch the select lists. However, it would be much better at this point to just do it in your post action.
Upvotes: 2