2010
07.24

Again another long time between posts, this one is partly a small tutorial and partly about a small issue I encountered and workaround. This post discusses form validation using a cool jQuery form validation plugin created by Jörn Zaefferer, which I highly recommend, you can download the plugin from here. The plugin allows you to quickly and easily validate your html forms using the power of jQuery, the basic principle is that you specify the rules for validation on the fields of your form and submitting the form will be disabled until all fields are valid, where validation rules are broken the user is informed with messages next to the invalid fields. I wouldn’t be surprised if this plugin became part of jQuery directly since so many people are using it already.

Lets have a look at a quick simple example, lets say I have a form with 3 input fields, name, email and website, we want to have the name and email fields required, we want to check the email is valid and because we are storing these fields in a database with a character limit we need to check the fields are not too long. Below is the html form code and the javascript for the validation.

<script type="text/javascript">
$(function(){
    $("#subscribe_test").validate({
        rules: {
            fullname: { required: true, maxlength: 64 },
            email: { maxlength: 32 },
            website: { maxlength: 32 }
        }
    });
});
</script>

<form id="subscribe_test" action="save_subscriber.php" method="POST">
  <table>
    <tbody>
      <tr>
        <td><label for="fullname">Full name: *</label></td>
        <td><input id="fullname" type="text" /></td>
      </tr>
      <tr>
        <td><label for="email">Email: *</label></td>
        <td><input id="email" class="email required" type="text" /></td>
      </tr>
      <tr>
        <td><label for="website">Website:</label></td>
        <td><input id="website" type="text" /></td>
      </tr>
      <tr>
        <td><input type="submit" /></td>
        <td></td>
      </tr>
    </tbody>
  </table>
</form>

In the above example you can see that you can apply the validation rules both in javascript and also using the predefined rule names as the css class for the input. E.g. the email input field is using classes email and required, the validation plugin will look for any class names on the inputs and apply the validation rule if there is one. I could have defined the email rule solely in the script but I wanted to show that there is a quicker way using classes. The working example for the above code is below.

You can also do remote validation. For example, lets say in our example we did not want someone with the same email address to be subscribed twice. You can use a special validation rule remote which points to a script which should output true or false based on the form input value. We will also give a special message for when the email address is already in use. The changed script code is then:

<script type="text/javascript">
 $(function(){
     $("#subscribe_test2").validate({ rules: {
         fullname: { required: true, maxlength: 64 },
         email: { maxlength: 32, remote: "/check_subscribed.php" },
         website: { maxlength: 32 }
     },
    messages: {
        email:{ remote: "Already subscribed" }
    } });
 });
</script>

The running example now will not allow you to enter the email test@example.com, for this example there is a script called check_subscribed.php which is hard coded to look for the POST email variable and return false if it equals test@example.com.

So that is all good everything seems to be validating fine. Now I will show you a small case to watch out for. Lets assume that the subscribe form needs to be submitted using ajax and only accepts a required email address which should be remotely validated. Below is the code and the working example, if you simply enter the already subscribed email test@example.com and submit you see it does not work properly, the form gets submitted even though the validation fails.

Update 29/09/2010 since updating this post and rechecking the code it appears, this actually does work. Perhaps the browsers have changed the order the javascript events occur, I certainly did not change anything, this was an issue previously.

Code and example below.

<script type="text/javascript">
jQuery(function($){
       $("#subscribe_test3").submit(function(e){
          if ($(this).valid()){
               $.ajax( {
                   type: "POST",
                   url: "/save_subscriber.php",
                   data: "email="+$("#subscribe_test3_email").val(),
                   success: function(data){
                        $("#submit_result").html("Ajax submit results:
"
+ data);
                   }
               });
          }
          return false;
    });
    $("#subscribe_test3").validate({ rules: {
         email: { maxlength: 32, remote: "/check_subscribed.php" }
     }, messages: {
        email: { remote: "Already subscribed"}
     }
     });
});
</script>

<form id="subscribe_test3" action="save_subscriber.php" method="POST">
  <table>
    <tbody>
      <tr>
        <td><label>Email: *</label></td>
        <td><input id="subscribe_test3_email" class="email required" name="email" type="text" /></td>
      </tr>
      <tr>
        <td><input type="submit" /></td>
      </tr>
    </tbody>
  </table>
</form>

The reason the above example did not work properly is because the remote validation checking is done asynchronously, as is the ajax request. In the above code, the form submit event binding function checks first if the form is valid before doing the ajax submit. The trouble is that the remote validation is done asynchronously. So the valid check is just returning true instead of false. In order to solve this the remote validation needs to be done synchronously instead (or async: false). Below is the relevant fix and the fixed example.

$("#subscribe_test3").validate({
  rules: {
    email: {
      maxlength: 32, remote: { url: "/check_subscribed.php", async: false }
    }
  },
  messages: {
    email: { remote: "Already subscribed"}
  }
});

Update 27/09/2010

It has been asked what the check_subscribed.php script did, so here it is below:

<?php
$email = $_REQUEST["email"];
if ($email == "test@example.com"){
    echo "false";
} else {
    echo "true";
}
?>

Update 01/11/2010

Someone has asked for the files used in these examples, so here is a zip file containing a html page and the necessary php scripts. The jquery and validation plugin are not included in the zip but are referenced as external scripts. This is a recommended way of including jQuery in your sites (but obviously a more up to date version).

