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. 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:<br />" + 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>
    <tr>
        <td><label>Email: *</label></td>
        <td><input id="subscribe_test3_email" class="email required" remote="check_subscribed.php" name="email" type="text"/>
        </td>
    </tr>
    <tr>
        <td><input type="submit"/></td>
    </tr>
</table>
<div id="submit_result"></div>
</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"}
     }
});

No Comment.

Add Your Comment