In my code, i use ajax.beginform for collection entries (with modal window for new entries) then refresh the list.
Controller
public ActionResult BusinessCategoryNewUpdateRow(BusinessCategoryViewModel vmodel) { try { vmodel.Subcategories.Add(vmodel.NewEditEntry); return PartialView("BusinessCategory/SubBusinessCategoryView", vmodel); } catch { return View(); } }
View :
@using (Ajax.BeginForm("BusinessCategoryNewUpdateRow", "BusinessReference", new AjaxOptions { UpdateTargetId = "subCategoryPart", OnSuccess = "clearDialog" }, new { id = "showWin" })) { <div class="form"> <div class="row"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.MainCategory.name, new { @class = "floating-label" }) @Html.EditorFor(model => model.MainCategory.name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.MainCategory.name, "", new { @class = "text-danger" }) </div> </div> </div> <div class="row"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.MainCategory.business_cat_code, new { @class = "floating-label" }) @Html.EditorFor(model => model.MainCategory.business_cat_code, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.MainCategory.business_cat_code, "", new { @class = "text-danger" }) </div> </div> </div> <div class="row p-b-10"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.MainCategory.description, new { @class = "floating-label" }) @Html.EditorFor(model => model.MainCategory.description, "Text", new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.MainCategory.description, "", new { @class = "text-danger" }) </div> </div> </div> <div class="row"> <div class="col-md-2"> <h5>Sub-Category</h5> </div> <div class="col-md-3 p-b-5"> @*<button type="button" class="btn btn-sm btn-primary has-ripple ml-1" data-toggle="modal" data-target="#popWinSubCategory">Add<span class="ripple ripple-animate" style="height: 173.675px; width: 173.675px; animation-duration: 0.7s; animation-timing-function: linear; background: rgb(255, 255, 255); opacity: 0.4; top: -49.1375px; left: 53.1625px;"></span></button>*@ <button type="button" class="btn btn-sm btn-secondary has-ripple" data-toggle="modal" data-target="#popWinSubCategory">Add<span class="ripple ripple-animate" style="height: 173.675px; width: 173.675px; animation-duration: 0.7s; animation-timing-function: linear; background: rgb(255, 255, 255); opacity: 0.4; top: -49.1375px; left: 53.1625px;"></span></button> </div> </div> @*popup window*@ <div id="popWinSubCategory" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="popWinSubCategoryLabel" style="display: none;" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="popWinSubCategoryLabel">Add/Edit Subcategory</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> </div> <div class="modal-body"> <div class="row"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.NewEditEntry.name, new { @class = "floating-label" }) @Html.EditorFor(model => model.NewEditEntry.name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.NewEditEntry.name, "", new { @class = "text-danger" }) </div> </div> </div> <div class="row"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.NewEditEntry.business_cat_code, new { @class = "floating-label" }) @Html.EditorFor(model => model.NewEditEntry.business_cat_code, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.NewEditEntry.business_cat_code, "", new { @class = "text-danger" }) </div> </div> </div> <div class="row"> <div class="col-md-11"> <div class="form-group fill"> @Html.LabelFor(model => model.NewEditEntry.description, new { @class = "floating-label" }) @Html.EditorFor(model => model.NewEditEntry.description, "Text", new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.NewEditEntry.description, "", new { @class = "text-danger" }) </div> </div> </div> </div> <div class="modal-footer"> <button type="submit" class="btn btn-primary" id="btnSaveAdd">Save</button> <button type="button" class="btn btn-secondary has-ripple" data-dismiss="modal">Close<span class="ripple ripple-animate" style="height: 74.9625px; width: 74.9625px; animation-duration: 0.7s; animation-timing-function: linear; background: rgb(255, 255, 255); opacity: 0.4; top: -26.3813px; left: -14.7937px;"></span></button> </div> </div> </div> </div> @*popup window*@ <div class="row"> <div class="col-md-12"> <div id="subCategoryPart"> <div class="table-responsive"> @Html.Partial("BusinessCategory/SubBusinessCategoryView", Model) </div> </div> </div> </div> </div> }
This part is ok, the problem is when i include/add Html.BeginForm outside Ajax.BeginForm, the add button of modal window triggers the Html.BeginForm instead of the Ajax.BeginForm.
What is the best approach to handle collections (parent-child entries) then perform a final submit using Html.BeginForm and Ajax.BeginForm? Is there a similar code snippet to cater parent-child entries?