Official website for Web Designer - defining the internet through beautiful design
FOLLOW US ON:
Subs House Ad
Mar
26

Add client-side form validation with jQuery

by Steve Jenkins

02 Examine the page 151_068_step02 Open the start.html page up in your web browser to get a feel for how it looks. We’ve gone for a simple layout, with the form fields floated right, the label contents to the left and a simple background applied to indicate required fields. We’re going to grab the title text from each label and use it to generate an information bubble, which provides the user with useful hints when completing the form. 03 Set up the hooks Add the code below into your HTML document immediately beneath the line you added in the first step. Once the document has loaded in the browser, we use jQuery to grab every label that has a title attribute using the line $(“label[title]”).each(function(){…..});. For each label returned, we add a new div inside the label, store the title text from the label and then remove it from the label. We go on to set the content for the new div we just created to be the stored title text, and reduce the div Opacity to zero; it becomes invisible. Finally, add a hook for two events: one for when the user enters the form field with their cursor, and a second for when their cursor leaves the field.

04 Preview the effect
151_068_step04

If you load your page up in your browser, you’ll be spectacularly disappointed; it looks exactly the same as before. This is because although we’ve added the new divs into the markup, we’ve also hidden them by setting the Opacity to zero. If you’d like a quick look at how the info bubbles will appear, change the line $(“.infopop”,this).css({opacity:0}). html(titletext); to read $(“.infopop”,this).css({opacity:1}).html(titletext); and reload in your browser. Notice that although the submit button is contained within a label, there isn’t a corresponding info bubble. This is because the label for the submit button has no title attribute so it was ignored. We’re going to animate each bubble into view when the form field has focus, and animate it back out of view again when it loses focus. Set your code back to its original Opacity of zero.

05 Add the animations

Add the code below directly above the closing tag (underneath the code you added in step three). Here, we are adding four functions that perform similar tasks. doFocus() uses the jQuery object to add a class of ‘active’ to the selected element, and animate the position of the info bubble along with the Opacity, so that it slides into view. doBlur() currently just calls isGood(), which might seem a little odd, but later we’re going to validate the field when it loses focus so it makes sense to do the animation in a separate function. reportErr() takes an element and a message, assigns an error class to the info bubble and animates it into position. Finally, isGood() removes any error classes, and animates the info bubble out of view. If you want a full understanding of jQuery’s chaining, selectors and methods for animation and element manipulation.

function doFocus (obj){
$(obj).addClass(“active”).parents(“label”).addClass(“active”).find(“.infopop”).
animate({opacity:1,left:492},500);
}
function doBlur(obj) {
isGood(obj);
}
function reportErr(obj, message) {
$(obj).addClass(“error”).parents(“label”).removeClass(“isgood”).
addClass(“required”).addClass(“error”).find(“.infopop”).html(message).
addClass(“errorpop”).animate({opacity:1,left:492},500);
}
function isGood(obj) {
$(obj).removeClass(“error”).removeClass(“active”).parents(“label”).
addClass(“isgood”).removeClass(“error”).removeClass(“active”).find(“.infopop”).
removeClass(“errorpop”).animate({opacity:0,left:513},500);
}

06 Connect up the hooks
151_068_step06

Now that the functions are set up for the animation, we need to assign the hooks to call them when the different events fire. We’ll call the doFocus() function when a field becomes active, and the doBlur() function when the field loses focus. This is quite straightforward; alter the existing code for the events to read as below. Once you’ve saved this, test again in your browser and you will see the effect starting to take shape. Note how each field is marked with a tick when you move your cursor away.

$(“input”,this).focus(function(){
// User puts their cursor in the form field
doFocus(this);
}).blur(function(){
// User moves their cursor out the form field
doBlur(this);
});

07 Coloured borders

Already the form is far more user-friendly; the current field highlights when you click into it, a nice info bubble is animated into place to provide additional information and it all animates away again when the field loses focus. We’re going to take it one step further by validating the entries the user makes to check they’re completing the correct information. When the validation fails we want the user to be made aware of the problem, and we also want to provide additional helpful information to make it easy for the visitor to make corrections. We’ve already set up the error states in our CSS and with the reportErr() function, so when we need to alert the user to a problem we’ll call the reportErr() function. Try that now by adding a temporary validation function; add the code below beneath the existing functions in your block of script.

function validate(obj) {
if ($(obj).val()==’’) {
reportErr(obj, “This can’t be empty”);
return false;
} else {
return true;
}}

Now change your onBlur() function to read as below:
function doBlur(obj) {
if (validate(obj)) {
isGood(obj);
}}

08 Review and test
151_068_step08

The code we’ve just added checks to see if the field parses validation when the doBlur() function is called. If the validate function returns true, the test is passed and we fire off the isGood() function. If the validation fails, and thus returns false, the isGood() function is never called, so the bubble remains in view. Additionally, by calling the reportErr() function within the validation function, we parse in an error message when validation fails. Test the page once again in your browser. You’ll see that when you leave a field empty the info bubble turns red, the label highlights in red and an error message is shown in the info bubble. Once we enter something into the field, however, the bubble returns to green and animates out. This happens because we’ve met the validation criteria (that the field can’t be empty), and thus isGood() is called. There are a few issues, though. First of all, the validation is applying to everything – whether it’s a required field or not – and second of all, the validation itself isn’t terribly useful.

