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

16,249

Solution 1

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.

Solution 2

The proper way to use ajax with this plugin is to put the ajax inside of the plugin's submitHandler callback function.

"The right place to submit a form via Ajax after it is validated."

From documentation

Example: Submits the form via Ajax when valid.

$(".selector").validate({
  submitHandler: function(form) {
    $(form).ajaxSubmit();
  }
});

This ensures that if the form is valid then only form is submited.

Solution 3

First dont use e.preventDefault(); it will Prevent a submit button from submitting a form.

In your $(".allforms").submit function first validate your form

like this var frmVlalidation = $('#formId').valid();

if your form is validated properly frmVlalidation value will be true if validation fails it will return false .

by using this variable call ajax.

like this.

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

        var frmVlalidation = $('#formId').valid();

        if (frmVlalidation == true) 
        {
        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);
    });
Share:
16,249
dfmetro
Author by

dfmetro

Updated on July 22, 2022

Comments

  • dfmetro
    dfmetro almost 2 years

    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.