I have an MVC5 application that I am just starting to do with Ajax. I have a page with a button that, when clicked, opens the Bootstrap module with a form from another action. However, when this modal form is submitted, the unobtrusive jquery validation is not called, and the page is redirected to a partial view on a blank page, and not inside the modal dialog.
So, 1: How can I get jQuery validation to work inside the modal, and 2: How can I make the form not refresh the page, but reload the returned view to modal? and 3: I'm confused about how Ajax.BeginForm should work, as I assume that it did not create the page refresh.
Here is the page containing the button for loading the modal:
@using Plus.ViewModels @model UserViewModel @{ ViewBag.Title = "Personal Details"; } @using (Html.BeginForm(null, null, FormMethod.Post, new { @class = "form-horizontal" })) { @Html.AntiForgeryToken() // A separate form here <div class="form-actions"> <button class="btn btn-primary" type="submit"> <i class="fa fa-save"></i> Save </button> | <a class="btn btn-primary" href="@Url.Action("ChangePassword", "Manage", new object{})" data-toggle="modal" data-target="#myModal">Change Password</a> </div> } <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false"> <div class="modal-dialog"> <div class="modal-content"> </div> </div> </div> @section Scripts { <script type="text/javascript"> $('#myModal').on('shown.bs.modal', function () { jQuery.validator.unobtrusive.parse($(this)); }) </script> }
The view containing the form I want to submit inside the modal dialog:
@model Plus.ViewModels.ChangePasswordViewModel @{ ViewBag.Title = "Change Password"; Layout = ""; AjaxOptions options = new AjaxOptions(); options.HttpMethod = "POST"; options.Url = Url.Action("ChangePassword", "Manage"); options.UpdateTargetId = "modalForm"; options.InsertionMode = InsertionMode.Replace; } @using (Ajax.BeginForm("ChangePassword", "Manage", null, options, new { @class = "form-horizontal", role = "form" })) { <div id="modalForm"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">Change Password</h4> </div> <div class="modal-body"> @Html.AntiForgeryToken() @Html.ValidationSummary("", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-6 control-label" }) <div class="col-md-6"> @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-6 control-label" }) <div class="col-md-6"> @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-6 control-label" }) <div class="col-md-6"> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Change Password</button> </div> </div> }
Controller for action:
public ActionResult ChangePassword() { ChangePasswordViewModel cpvm = new ChangePasswordViewModel(); return PartialView(cpvm); } // // POST: /Manage/ChangePassword [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model) { if (!ModelState.IsValid) { return PartialView(model); } var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); if (result.Succeeded) { return Json(new { success = true }); } // Failed AddErrors(result); return PartialView(model); }