JQuery验证 - 仅在验证完成时提交表单

JQuery验证 - 仅在验证完成时提交表单

问题描述:

I am working on a contact form that uses jquery validate to validate the form to make sure all data entered is correct. Everything is fine expect for when I click the submit button - the validation error messages appear along with a confirmation message saying that the message has been sent. So basically its sending the form although all fields are incomplete.

I only want the form to submit once all fields have been filled out correctly.

I have included my code below...

<script type="text/javascript">

// validate contact form
$(function() {
    $('.contactusform').validate({
        rules: {
            name: {
                required: true
            },
            telno: {
                required: true,
                number: true
            },
            email: {
                required: true,
                email: true
            },
            town: {
                required: true
            },
            device: {
                required: true
            },
            message: {
                required: true
            },
        
        },

        messages: {
            name: {
                required: "Please enter your full name."
            },
            telno: {
                required: "Please enter your phone number."
            },
            email: {
                required: "Please enter your email address."
            },
            town: {
                required: "Please enter your town."
            },
            device: {
                required: "Please select your device."
            },
            message: {
                required: "Please enter your message."
            },
        
        },
    
    })
});
</script>

<script>
$(document).ready(function(){

    $('.contactusform').validate();

    // grab the submits button ID. do not use <input type="submit"> inside the form. Use a button instead outside the form.
    $("#submit2").click(function()
    {
        // grab the forms ID
        $("#message").submit(function(e)
        {
            // add a loading image in place of your returning outcome
            $("#simple-msg").html("Sending...");

            // serialize/combine all submitted fields into an array
            var postData = $(this).serializeArray();

            // set url based of action
            var formURL = $(this).attr("action");

            // set ajax parameters
            $.ajax(
            {
                url : formURL,
                type: "POST",
                data : postData,
                success:function(data, textStatus, jqXHR) 
                {
                    $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');

                },
                error: function(jqXHR, textStatus, errorThrown) 
                {
                    $("#simple-msg").html('<p>Message failed to send. Please try again!</p>');
                }
            });
            e.preventDefault(); //STOP default action
            e.unbind();
        });

        $("#message").submit(); //SUBMIT FORM
    });

});
</script>

Could also someone tell me if it is possible to disable the submit button and clear any data entered into form when submission is successful?

Thanks a lot for all your help in advance.

UPDATED CODE

<script type="text/javascript">
$(document).ready(function () {
    $('.contactusform').validate({
        rules: {
            name: {
                required: true
            },
            telno: {
                required: true,
                number: true
            },
            email: {
                required: true,
                email: true
            },
            town: {
                required: true
            },
            device: {
                required: true
            },
            message: {
                required: true
            }, //<---unnecessary, remove it
        },
        messages: {
            name: {
                required: "Please enter your full name."
            },
            telno: {
                required: "Please enter your phone number."
            },
            email: {
                required: "Please enter your email address."
            },
            town: {
                required: "Please enter your town."
            },
            device: {
                required: "Please select your device."
            },
            message: {
                required: "Please enter your message."
            }, //<---unnecessary, remove it

        },

        //Submit Handler Function
        submitHandler: function (form) {
        // add a loading image in place of your returning outcome
        $("#simple-msg").html("Sending...");
        // serialize/combine all submitted fields into an array
        var postData = $(this).serializeArray();
        // set url based of action
        var formURL = $(this).attr("action");
        $.ajax({
                type: "POST",
                url: formURL,
                data: postData,
                success:function(data, textStatus, jqXHR) {
                   $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');
                },
                error: function(jqXHR, textStatus, errorThrown) {
                   $("#simple-msg").html('<p>Message failed to send. Please try again!</p>');
                }
            });
        }
    }); //<----missing ; in original code
});
</script>

CODE FOR FORM

<form name='message' id='message' class="contactusform" enctype="multipart/form-data" action="<?=admin_url()?>admin-post.php">

