Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
754 views
in Technique[技术] by (71.8m points)

javascript - Jquery Ajax Form Requires 2 Clicks to submit

i have an html form which which does jquery/ajax validations.

following is the html form...

<div class="box3">
    <form method="post" name="loginform" action="models/login.php">
    <h2>LOGIN<br /><br /> (Post/Manage Property)</h2>
        <input type="email" class="homepage"  name="user_email2" id="user_email2" placeholder="Email" maxlength="50" required />
        <div class ="errormsg" id ="errormsg6"></div>
        <input type="password" class="homepage"  name="user_password2" id="user_password2" placeholder="Password" maxlength="20" required />
        <div class ="errormsg" id ="errormsg7"></div>
        <input type="submit" name="login" id="login" value="Submit">
        <div class ="errormsglast" id ="errormsg8"></div>
        <div class="homeforgotpassword"><a href="forgot-password" class="forgotpasswordlink">Forgot Password</a></div>
    </form>
</div>

the jquery/ajax for validation is as follows

$(document).ready(function()
{
    /* ----------------- Login Validations Global Variables -----------------   */
    var user_email2 = "";
    var user_password2 = "";
    var user_emailajax2 = "";
    var user_mobileajax2 = "";

    var emailformat = new RegExp(/^[+a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/i);

    /* ----------------- Define Validate Email */
    var validate_email_login = function()
        {
            var item5 = $("#user_email2").val();
            var item5 = item5.toLowerCase();

            if (item5.length < 6 || item5.length > 50)
            {
                $("#errormsg6").html("Email : 6 - 50 Characters");
                user_email2 = "";
            }
            else
            {
                $("#errormsg6").html("")
                user_email2 = item5;
                if (!emailformat.test(item5))
                {
                    $("#errormsg6").html("Wrong Email Format")
                    user_email2 = "";
                }
                else
                {
                    $("#errormsg6").html("")
                    user_email2 = item5;
                    $.ajax(
                    {
                        type: 'POST',
                        url: 'classes/validatelogin.php?f=1',
                        data: "user_email2=" + item5,
                        success: function(msg)
                        {
                            if (msg == "exists")
                            {
                                $("#errormsg6").html("");
                                user_emailajax2 = item5;
                            }
                            else if (msg == "ok")
                            {
                                $("#errormsg6").html("Email Does Not Exist");
                                user_emailajax2 = "";
                            }
                        }
                    });
                }
            }
        }

    /* ----------------- Define Validate Password */
    var validate_password_login = function()
        {
            var item5 = $("#user_email2").val();
            var item5 = item5.toLowerCase();

            var item6 = $("#user_password2").val();
            if (item6.length < 8 || item6.length > 20)
            {
                $("#errormsg7").html("Password : 8-20 Characters")
                user_password2 = "";
            }
            else
            {
                $("#errormsg7").html("")
                user_password2 = item6;
                $.ajax(
                {
                    method: "POST",
                    url: "classes/validatelogin.php?f=2",
                    data: "user_email2=" + item5 + "&user_password2=" + item6,
                    success: function(msg)
                    {
                        if (msg == "WrongPw")
                        {
                            $("#errormsg7").html("Wrong Password");
                            user_mobileajax2 = "";
                        }
                        else if (msg == "CorrectPw")
                        {
                            $("#errormsg7").html("");
                            user_mobileajax2 = "item6";
                        }
                    }
                });
            }
        }

    /* ----------------- Run Functions */
    $("#user_email2").on('focusout', validate_email_login);
    $("#user_password2").on('focusout', validate_password_login);
    $("#login").on('click', validate_email_login);
    $("#login").on('click', validate_password_login);

    /* ----------------- Stop on Submit */
    $("#login").click(function()
    {
        if (user_email2 == "" || user_password2 == "" || user_emailajax2 == "" || user_mobileajax2 == "")
        {
            $("#errormsg8").html("Please Fill All Fields (Correctly)")
            return false;
        }
        else
        {
            return true;
        }
    });
});

if there are no errors then the form submits in one click, however if there are errors and these errors are then rectified (as per validation rules) then the submit button requires two clicks to submit.

Have tried the following things

Renaming $("#login").click(function() to $("#login").on( "click", function()

$("#login").trigger("click"); - after return true and before return true

$( "#login" ).click(); - after return true and before return true

<input type="button" name="login" id="login" value="Submit"> - changing the submit to button

I tried this solution (it did not work, result was the same two clicks required... )

$(document).ready(function()
{
    /* ----------------- Login Validations Global Variables -----------------   */
    var user_email2 = "";
    var user_password2 = "";
    var user_mobileajax2 = "";
    var emailformat = new RegExp(/^[+a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/i);
    /* ----------------- Define Validate Password */
    var validate_password_login = function()
    {
        // Set up the deferred object
        var def = $.Deferred();
        var item5 = $("#user_email2").val();
        var item5 = item5.toLowerCase();
        var item6 = $("#user_password2").val();
        if (item6.length < 8 || item6.length > 20)
        {
            $("#errormsg7").html("Password : 8-20 Characters");
            user_password2 = "";
            // Not a valid password so reject the deferred
            def.reject();
        }
        else
        {
            $("#errormsg7").html("");
            user_password2 = item6;
            $.ajax(
                {
                    method: "POST",
                    url: "classes/validatelogin.php?f=2",
                    data: "user_email2=" + item5 + "&user_password2=" + item6
                })
                .done(function(msg)
                {
                    if (msg == "WrongPw")
                    {
                        $("#errormsg7").html("Wrong Password");
                        user_mobileajax2 = "";
                        // The server said the PW was wrong, so reject this
                        def.reject();
                    }
                    else if (msg == "CorrectPw")
                    {
                        $("#errormsg7").html("");
                        user_mobileajax2 = "item6";
                        // Looks like we are valid so we can resolve this
                        def.resolve();
                    }
                })
                .fail(function()
                {
                    // Something went wrong on the server side, so have to reject
                    def.reject();
                });
        }
        // We return the promise
        return def.promise();
    }
    /* ----------------- Run Functions */
    $("#user_password2").on('focusout', validate_password_login);
    // Move to submit handler
    $('form[name="loginform"]').on('submit', function()
    {
        // Set up the validation methods inside $.when
        $.when(validate_password_login())
            .done(function()
            {
                // Done means success!
                return true;
            })
            .fail(function()
            {
                // And fail is obviously a fail.
                return false;
            });
    });
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I didn't fully replicate this with an entire login set up, but I did do a quick fake to test by changing the ajax.success to ajax.error and using a bad url to trigger the error, then inside of the error, I set the msg variable equal to the string that signals a valid response and the form did not require two submits.

That, coupled with giving the code a closer look, I'm going to guess the issue is a sort of race condition due to the ajax calls.

Your click handlers are set up like this:

$("#login").on('click', validate_email_login);
$("#login").on('click', validate_password_login);
$("#login").click(function() { ... });

Inside of that last handler is where the code checks the strings to see if the results are valid. However, by the time it gets to there those previous ajax requests may have not finished loading and those strings probably have not been reset yet. You can add some console.logs in that function to see what those values are and confirm.

Because those ajax calls are asynchronous you are going to have to wait for them to finish before you can check that the form is valid. What you are looking for are Promises and Deferreds.

I would suggest refactoring it into something like this:

  1. Set up a Deferred in both of your validation methods.
  2. Remove the #login click handlers and move everything into a submit handler for the form.
  3. In the submit handler of the form call the validation methods using $.when.

Quick code example:

// Move to submit handler
$('form[name="loginform"]').on('submit', function() {
    // Set up the validation methods inside $.when
    $.when(validate_email_login(), validate_password_login())
     .done(function() {
        // Done means success!
        return true;
     })
     .fail(function() {
        // And fail is obviously a fail.
        return false;
     });
});

In addition to the jQuery docs, at a glance, this looks like another good resource for examples and an explanation of everything: http://jqfundamentals.com/chapter/ajax-deferreds. I think the stuff that is most like what you have is towards the bottom.

A quick set up of what one of the validation methods might look like (untested):

var validate_password_login = function() {
    // Set up the deferred object
    var def = $.Deferred();
    var item5 = $("#user_email2").val();
    var item5 = item5.toLowerCase();
    var item6 = $("#user_password2").val();

    if (item6.length < 8 || item6.length > 20) {
      $("#errormsg7").html("Password : 8-20 Characters");
      user_password2 = "";
      // Not a valid password so reject the deferred
      def.reject();
    } else {
      $("#errormsg7").html("");
      user_password2 = item6;
      $.ajax({
        method: "POST",
        url: "http://www.google.com",
        data: "user_email2=" + item5 + "&user_password2=" + item6
      })
      .done(function(msg) {
          if (msg == "WrongPw") {
            $("#errormsg7").html("Wrong Password");
            user_mobileajax2 = "";
            // The server said the PW was wrong, so reject this
            def.reject();
          } else if (msg == "CorrectPw") {
            $("#errormsg7").html("");
            user_mobileajax2 = "item6";
            // Looks like we are valid so we can resolve this
            def.resolve();
          }
       })
       .fail(function() {
          // Something went wrong on the server side, so have to reject
          def.reject();
        });
    }

    // We return the promise
    return def.promise();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...