09 Building effective validation

Now that we’ve tested the concept, we’ll add in the real validation routines. There are many different ways you could approach this, but for ease of example we’re going to simply use regular expressions to check the contents of the field are valid. For now, replace your validate() function with the code below, or copy and paste the function from the finished version of the page. We’ll look at what’s going in the following steps.

function validate(obj) {
// Extend jQuery object to include Regular expression masks assigned to properties
mask = jQuery.extend({textfieldmask: /^[a-z\.\s-]{5,}$/i,phonemask: /^[0-9\(\)\+\.\s-]{8,}$/
i,passwordmask: /^\w{5,}$/, emailmask:/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-
]+\.)+[a-z]{2,6}$/});
// Extend jQuery object to include error messages assigned to properties
errmsg = jQuery.extend({textfielderr:”5 or more letters”,phoneerr: “Include dialling code”,
passworderr:”Minimum 5 characters”,emailerr:”Invalid address”,matcherr: “Must match”});
// Set up variables to hold details of which mask to use and whether the field should match
another field
var masktouse = null;
var mustmatch = null;
// Determine the type of mask we’re going to validate against
switch(obj.name) {
case “name”: masktouse=”textfieldmask”;
errtouse=”textfielderr”; break;
case “phone”: masktouse=”phonemask”;
errtouse=”phoneerr”; break;
case “username”: masktouse=”textfieldmask”;
errtouse=”textfielderr”; break;
case “email”: masktouse=”emailmask”;
errtouse=”emailerr”; break;
case “password”: masktouse=”passwordmask”;
errtouse=”passworderr”; mustmatch=”verpassword”; break;
case “verpassword”: masktouse=”passwordmask”;
errtouse=”passworderr”; mustmatch=”password”; break;
// Check that the element is a required field before validating against it.
if($(obj).parents(“label”).hasClass(“required”) && masktouse) {
// Set up a quick way of accessing the object we’re validating
pointer = $(obj);
// Test the value of the field against the Regular Expression
if (mask[masktouse].test(pointer.val())) {
// The field validated successfully!
// Check to see if the field needs to match another field in the form
if (mustmatch) {
// It does need to match, so grab the object it needs to match
matchobj = $(“#”+mustmatch);
if (matchobj.val()!=’’ && matchobj.val()!=pointer.val()) {
// The fields don’t match, so report an error on both of them
reportErr(obj,errmsg[“matcherr”]);
reportErr(matchobj,errmsg[“matcherr”]);}
else {
// Either the fields match, or the other field hasn’t been completed yet
// If the other field has been completed, call the isGood function to clear any error message
if (matchobj.val()!=’’) { isGood(matchobj);}
return true;
}
}
else {
// No match is required, so return true – validation passed!
return true;
}
} else {
// The field failed to validate against the Regular Expression
reportErr(obj,errmsg[errtouse]);
return false;
}}
else {
// This isn’t a required field, so we won’t validate it against anything
return true;
}}

10 Give it a try
151_068_step10

Before we look at how the code works, give it a try in your browser to see the validation functioning. Notice that when you fail to complete a particular field, the error message alters according to the type of field. The email field will only validate if you enter a valid email address, the name field must contain at least five letters, and so on.

11 Understanding the code

Now that you’ve seen the code working, it needs a little explanation above and beyond the comments in the script. We’re using paths through conditional statements – lots of ‘if’s and ‘else’s – to determine whether validation is required and if the various criteria are met; all standard JavaScript coding that we won’t detail here (but if you’re new to JavaScript, see the boxout for useful resources). The interesting bit is at the top of the function. First of all, we extend the jQuery object to include properties for each of the regular expression masks we want to use to validate our field content. Don’t confuse the assignment of the variable (in this case, mask) as you assigning the properties exclusively to that object variable; ‘mask’ is simply used as a wrapper to the jQuery properties contained within the statement, so property names must be unique to the overall jQuery object. We repeat this process for the error messages to be displayed when validation fails. Finally, we use a simple switch statement to check the name of the field being validated, and based on the name we decide what kind of field that is, which error message to use and whether the content of that field should match another field in the form. There are jQuery plug-ins available that automate this process, but they require you to add invalid XHTML attributes to your markup.

Pages: 1 2

Bookmark and Share

2 Comments »

  • Cheshire Plasterer said:

    Thanks. This is exactly what I have been looking for and ypu’ve made it easy to understand. I’ve been wanting to put a better form into my site for a while now and this makes it look more professional

  • Paul Sayer said:

    EXCELLENT script and would be excellent bar one small issue I seem to be having, which is that the form STILL submits even if there are errors outstanding. Is there a way to stop the form submitting until all fields are correct?

What's your opinion?

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.