Comment garder la liste déroulante en cascade des éléments sélectionnés après la soumission du formulaire?

Lorsque la page charge, tout fonctionne bien. Mais lorsque je soumets le formulaire, mes listes déroulantes perdent les éléments sélectionnés précédents après la mise à jour de la page.

Comment puis-je modifier ma fonction pour initialiser les listes déroulantes et conserver les éléments précédents sélectionnés (sur les deux) s'ils existent.

Voici ma vue avec le javascript qui initialise mes listes déroulantes:

@model Models.Book @{ ViewBag.Title = "Index"; } @section scripts { <script type="text/javascript"> $(function() { $.getJSON("/Home/Books/List", function(data) { var items = "<option>--------------------</option>"; $.each(data, function(i, book) { items += "<option value='" + book.Value + "'>" + book.Text + "</option>"; }); $("#Books").html(items); }); $("#Books").change(function() { $.getJSON("/Home/Chapters/List/" + $("#Books> option:selected").attr("value"), function(data) { var items = "<option>--------------------</option>"; $.each(data, function(i, chapter) { items += "<option value='" + chapter.Value + "'>" + chapter.Text + "</option>"; }); $("#Chapters").html(items); }); }); }); </script> } @using (@Html.BeginForm("ListChapterContent", "Home")) { <div id="header"> <label for="Books">Books</label> <select id="Books" name="Books"></select> <label for="Chapters">Chapters</label> <select id="Chapters" name="Chapters" onchange="this.form.submit();"></select> </div> 

Voici mon modèle:

 public class Book { public string Translator{ get; set; } public string Edition{ get; set; } public List<Book> Books{ get; set; } public int SelectedBook { get; set; } public int SelectedChapter { get; set; } } 

Utilisez les HtmlHelpers pour générer vos contrôles plutôt que créer manuellement votre html afin que vous obteniez une liaison de modèle à 2 voies. Vous en trouverez le plus simple si vous utilisez un modèle de vue

 public class BookVM { [Required] public int? SelectedBook { get; set; } [Required] public int? SelectedChapter { get; set; } public SelectList BookList { get; set; } public SelectList ChapterList { get; set; } } 

Manette

 public ActionResult Create() { BookVM model = new BookVM(); ConfigureViewModel(model); return View(model); } private void ConfigureViewModel(BookVM model) { IEnumerable<Book> books = db.Books; model.BookList = new SelectList(books, "ID", "Name"); if (model.SelectedBook.HasValue) { IEnumerable<Chapter> chapters= db.Books.Where(c => c.BookId == model.SelectedBook.Value); model.ChapterList = new SelectList(chapters, "ID", "Name"); } else { model.ChapterList = new SelectList(Enumerable.Empty<SelectListItem>()); } } 

Et dans la vue

 @model BookVM @using (@Html.BeginForm()) { @Html.LabelFor(m => m.SelectedBook) @Html.DropDownListFor(m => m.SelectedBook, Model.BookList, "-Please select-") @Html.ValidationMessageFor(m => m.SelectedBook) @Html.LabelFor(m => m.SelectedChapter) @Html.DropDownListFor(m => m.SelectedChapter, Model.ChapterList) @Html.ValidationMessageFor(m => m.SelectedChapter) } 

Ensuite, votre script devient (supprimez le premier)

 var url = '@Url.Action("FetchChapters")'; // don't hard code url's var chapters = $('#SelectedChapter'); $('#SelectedBook').change(function() { if (!$(this).val()) { return; } $.getJSON(url, { id: $(this).val() }, function(data) { chapters.empty().append($('<option></option>').val('').text('-Please select-')); $.each(data, function(index, chapter) { subLocalities.append($('<option></option>').val(item.Value).text(item.Text)); }); }); }); 

Et votre méthode pour retourner le json serait

 public JsonResult FetchSubLocalities(int ID) { var chapters= db.Books.Where(c => c.BookId == ID).Select(c => new { Value = c.ID, Name = c.Name }); return Json(chapters, JsonRequestBehavior.AllowGet); } 

Et enfin dans la méthode POST, si vous devez retourner la vue

 [HttpPost] public ActionResult Create(BookVM model) { if(!ModelState.IsValid) { ConfigureViewModel(model); return View(model); } .... 

Reportez-vous également à ce DotNetFiddle pour un exemple similaire