64 comments so far

Add Your Comment
  1. html code:

    $(function(){
    $(“#subscribe_test2″).validate({ rules: {
    fullname: { required: true, maxlength: 64 },
    emailId: { maxlength: 32, remote: “check_subscribed.php” },
    website: { maxlength: 32 }
    },
    messages: {
    emailId:{ remote: “Already subscribed” }
    } });
    });

    Multiple fields, remote check for email address

    Full name: *

    Email: *

    Website:

    phpcode:

    0)
    {
    echo “false”;
    }
    else
    {
    echo “true”;
    }
    ?>

    where i have done mistake. it always coming “Please enter a valid email address.”.

  2. JS Code:

    $(document).ready(function(){
    $(‘#registration_form’).validate({
    onkeyup: false,
    errorClass: ‘error’,
    validClass: ‘valid’,
    rules: {
    username: {
    required: true,
    minlength: 5,
    remote: “checkusername.php”
    },
    emailId: {
    required: true,
    email: true,
    remote: “checkemail.php”,
    },
    messages:{
    username: {
    required: “Please enter Username”,
    minlength: “Please enter atleast 5 characters”,
    remote: “Already taken! Please try with onother user name”,
    },
    emailId: {
    remote: “Already taken! Please try with onother email address”,
    },
    });

    CheckEmail.php:

    Check Username.php::

    0) {
    echo “false”;
    } else {
    echo “true”;
    }

    ?>

    When I am using your code it’s working perfectly. But
    when I am fetching from the DB it’s not working. I am sending my code please help me.
    Thanks in Advance.

    /*
    $username = $_REQUEST["username"];
    if ($username == “username”){
    echo “false”;
    } else {
    echo “true”;
    }

    */

  3. Are you saying the above is working but when validating against the database it’s not? If so I need to see some of that database code.

  4. mysql_connect(‘localhost’,’root’,”) or die(mysql_error());
    mysql_select_db(‘siddhart_global’) or die(mysql_error());

    $username = mysql_real_escape_string($_REQUEST["username"]);

    $query = “SELECT username FROM tbl_registration WHERE username = ‘$username'”;
    $result = mysql_query(“$query”) or die (mysql_error());
    $count = mysql_num_rows($result);

    if($count > 0) {
    echo “false”;
    } else {
    echo “true”;
    }

  5. That looks ok to me, what happens when you request the php script directly. E.g. CheckUsername.php?username=test

  6. I have been having the same problem.

    0) {
    echo “false”;
    } else {
    echo “true”;
    }
    ?>

    I swapped your code with the above and it doesn’t seem to work. Could it be that i’m using localhost? (MAMP).

  7. Sorry php tags made that comment come out wrong.

    $email = mysql_real_escape_string($_REQUEST["email"]);

    $query = “SELECT COUNT(id) FROM users WHERE email = ‘$email’”;
    $result = mysql_query(“$query”) or die (mysql_error());
    $count = mysql_num_rows($result);

    if($count > 0) {
    echo “false”;
    } else {
    echo “true”;
    }

  8. Code looks correct, it’s been a long time since I made this post and the validation library could have changed since then, if you read in the complete comment history you will see an issue with a different version of the form validation library. Try version 1.7, if it’s still not working can you post some running code online or email me a zip file with the HTML JavaScript and PHP code, jsfiddle seems a nice place to test JavaScript code but doesn’t support php code. I just need something online so I can debug it. Thanks.

  9. Thanks for your reply. I have now successfully figured the problem out, and it works very good now, although I have run into another problem. I will email you this time.

  10. Thanks for the write up , works well in my app

  11. rules:
    {
    “data[add_countryfrm][country_code]“:
    {
    required : true,
    minlength : 2,
    remote :
    {
    url: ‘admins/addcountry_checker’,
    type: ‘post’,
    data: {
    “ids”: $(‘#country_code’).val()
    }
    }
    },
    Using Above Coding in Cake PHP Not working
    public function addcountry_checker()
    {
    $this->layout=’ajax';
    $this->autoRender=false;
    $countrycode=trim(mysql_real_escape_string($_GET[“data['add_countryfrm']['country_code']“]));
    $valid = ‘true';
    $ad11=$this->Countrie->find(‘first’,array(‘conditions’=>array(‘country_code2’=>$countrycode,’country_status’=>’1′)));
    if($ad11)
    {
    $valid = ‘false';
    }
    echo $valid;
    }

  12. From a quick glance, your rules you have “data[add_countryfrm][country_code]“: you should remove the quotes if you a planning to have the rule for the field named by data[add_countryfrm][country_code]. I would also ask is this intentional. Do you really need a form field named by this dynamic variable?

  13. Hi Tim.If it not much trouble ,could you let me know how you solved the problem of database connectivity. I have run into the same problem. Help would be appreciated.
    thanks

  14. This Worked for me in java, struts and remote jquery validation:
    JAVA SIDE:

    response.setContentType(“text/plain; charset=iso-8859-1″);
    response.getOutputStream().print(!resultado); /* resultado is boolean*/

    $(“#frmFichaTConfiguracion”).validate({
    rules: {
    “ENCOD”: {
    remote: {
    url : “/r03-01i/was/r03ComprobarPKTConfigAJAX.do”
    }
    }
    },
    messages:{
    “ENCOD”: existeBBDD
    }
    });