<?php
 if(isset($_SESSION['message']))
 {
 echo $_SESSION['message'];
 unset($_SESSION['message']);
 }
 ?>
    <input type="hidden" name="action" value="add_foobar">
    <input type="hidden" name="data" value="foobarid">
    <label>Full Name:</label>
    <input type="text" name="name" value="" required="">
    <label>Phone Number:</label>
    <input type="text" name="telno" id="telno">
    <label>Email Address:</label>
    <input type="email" name="email" value="" required="">
    <label>Town:</label>
    <input type="text" name="town" value="" required="">
    <label>Device:</label>
    <select name="device" value="" required="">
        <option selected="selected" value=""></option>
        <option value="Not Sure">Not Sure</option>
        <option selected="selected" value=""></option>
        <option value="iPhone 3G">iPhone 3G</option>
        <option value="iPhone 3GS">iPhone 3GS</option>
        <option value="iPhone 4G">iPhone 4G</option>
        <option value="iPhone 4S">iPhone 4S</option>
        <option value="iPhone 5">iPhone 5</option>
        <option value="iPhone 5C">iPhone 5C</option>
        <option value="iPhone 5S">iPhone 5S</option>
        <option value="iPhone 6">iPhone 6</option>
        <option value="iPhone 6 Plus">iPhone 6 Plus</option>
        <option selected="selected" value=""></option>
        <option value="MacBook">MacBook</option>
        <option value="MacBook Pro">MacBook Pro</option>
        <option value="MacBook Air">MacBook Air</option>
        <option selected="selected" value=""></option>
        <option value="iMac">iMac</option>
        <option selected="selected" value=""></option>
        <option value="iPad 1">iPad 1</option>
        <option value="iPad 2">iPad 2</option>
        <option value="iPad 3">iPad 3</option>
        <option value="iPad 4">iPad 4</option>
        <option value="iPad Air">iPad Air</option>
        <option value="iPad Air 2">iPad Air 2</option>
        <option value="iPad Mini 1">iPad Mini 1</option>
        <option value="iPad Mini 2">iPad Mini 2</option>
        <option value="iPad Mini 3">iPad Mini 3</option>
        <option selected="selected" value=""></option>
        <option value="iPod Classic">iPod Classic</option>
        <option value="iPod Mini">iPod Mini</option>
        <option value="iPod Nano">iPod Nano</option>
        <option value="iPod Shuffle">iPod Shuffle</option>
        <option value="iPod Touch">iPod Touch</option>
    </select>
    <label>Message:</label>
    <textarea name="message" cols="30" rows="4" value="" required=""></textarea>
    <input class="submit2" type='submit' id='submit' value='Send Message' />
</form>
<div id='simple-msg'></div>

CODE FOR PLUGIN

<?php

if(!defined('WPINC'))
{
die;
}

// create table at plugin activition
register_activation_hook( __FILE__, 'jms_create_db' );
function jms_create_db() 
{
    global $wpdb;
    $charset_collate = $wpdb->get_charset_collate();
    $table_name=$wpdb->prefix.'contactusform';
    $sql="CREATE TABLE $table_name(
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        time datetime DEFAULT NULL,
        name varchar(50) DEFAULT NULL,
        telno varchar(20) DEFAULT NULL,
        email varchar(75) DEFAULT NULL,
        town varchar(75) DEFAULT NULL,
        device varchar(75) DEFAULT NULL,
        message text,
        UNIQUE KEY id (id)
        ) $charset_collate;";
    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}

//adding plugin to admin menu
add_action('admin_menu', 'jms_menu');
function jms_menu() 
{
 add_menu_page(__('Contact Form','jms'), __('Contact Form','jms'),
     'administrator', 'jms-contact-form', 'jms_settings_page', 'dashicons-email');
    function jms_settings_page() 
     {
        global $wpdb;
        $table_name=$wpdb->prefix.'contactusform';
        $client_msg = $wpdb->get_results( 
            "
            SELECT *
            FROM $table_name
            "
        );
        require_once(plugin_dir_path(__FILE__).'settings-page.php');
     }
     
}

function cf_jms()
{
 ob_start();
 require_once(plugin_dir_path(__FILE__).'form.php');
 return ob_get_clean();
}
add_shortcode( 'jms_contact_form', 'cf_jms' );

