I have recently created a table (Datatables) that relies on a popup window to add entries to it. When you add an item the first time, the modal closes and the table refreshes itself and you can see the new entry. The issue starts when you go and try to add another item to it after the first. Instead of submitting and repeating the early behaviour, it redirects the page to a json output of the html of the modal.
I'm not too sure why and I have also tried to debug it. The second time, it isn't submitting to the controller at all.
This is the jQuery modal I'm using https://github.com/kylefox/jquery-modal
Here is my ajax query to open up a modal with a form
$("#addRole").click(function (e) {
var form_data = {
"Id": "@Model.Id",
};
$.ajax({
url: "@Url.Action("NewRole", @ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: JSON.stringify(form_data),
contentType: "application/json",
success: function (result) {
$(result.Output).appendTo('body').modal();
},
error: function (error) {
console.log(error);
}
});
return false;
});
This is the div where the form will be attached to
<div id="modal"></div>
The ajax above then goes to this controller function:
[HttpPost]
public ActionResult NewRole(String Id)
{
var role = new RolesDetailsViewModel
{
ApplicationId = Id,
Id = null,
RoleName = null
};
var result = this.Json(new
{
Output = ViewToString.Render(this, "Modal/RoleDetails", role)
}, JsonRequestBehavior.AllowGet);
return result;
}
This controller then returns this modal page
@model ManagementStudio.Data.ViewModels.RolesDetailsViewModel
<div id="roleDetails" class="modal">
<script>
$(document).ready(function () {
$("#form").submit(function (e) {
e.preventDefault();
var form_data = $(this).serialize();
console.log(form_data);
$.ajax({
url: "@Url.Action("SaveRole", @ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: form_data,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (result) {
if (result.success) {
console.log("success");
$("#close").trigger("click");
return;
}
$.each(result.errors, function (index, item) {
// Get message placeholder
var element = $('[data-valmsg-for="' + item.propertyName + '"]');
// Update message
element.append($('<span></span>').text(item.errorMessage));
// Update class names
element.removeClass('field-validation-valid').addClass('field-validation-error');
$('#' + item.propertyName).removeClass('valid').addClass('input-validation-error');
});
}
});
return false;
});
});
</script>
<div class="col-sm-12">
@if (Model.Id == null)
{
<h2>Add Role</h2>
}
else
{
<h2>Edit Role</h2>
}
<hr />
</div>
@using (Html.BeginForm(null,null,FormMethod.Post,new { id="form"}))
{
@Html.AntiForgeryToken()
<div class="col-sm-12">
<div class="form-group">
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.ApplicationId)
</div>
<div class="form-group">
@Html.LabelFor(m => m.RoleName)
@Html.TextBoxFor(m => m.RoleName, new { @class = "form-control col-sm-12" })
@Html.ValidationMessageFor(m => m.RoleName)
</div>
<div class="form-group">
<div class="clearfix">
<input type="submit" id="save" value="Save" class="btn btn-primary pull-right"/>
<a href="#" id="close" class="btn btn-default pull-right" rel="modal:close">Cancel</a>
</div>
</div>
</div>
}
</div>
When I submit the form located on this page, it goes to this controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveRole(SaveRolesDetailsViewModel Input)
{
if (ModelState.IsValid)
{
var result = rolesData.Save(Input);
if(result == false)
{
ModelState.AddModelError("RoleName", "Role Name already exists");
var errors = AjaxError.Render(this);
return Json(new { success = false, errors });
}
return Json(new { success = true });
}
else
{
var errors = AjaxError.Render(this);
return Json(new { success = false, errors });
}
}
But the second time I submit the form(without refreshing the page), it doesn't even hit the SaveRole function at all. It just outputs this
{"Output":"\u003cdiv id=\"roleDetails\" class=\"modal\"\u003e\r\n \u003cscript\u003e\r\n $(document).ready(function () {\r\n $(\"#form\").submit(function (e) {\r\n e.preventDefault();\r\n var form_data = $(this).serialize();\r\n console.log(form_data);\r\n $.ajax({\r\n url: \"/Applications/SaveRole\",\r\n method: \"POST\",\r\n data: form_data,\r\n contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\r\n success: function (result) {\r\n if (result.success) {\r\n console.log(\"success\");\r\n $(\"#close\").trigger(\"click\");\r\n return;\r\n }\r\n $.each(result.errors, function (index, item) {\r\n // Get message placeholder\r\n var element = $(\u0027[data-valmsg-for=\"\u0027 + item.propertyName + \u0027\"]\u0027);\r\n // Update message\r\n element.append($(\u0027\u003cspan\u003e\u003c/span\u003e\u0027).text(item.errorMessage));\r\n // Update class names\r\n element.removeClass(\u0027field-validation-valid\u0027).addClass(\u0027field-validation-error\u0027);\r\n $(\u0027#\u0027 + item.propertyName).removeClass(\u0027valid\u0027).addClass(\u0027input-validation-error\u0027);\r\n });\r\n }\r\n });\r\n return false;\r\n });\r\n });\r\n \u003c/script\u003e\r\n \u003cdiv class=\"col-sm-12\"\u003e\r\n \u003ch2\u003eAdd Role\u003c/h2\u003e\r\n \u003chr /\u003e\r\n \u003c/div\u003e\r\n\u003cform action=\"/Applications/NewRole\" id=\"form\" method=\"post\"\u003e\u003cinput name=\"__RequestVerificationToken\" type=\"hidden\" value=\"rKsqdcNvYkjKMs1eGaghb3BTS6ahAK8_1uy3uJ1kKYCewlQN81FMbyMjcxXHjMULnRux5gOkCPjA-C74H2HGeQ7QU29P_EXvlk9HKpAGwAF5U8l6JB25MiJlHZjbb3jLJnvO9hxkopbxEgZDHEc50w2\" /\u003e \u003cdiv class=\"col-sm-12\"\u003e\r\n \u003cdiv class=\"form-group\"\u003e\r\n \u003cinput id=\"Id\" name=\"Id\" type=\"hidden\" value=\"e201adb7-ae20-4ad0-9589-69e9bd903e81\" /\u003e\r\n \u003cinput id=\"ApplicationId\" name=\"ApplicationId\" type=\"hidden\" value=\"e201adb7-ae20-4ad0-9589-69e9bd903e81\" /\u003e\r\n \u003c/div\u003e\r\n \u003cdiv class=\"form-group\"\u003e\r\n \u003clabel for=\"RoleName\"\u003eRoleName\u003c/label\u003e\r\n \u003cinput class=\"form-control col-sm-12\" id=\"RoleName\" name=\"RoleName\" type=\"text\" value=\"\" /\u003e\r\n \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"RoleName\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\r\n \u003c/div\u003e\r\n \u003cdiv class=\"form-group\"\u003e\r\n \u003cdiv class=\"clearfix\"\u003e\r\n \u003cinput type=\"submit\" id=\"save\" value=\"Save\" class=\"btn btn-primary pull-right\"/\u003e\r\n \u003ca href=\"#\" id=\"close\" class=\"btn btn-default pull-right\" rel=\"modal:close\"\u003eCancel\u003c/a\u003e\r\n \u003c/div\u003e\r\n \u003c/div\u003e\r\n \u003c/div\u003e\r\n\u003c/form\u003e\u003c/div\u003e\r\n"}
This is actually the returned code for an empty modal window. I'm not sure what I can do already.