简体   繁体   中英

Preventing Double Submit on Form

I'm at my wits end with trying to get this form to work right. Basically, when ever you hit submit on this, it stalls for about 5 seconds before going to a thank you page, and the user usually thinks they didn't click right and tries hitting submit at lest 3 more times. I end up with 4 submissions after this when i just want one. I know this question has been asked a lot, but none of the solutions i find seem to work since this "form" doesn't seem to have a form tag in it, just inputs.

This landing page is the work of a previous web designer who I'm assuming just used a template from god knows where and I have been tasked with getting it to work right with my very limited knowledge/experience. I like the way it looks and functions, but there's the aforementioned issue.

Here's the HTML:

<div class="col-sm-4" id="join-us-form">
    <div class="form-bg">
      <div class="form-arrow"></div>
      <h3>title</h3>
      <div id="join-us-results"></div>
      <!-- Form -->
      <form method="POST" action="join_us.php">
        <div class="form-group">
          <input type="text" name="first_name" id="first_name" class="form-control f-input input-field" placeholder="First Name" />
        </div>
        <div class="form-group">
          <input type="text" name="last_name" id="last_name" class="form-control f-input input-field" placeholder="Last Name" />
        </div>
        <div class="form-group">
          <input type="text" name="company" id="company" class="form-control f-input input-field" placeholder="Company" />
        </div>
        <div class="form-group">
          <input type="text" name="email" class="form-control f-input input-field" placeholder="Email" />
        </div>
      <div class="form-group">
          <input type="text" name="phone" maxlength="15"  class="form-control f-input input-field" placeholder="Phone" />
        </div>
        <input type="submit" class="submit-btn" value="Submit" id="submit_btn" onsubmit="document.getElementById('submit_btn').disabled=true; document.getElementById('submit_btn').value='Submitting, please wait...';" />
        </form>
    </div>
  </div>

Here's the Javascript:

/* ==========================
   JOIN-US FORM
=============================*/

$('#submit_btn').on('click', function() { 
    var proceed = true;
    //simple validation at client's end
    //loop through each field and we simply change border color to red for invalid fields       
    $("#join-us-form input[required=true]").each(function(){
        $(this).css('border-color',''); 
        if(!$.trim($(this).val())){ //if this field is empty 
            $(this).css('border','solid 1px red'); //change border color to red   
            proceed = false; //set do not proceed flag
        }
        //check invalid email
        var email_reg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; 
        if($(this).attr("type")=="email" && !email_reg.test($.trim($(this).val()))){
            $(this).css('border','solid 1px red'); //change border color to red   
            proceed = false; //set do not proceed flag              
        }
    });
    if(proceed) //everything looks good! proceed...
    {
        //get input field values data to be sent to server
        var post_data = {
            'first_name'    : $('input[name=first_name]').val(),
            'last_name'     : $('input[name=last_name]').val(),             
            'user_email'    : $('input[name=email]').val(), 
            'phone_number'  : $('input[name=phone]').val(), 
            'company'       : $('input[name=company]').val()
        };
        //Ajax post data to server
        $.post('join_us.php', post_data, function(response){ 
            if(response.type == 'error'){ //load json data from server and output message     
                var output = '<div class="error">'+response.text+'</div>';
            }else{
                window.location.href = "http://url.com/landing/thank-you.html";
                //output = '<div class="success">'+response.text+'</div>';
                //reset values in all input fields
                $("#join-us-form  input[required=true]").val(''); 
            }
            $("#join-us-results").hide().html(output).slideDown();
        }, 'json');
    }
});

And here's the PHP:

<?php
if($_POST)
{
$to_email       = "lead@url.com"; //Recipient email, Replace with your own email.

//check if its an ajax request, exit if not
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {

    $output = json_encode(array( //create JSON data
        'type'=>'error', 
        'text' => 'Sorry Request must be Ajax POST'
    ));
    die($output); //exit script outputting json data
} 

//Sanitize input data using PHP filter_var().
$first_name     = filter_var($_POST["first_name"], FILTER_SANITIZE_STRING);
$last_name      = filter_var($_POST["last_name"], FILTER_SANITIZE_STRING);
$user_email     = filter_var($_POST["user_email"], FILTER_SANITIZE_EMAIL);
$phone_number   = filter_var($_POST["phone_number"], FILTER_SANITIZE_NUMBER_INT);
$company        = filter_var($_POST["company"], FILTER_SANITIZE_STRING);
$subject        = "Lead / url.com";

//additional php validation
if(strlen($first_name)<4){ // If length is less than 4 it will output JSON error.
    $output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
    die($output);
}
if(strlen($last_name)<4){ // If length is less than 4 it will output JSON error.
    $output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
    die($output);
}
if(strlen($company)<3){ //check emtpy company
    $output = json_encode(array('type'=>'error', 'text' => 'Please enter a Company Name.'));
    die($output);
}
if(!filter_var($user_email, FILTER_VALIDATE_EMAIL)){ //email validation
    $output = json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!'));
    die($output);
}
if(!filter_var($phone_number, FILTER_SANITIZE_NUMBER_FLOAT)){ //check for valid numbers in phone number field
    $output = json_encode(array('type'=>'error', 'text' => 'Enter only digits in phone number'));
    die($output);
}

//email body
$message_body = "From : ".$first_name."\r\nEmail : ".$user_email."\r\nPhone Number : (".$phone_number.")". $phone_number."\r\nCompany: ".$company ;

//proceed with PHP email.
$headers = 'From: '.$first_name.'' . "\r\n" .
'Reply-To: '.$user_email.'' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

$send_mail = mail($to_email, $subject, $message_body, $headers);
//header('Location: thank-you.html');

if(!$send_mail)
{
    //If mail couldn't be sent output error. Check your PHP email configuration (if it ever happens)
    $output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
    die($output);
}else{
    $output = json_encode(array('type'=>'message', 'text' => 'Hi '.$first_name .' ! Look to hear from us soon!'));
    die($output);
}

} ?>

