How to in ASP.NET MVC prevent jquery ajax submit if validation fails

dfmetro picture dfmetro · Feb 12, 2016 · Viewed 15.5k times · Source

I am using ASP.NET 5 MVC RC1

The jquery validation plugins that my ASP.NET MVC uses is the standard jquery.validate.js that a default ASP.NET 5 template project uses.

 /*!
 * jQuery Validation Plugin v1.14.0
 *
 * http://jqueryvalidation.org/
 *
 * Copyright (c) 2015 Jörn Zaefferer
 * Released under the MIT license
 */

and jquery.validation.unobtrusive.js

/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/

I provide a simple Required field example below to demonstrate my problem.

ViewModel:

public class TierImportStatusUpdateViewModel
{
    [Required]
    public string String1 { get; set; }
    [Required]
    public string String2 { get; set; }
    //more fields
}

cshtml:

@model  MyViewModel
<form action="/controller/action" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#dic1" id="form1" method="post" class="allforms">
    @Html.LabelFor(model=>model.String1)
    @Html.EditorFor(model=>model.String1)
    @Html.ValidationMessageFor(model=>model.String1)
   <br>
    @Html.LabelFor(model=>model.String2)
    @Html.EditorFor(model=>model.String2)
    @Html.ValidationMessageFor(model=>model.String2)
    <br>
    <button type="submit" class="btn btn-primary" id="submit" name="submit">submit</button>
</form>

The above validation works correctly. If String1 is not captured in the form the POST method is NOT called and error message is showed on the client side.

I then use the following jquery as I'd like to catch all form submits and do some additional logic:

   $(".allforms").submit(function (e) {

        e.preventDefault();

        var self = this;
        $.ajax({
            processData: false,
            contentType: false,
            data: new FormData(this),
            type: $(this).attr('method'),
            url: $(this).attr('action'),
            success: function (data) {
                //other logic
            }
        });

        return (false);
    });

This jquery function works and call my controller method when the button is clicked. However when String1 is not captured and submit is clicked, the validation kicks in and shows the error message but the jquery function still POSTS the form.

How do I prevent the jquery function to not call the ajax method if the existing validation fields failed?

There is no need for me to do my own validation as the validation message is being shown on screen. I just need to prevent the submit

The only thing I could find in my form is the individual validation fields e.g

 <span class="text-danger field-validation-valid" data-valmsg-for="String1" data-valmsg-replace="true"></span>

and the form only has the novalidate=novalidate tag which the jquery.validate.js adds to all forms it is enabled on.

Answer

JotaBe picture JotaBe · Feb 12, 2016

You need to conditionally make the ajax call only if the form is valid, which can be done with this javascript code:

if ($("#form1").valid()) {
    // make the ajax call
}

The documentation is here: .valid().

Please, verify that the form's id in the generated page is indeed form1. If not, there are alternative selectors that you can use, or ways to get the id which will be generated by the Razor code.

NOTE: as I reread your code I can see you're using a single handler for all forms. In that case you must call the .valid() method in the form that triggered the event, which sill be available trhough $(this). I.e, do $(this).valid() to check if the form is valid.