//if you want to have both logged in and not logged in users submitting, you have to add both actions!
add_action( 'admin_post_add_foobar', 'jms_admin_add_foobar' );
add_action( 'admin_post_nopriv_add_foobar', 'jms_admin_add_foobar' );
function jms_admin_add_foobar() {
    global $wpdb;
    $data = array(
        'time'  => current_time('mysql'),
        'name'  => sanitize_text_field( $_POST['name']),
        'telno'  => sanitize_text_field( $_POST['telno']),
        'email' => isset( $_POST['email'] ) ? sanitize_email( $_POST['email']) : null,
        'town'  => sanitize_text_field( $_POST['town']),
        'device'  => sanitize_text_field( $_POST['device']),
        'message'   => sanitize_text_field( $_POST['message'])
    );

    $table_name = $wpdb->prefix.'contactusform';
    $headers = array( 'Content-Type: text/html; charset=UTF-8' );
    // send Email for admin
    wp_mail(
        get_option( 'admin_email' ),
        'Instant Qoute/Callback Form',
        'Time : ' . $data['time'] .
        'Name : ' . $data['name'] .
        'Tel No : ' . $data['telno'] .
        'Email : ' . $data['email'] .
        'Town : ' . $data['town'] .
        'Device : ' . $data['device'] .
        'The message: ' . $data['message'],         
        $headers
    );

    if ( $wpdb->insert( $table_name, $data ) ) {
        $_SESSION['message'] = "";
    } else {
        $_SESSION['message'] = "";
    }
    //redirect back to where user was comming
    wp_redirect( $_SERVER['HTTP_REFERER'] );
    //request handlers should die() when they complete their task
}

?>

</div>

@Ahmad Baktash Hayeri answer covers almost all the aspect so purpose of this answer is to to use submitHandler function and when using a plugin why not take advantage of it let it do all the hard work for you.

I suggest totally remove the 2nd script and use submitHandler function and handle your Ajax method and all other request in it.

Check following script, you have unnecessary comma's and missing ;

$(document).ready(function () {
    $('.contactusform').validate({
        rules: {
            name: {
                required: true
            },
            telno: {
                required: true,
                number: true
            },
            email: {
                required: true,
                email: true
            },
            town: {
                required: true
            },
            device: {
                required: true
            },
            message: {
                required: true
            }, //<---unnecessary, remove it
        },
        messages: {
            name: {
                required: "Please enter your full name."
            },
            telno: {
                required: "Please enter your phone number."
            },
            email: {
                required: "Please enter your email address."
            },
            town: {
                required: "Please enter your town."
            },
            device: {
                required: "Please select your device."
            },
            message: {
                required: "Please enter your message."
            }, //<---unnecessary, remove it

        },
        //Submit Handler Function
        submitHandler: function (form) {
        // add a loading image in place of your returning outcome
        $("#simple-msg").html("Sending...");
        // serialize/combine all submitted fields into an array
        var postData = $(this).serializeArray();
        // set url based of action
        var formURL = $(this).attr("action");
        $.ajax({
                type: "POST",
                url: formURL,
                data: postData,
                success:function(data, textStatus, jqXHR) {
                   $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');
                },
                error: function(jqXHR, textStatus, errorThrown) {
                   $("#simple-msg").html('<p>Message failed to send. Please try again!</p>');
                }
            });
        }
    }); //<----missing ; in original code
});

Now last to reset form and disable submit button, no idea why you want to disable the submit button,

following can reset the form and disable the submit button

$(form)[0].reset();
$('#theSubmitButton').attr("disabled", true);

e.g if you want to reset the form and disable button after Ajax success function

success:function(data, textStatus, jqXHR) {
   $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');
   $(form)[0].reset();
   $('#theSubmitButton').attr("disabled", true);
},

What you don't need anymore is 2nd script, e-prevent default and submit function

If button disable after form submission and wants to enable it, you can use following piece of code inside validate plugin, so it will again enable the button once the fields will have all valid values.