The only thing that has sort-of worked was adding a onclick to the submit input that prevented it from being submitted again, but if the validation failed then it would get stuck and the user couldn't submit it without refreshing the page.

I'm new to all this, so help and patience would be greatly appreciated.

Thanks in advance.

Hi just disable your submit button when form is submitted

$("form").submit(function() {
    $(this).find('input[type="submit"]').prop("disabled", true);
})

As you said, you can enable and disable button according to user action and response from your service.

You can change your request section like that;

if(proceed) //everything looks good! proceed...
    {

        $('#submit_btn').prop('disabled', true);
        /* Disable button on request start */

        //get input field values data to be sent to server
        var post_data = {
            'first_name'    : $('input[name=first_name]').val(),
            'last_name'     : $('input[name=last_name]').val(),             
            'user_email'    : $('input[name=email]').val(), 
            'phone_number'  : $('input[name=phone]').val(), 
            'company'       : $('input[name=company]').val()
        };
        //Ajax post data to server
        $.post('join_us.php', post_data, function(response){ 
            if(response.type == 'error'){ //load json data from server and output message     
                var output = '<div class="error">'+response.text+'</div>';
            }else{
                window.location.href = "http://url.com/landing/thank-you.html";
                //output = '<div class="success">'+response.text+'</div>';
                //reset values in all input fields
                $("#join-us-form  input[required=true]").val(''); 
            }

            $('#submit_btn').prop('disabled', false);
            /* Enable button again on request end */

            $("#join-us-results").hide().html(output).slideDown();
        }, 'json');
    }

You can disable your submit button with using ajax

beforeSend: function(msg){
    $(".button").button("disable");
  }

and enable after success.

您可以分配一个变量true,当它为true时,就可以防止重新提交就这么简单。

You can literally add to your JS:

form.myButton.disabled = true;
    return true;

and then within your form tag add:

onsubmit="myButton.disabled

To use myButton you'd need to also add into the form name="myButton" and then wrap an if isset($_POST['myButton'])) { // code }

Dunno, something like setting a disabled prop might work.

jQuery(document).ready(function($) {
    $('#join-us-form').find('form').on('submit', function(e) {
        e.preventDefault();
        if (!$(this).find('input[type="submit"]').prop('disabled')) {
            $.ajax({
                url: '/path/to/foo.php',
                method: 'POST',
                dataType: 'json', // doesn't have to be, just an example
                data: {
                    first_name: $(this).find('#first_name').val(),
                    last_name: $(this).find('#last_name').val(),
                    company: $(this).find('#company').val(),
                    email: $(this).find('#email').val(),
                    phone: $(this).find('#phone').val()
                },
                beforeSend: function() {
                    $(this).find('input[type="submit"]').prop('disabled', true);
                },
                success: function(response) {
                    if (typeof response.error !== 'undefined') { // assuming you're returning something like this
                        console.log('It works!');
                    }
                    else console.log('Houston, we have a problem ...');
                },
                error: function () {
                    console.log('oops!');
                },
                complete: function() {
                    $(this).find('input[type="submit"]').prop('disabled', false);
                }
            });
        }
    });
});

First of all, don't trust the user. When using JavaScript as your only safeguard, you're trusting the user.

That being said: Your onsubmit function doesn't return false , so the form get's submitted the standard html way, even if all the safeguards fail. See Prevent form redirect OR refresh on submit? and https://stackoverflow.com/a/38491643/4275413

After you have fixed that, you can probably disable the button and stuff after ajax.call it (which is asynchronous so do it outside the "success" stuff, but only when proceeding). Your javascript - I believe - overwrites the onsubmit in html on the element. So that's another one.

Maybe there's more stuff going on, but you should try those two for a start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM