Hopeless Coder
Hopeless Coder

Reputation: 17

Checking multiple functions are true in Javascript before submission

I have been working on improving my javascript validation and with the help off the internet (including stackoverflow) have been able to create what I need. The only problem I have is checking multiple functions = true doesn't seem to work. It's been driving me crazy and I hope someone can help.

What I'm trying to do is check that the username and email are within the set variables and if the username and email haven't been used. The availability off the username and email shows whether it's available or not whilst you are typing. Which works great, the only problem is that if the user clicks register when they one or more are not available the form still gets submitted. To overcome this I thought off using an if statement that checks if multiple functions are true, if so pass the details to the php script if not the show an alert message.

For some reason it keeps bringing up the 'not available' alert message even if the username and email are showing as available on the form. I have checked the database table and the php code is working correctly.

Here is the code below

html:

  <form name="regForm" role="form" action="php/registerphp.php" method ="post" 
  onsubmit="return RegFormValidation();">


  <fieldset>
  <div class="form-group">
    <label for="username">Username</label><span>*</span><span> </span><span id="username_availability_result"></span>
    <input type="username" class="form-control" id="username" 
    placeholder=" Enter a username" name="username">

  </div>
  <div class="form-group">
    <label for="email">Email address</label><span>*</span><span> </span><span id="email_availability_result"></span>
    <input type="email" class="form-control" id="email" 
    placeholder=" Enter email" name="email">
  </div>

Javascript

function RegFormValidation()
{  
    if(check_username_availability() && check_email()) {
        return true;
    } else 
    {
        alert("Username or Email not correct.");
        return false;               
    }
}



$(document).ready(function username_correct_format() 
{  


        var min_chars = 3;  
        var characterReg = /^\s*[a-zA-Z0-9,\s]+\s*$/; 
        var characters_error = ' - Min. characters required is 3, only use letters and numbers.';  
        var checking_html = 'Checking...';  


        $('#username').keyup(function()
        {  

            if($('#username').val().length > min_chars || characterReg.test($('#username').val()))
            {  
                //else show the checking_text and run the function to check  
                $('#username_availability_result').html(checking_html);  
                check_username_availability(); 

            }else
            {  

                //if it's bellow the minimum show characters_error text '  
                $('#username_availability_result').html(characters_error);  
            }


        });  

});  

//function to check username availability  
function check_username_availability()
{  


        var username = $('#username').val();  


        $.post("php/check_username.php", { username: username },  
            function(result)
            {  

                if(result == 1)
                {  

                //show that the username is available  
                $('#username_availability_result').html('<span class="is_available"> is available</span>');                    
                return true;
                }else
                {  
                //show that the username is NOT available  
                $('#username_availability_result').html('<span class="is_not_available"> is not available</span>');
                return false;
                }  
        });    
} 



$(document).ready(function email_correct_format() 
{  


        var min_chars = 4; 
        var characters_check = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        var characters_error = ' - only 1 email address per user.';  
        var checking_html = 'Checking...';  


        $('#email').keyup(function()
        {  


            if($('#email').val().length > min_chars && characters_check.test($('#email').val()))
            {
                //else show the cheking_text and run the function to check  
                $('#email_availability_result').html(checking_html);  
                check_email();    

            }else
            {  
                //if it's bellow the minimum show characters_error text '  
                $('#email_availability_result').html(characters_error); 

            }  
        });  

});  

//function to check email availability  
function check_email()
{  


        var email = $('#email').val();  

        $.post("php/check_email.php", { email: email },  
            function(result)
            {  

                if(result == 1)
                {  

                    //show that the email is available      
                    $('#email_availability_result').html('is available '); 
                    return true;
                }else
                {  
                    //show that the email is NOT available  
                    $('#email_availability_result').html('<span class="is_not_available"> is already registered.</span>'); 
                    return false;
                }  
            });  

} 

Upvotes: 1

Views: 1535

Answers (5)

Squiggs.
Squiggs.

Reputation: 4474

A couple of things you could do to improve your code.

You probably don't have to make two separate requests, pass the username and email direct to your php code, and you'll save on HTTP requests going out.

onsubmit="return RegFormValidation();" should be changed in jQuery to a bind call. Give the form an ID and do something like this

<form id="registerForm">....

$("form#registerForm").on('submit', function(e){

});

You've got var username = $('#username').val();

then

 if($('#username').val().length > min_chars || characterReg.test($('#username').val()))
            {  

You could probably clean that up a bit and reuse the variable, rather than continued calls to the jQuery functions. Patrick's answer above is a good start to some tidy ups and I reckon addresses the overall problem you are experiencing.

Upvotes: 0

Patrick Evans
Patrick Evans

Reputation: 42746

Because your checks are done using asynchronous methods your check methods are going to return before the requests have been made, your functions also do not return anything anyways. Thus each one is going to be returning undefiend

You can use jQuery's .when method to wait for one or more requests to be completed and then execute some function.

First thing that will need done is pass the event object and the form object to the validation function. We will need the event object to call preventDefault so that the form will not submit before it is supposed to.

Then we need to change the validation function around so that it will call the two check functions and setup a promise to call a callback when they are complete.

We will also need to change your to check functions to return the promise object that the .post method returns so that the .when method can use them.

After that you just do your checks against the returned data and process.

HTML

<form name="regForm" role="form" action="php/registerphp.php" method ="post" 
  onsubmit="return RegFormValidation(event,this);">

Javascript

function RegFormValidation(e,form) {  
    //Prevent the form submission
    e.preventDefault();
    //Each check function returns a promise object
    jQuery.when(check_username_availability(),check_email())
       .done(function(usernameResponse,emailResponse){
           //the responses passed back to the callback will be in an array
           //element 0 is the actual data retrieved
           //element 1 is the status (success, error, etc)
           //element 2 is the promise object

           if(usernameResponse[0] == 1 && emailResponse[0] == 1){
               //if everything is ok manually submit the form
               form.submit();
           } else {
               alert("Username or Email not correct.");
           }
     });
}

function check_username_availability() {  
    var username = $('#username').val();  
    return $.post("php/check_username.php", { username: username })
        .then(function(data){
           if(data == 1) {
              $('#username_availability_result').html('<span class="is_available"> is available</span>');                    
           } else {  
              $('#username_availability_result').html('<span class="is_not_available"> is not available</span>');
           }
           //We have to return the data here to make sure it gets passed
           //to the done callback from the validation function
           return data;
        });
} 
function check_email() {  
    var email = $('#email').val();  
    return $.post("php/check_email.php", { email: email })
        .then(function(data){
           if(data == 1) {
              $('#email_availability_result').html('<span class="is_available"> is available</span>');                    
           } else {  
              $('#email_availability_result').html('<span class="is_not_available"> is not available</span>');
           }
           //We have to return the data here to make sure it gets passed
           //to the done callback from the validation function
           return data;
        });
} 

You can look at jQuery's api section Deferred Objects to learn more about their deferred/promises. You can also look at other promise libraries like Q and see how they work, as they tend to work on the same principles and use similar method names.

Upvotes: 1

Jack
Jack

Reputation: 9388

It looks like you're making ajax calls for your validation. My guess is these are asynchronous calls (which won't work with your code).

My guess (sorry, I don't have time to test) is your functions check_username_availability and check_email will immediately return "undefined", which is why your validation is always throwing the alert.

Instead, what you'd want to do is make synchronous calls, or use callbacks to invoke the necessary functions.

Upvotes: 0

Phil Tune
Phil Tune

Reputation: 3373

To do multiple boolean checks, I would create a global variable (eg, allValid) immediately set to your control value (true or false)... then on each validation function, change the variable ONLY if something is invalid, so:

var allValid = true;
if(!/*validation requirement*/) { allValid = false; }
allValid = anotherValidationFunction() || false;

if(!allValid) { /*something's invalid*/ }

I don't know if that makes sense.

Upvotes: 0

Dynamic Remo
Dynamic Remo

Reputation: 531

You dont have to wrap functions in

 $(document).ready();

this will change the scope of function calling/referencing and is not a good practice. As this might help you out in resolving the return value from the function. All the Best!

Upvotes: 1

Related Questions