onkeyup: function( element, event ) {
   this.checkForm();
    if (this.valid()) { // checks form for validity
        $('#theSubmitButton').attr("disabled", false); //Button enable if all fields valid
    } else {
        $('#theSubmitButton').attr("disabled", true); //button will disbale if any field not valid
    }
},

Edit:

OP added the form later so changes required in HTML

Move <input class="submit2" type='button' id='submit' value='Send Message' /> inside the <form></form> and change type='button' to type='submit'

<form name='message' id='message' class="contactusform" enctype="multipart/form-data" action="<?=admin_url()?>admin-post.php">
<?php
if(isset($_SESSION['message'])){
 echo $_SESSION['message'];
 unset($_SESSION['message']);
 }
?>
     <input type="hidden" name="action" value="add_foobar">
     <input type="hidden" name="data" value="foobarid">
     <label>Full Name:</label>
     <input type="text" name="name" value="" required="">
     <label>Phone Number:</label>
     <input type"=text" name="telno" id="telno">
     <label>Email Address:</label>
     <input type="email" name="email" value="" required="">
     <label>Town:</label>
     <input type"=text" name="town" value="" required="">
     <label>Device:</label>
     <select name="device" value="" required="">
        <option selected="selected" value=""></option>
        <option value="Not Sure">Not Sure</option>
        ....Rest of the option attributes
        <option value="iPod Touch">iPod Touch</option>
    </select>
    <label>Message:</label><textarea name="message" cols="30" rows="4" value="" required=""></textarea>
    <input class="submit2" type='submit' id='submit' value='Send Message' />
</form>
<div id='simple-msg'></div>

Fiddle

before calling ajax, check whether your form is valid or not

update your code with this new code:

if($('.contactusform').valid()){
        $.ajax(
            {
                url : formURL,
                type: "POST",
                data : postData,
                success:function(data, textStatus, jqXHR) 
                {
                    $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');

                },
                error: function(jqXHR, textStatus, errorThrown) 
                {
                    $("#simple-msg").html('<p>Message failed to send. Please try again!</p>');
                }
            });
}

To resolve your problem, take note of the following:

  1. Merge both of your scripts into one, as it is totally pointless to have them in different tags.
  2. Use either the ID or the className of the form, however, the preferable is the ID. [for the answer I'm assuming that .contactusform and #contactusform refer to the same element in the DOM].
  3. The second call to .validate() method is not needed (so has to be removed). [it may override the first call of the .validate() method with the validation rule objects passed in.]
  4. // grab the submits button ID. do not use inside the form. Use a button instead outside the form. $("#submit2").click(function() ...

    -- Why not use a button with type='button' inside the form which will prevent the form from being submitted so that you can perform the AJAX call.

Now to register a handler on the submit event of the form, replace the last part of your code with the following:

$("#contactusform").submit(function(e) //Note the registration of the submit event on the form and NOT a button
    {
        var theForm = this;    // reference to the form that raised the event
        // add a loading image in place of your returning outcome
        $("#simple-msg").html("Sending...");

        // serialize/combine all submitted fields into an array
        var postData = $(this).serializeArray();

        // set url based of action
        var formURL = $(this).attr("action");

        // set ajax parameters
        $.ajax(
        {
            url : formURL,
            type: "POST",
            data : postData,
            success:function(data, textStatus, jqXHR) 
            {
                $("#simple-msg").html('<p>Thanks for your request - we will be in touch soon!</p>');

            },
            error: function(jqXHR, textStatus, errorThrown) 
            {
                $("#simple-msg").html('<p>Message failed to send. Please try again!</p>');
            }
        });
        e.preventDefault(); //STOP default action -- Is ok to be here, although changing the form submission button's type to `button` will do the same trick
        //e.unbind();   // Not necessary
    });

    //$("#message").submit(); //SUBMIT FORM --- No need for this again, not sure if '#message' is a form, but either way, by clicking the form submission button, you'll be triggering the submit event on the form.
});
  1. To reset the form fields .reset() method on the form in the success handler of your AJAX call:

    theForm.reset();
    $('#theSubmitButton').attr('disabled', 'disabled'); // disable form submission when submission successfull.