Jason James Jason James - 3 months ago 7
Ajax Question

Cancel MVC Form submit

I am submitting a form using AJAX. The fields are in a partial view that get sent to a controller action. The partial view is in a div that pops up when a button on the main form is clicked. If the user completes the form and clicks the submit button it then the update is performed in the controller action and all is well. However, if the user changes their mind I like to add a cancel button to hide the form. Adding the button and hiding the form works as expected, but the call to the controller action method still occurs. I've tried using

e.preventDefault();


but this hasn't worked.

I've tried using a second JQuery method attached to the cancel id but I can't get this to work.

My JQuery looks like this:

$('#VisitorModal').on('submit', '#visitorform', function (e) {
var data = $(this).serialize();
var url = '@Url.Action("CreateVisitor", "Meetings")';
var text = $('#title').val() + ' ' + $('#firstname').val() + ' ' + $('#surname').val() + ' (' + $('#company').val() + ')'; // a value from the form that you want as the option text
$.post(url, data, function (response) {
if (response) {
$('#VisitorID').append($('<option></option>').val(response).text(text)).val(response);
} else {
dialog.hide();
}
}).fail(function () {
dialog.hide();
});
dialog.hide();
e.preventDefault();
//return false; // cancel the default submit
});

$('#cancel').on('click', function () {
dialog.hide();
});


And here's my action method:

[HttpPost]
public JsonResult CreateVisitor(AppointmentViewModel model)
{
var visitor = new Visitor()
{
Title = model.VisitorTitle,
FirstName = model.VisitorFirstName,
LastName = model.VisitorSurname,
Company = model.VisitorCompany
};
db.Visitors.Add(visitor);
db.SaveChanges();
return Json(visitor.id);
}


And submit & cancel buttons here:

<div class="form-group">
<div class="col-md-offset-2 col-md-5">
<input type="submit" value="Create" class="btn btn-success" id="submit" />
<input type="button" value="Cancel" class="btn btn-warning" id="cancel" />
</div>
</div>


Does anyone have any suggestions that might get this to work as I hope?

Answer

Since your form is being loaded dynamically after the initial page has been rendered, you need to use event delegation by using .on() to add a listener to an ancestor that exists when the page is rendered

Instead of

$('#cancel').on('click', function () {
    dialog.hide();
});

use

$(document).on('click', '#cancel', function () {
    dialog.hide();
});

but replace document with the closest ancestor that exists when the page is first generated.