0

My site is http://www.extrabux.com/users/login

When a user is logging in, Jquery Validate plugin uses a "remote" function to check whether the provided email address exists in our database as a user. If the connection and our server is fast, the user sees feedback before she even finishes typing her password.

email: { 
    required: true, 
    email: true, 
    remote: {//http://docs.jquery.com/Plugins/Validation/Methods/remote
        url: 'check-signin-email-address',
            type: "post",
            data: {
                emailAddress: function() {
                    return $("#email").val();
                }
            }
        }
} 

If the connection or our server is slow, however, this causes an undesirable delay before the form can be submitted (because the Jquery Validate plugin waits until the form is confirmed to be valid).

What I'd like is:

  • If the remote query finishes before the user submits the form, it should block the submission (in the case where it finds that the email address is not in the database).
  • If the user submits the form before the remote query finishes, the remote query validation rule should be ignored (so that there is no delay--the server-side validation will catch that the user doesn't exist).

Thoughts?

Ryan
  • 22,332
  • 31
  • 176
  • 357
  • Do you use jquery ajax function to check email in db? – Scott Selby Nov 27 '12 at 18:51
  • This might help: http://stackoverflow.com/questions/446594/abort-ajax-requests-using-jquery – greener Nov 27 '12 at 18:58
  • I use the code I showed above. It posts the string email address to www.extrabux.com/users/check-signin-email-address and receives a json true/false result. See http://docs.jquery.com/Plugins/Validation/Methods/remote. Thanks! – Ryan Nov 27 '12 at 18:59

2 Answers2

0
 function checkEmail(){  
   $("#email").removeClass('email'); // this stops validation during ajax
   //might want to add a loading image to let user know 
     $.ajax({
       type: //type
       url: //url to check email,
       data: //email to check,
       success: function (msg) {
           $("#email").addClass('email'); //turns validation back on
               //take away loading image

            if (msg.GoodEmail != "GoodEmail" ) { //however you check for existing email
              $("#email").addClass('error'); //forces failed validation
               }
         }
      });
 }

This is an example using jquery's ajax , with this you can handle events before ajax , on success , on error , a little more control this way

Scott Selby
  • 9,420
  • 12
  • 57
  • 96
  • Thanks but I think that will disable all validation rather than just that one type. E.g. it will disable the password min length validation and the validation that requires that the string provided in the email address field looks like a valid email address. – Ryan Nov 27 '12 at 19:05
  • edited answer, now it will only stop validating the email input – Scott Selby Nov 27 '12 at 19:07
0

I think I figured this out. Instead of using the "remote" option, I used addMethod to create a rule that I call "isExtrabuxMember". I also created some global variables and used ajax bound to the change of the #email field to check whether the provided email address belonged to any existing Extrabux member.

Please comment if this helps you or if you have better ideas.

I now have this above the "validate" plugin call:

jQuery.validator.addMethod("isExtrabuxMember", function(value, element) {
    var emailRemoteFuncResult = checkSigninEmailAddressResult === null ? true : checkSigninEmailAddressResult;
    return emailRemoteFuncResult;
});

var checkSigninEmailAddressResult = null;
var emailXhrCheck;
$('#email').bind('change keyup', function(){
    checkSigninEmailAddressResult = null;
    if(emailXhrCheck){
        emailXhrCheck.abort();
    }
    emailXhrCheck = $.ajax({
        url: '/users/check-signin-email-address',
        type: "post",
        async: true,
        data: {
            emailAddress: function() {
                return $("#email").val();
            }
        },
        success: function(data){
            checkSigninEmailAddressResult = data;
            $("#email").valid();
        }
    });
});
$('#loginForm').submit(function(){
    if(emailXhrCheck){
        emailXhrCheck.abort();
    }
});           

Then within the "validate" plugin call:

rules: {              
    email: { 
        required: true, 
        email: true, 
        isExtrabuxMember: true                     
    }, 
    password: { 
        required: true, 
        minlength: 4 
    }      
}, 
messages: {
    email: {
        isExtrabuxMember: function(){
            var currentEmail = $('#email').val();
            return $.validator.format('<b>{0}<\/b> does not yet have an Extrabux account. <a href="\/users\/register?emailAddress={0}">Sign up?<\/a>', currentEmail);
        }
    },
    password: { 
        required: "Oops, you forgot to enter your password!"
    }                    
} 
Ryan
  • 22,332
  • 31
  • 176
  • 357