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?