jQuery Validation plugin overview

I’ve recently posted about the 1.2 release of the validation plugin. The post contains an unordered list of changes from the last release, which is handy when coming from a previous release, but lacks the perspective of someone new to the plugin. Therefore this post will cover three areas where the plugin has been improved significantly, and will also serve as a introduction to the plugin.

Specifying validation rules

The first problem to solve when dealing with form validation is to specify validation rules. Lets consider an example, validating a comment form, where the form itself looks like this in HTML:

<form id="commentform" method="post" action="">
	<fieldset>
		<legend>Please provide your name, email address (won't be published) and a comment</legend>
		<p>
			<label for="cname">Name (required, at least 2 characters)</label>
			<input id="cname" name="name"  />
		<p>
			<label for="cemail">E-Mail (required)</label>
			<input id="cemail" name="email" />
		</p>
		<p>
			<label for="curl">URL (optional)</label>
			<input id="curl" name="url" value="" />
		</p>
		<p>
			<label for="ccomment">Your comment (required)</label>
			<textarea id="ccomment" name="comment" ></textarea>
		</p>
		<p>
			<input class="submit" type="submit" value="Submit"/>
		</p>
	</fieldset>
</form>

With a bit of styling, the form will look like this:

Validation comment form

The easiest way to specify the validation rules, is adding classes and attributes:

<form id="commentform" method="post" action="">
	<fieldset>
		<legend>Please provide your name, email address (won't be published) and a comment</legend>
		<p>
			<label for="cname">Name (required, at least 2 characters)</label>
			<input id="cname" name="name" class="required" minlength="2" />
		<p>
			<label for="cemail">E-Mail (required)</label>
			<input id="cemail" name="email" class="required email" />
		</p>
		<p>
			<label for="curl">URL (optional)</label>
			<input id="curl" name="url" value="" class="url" />
		</p>
		<p>
			<label for="ccomment">Your comment (required)</label>
			<textarea id="ccomment" name="comment" class="required" ></textarea>
		</p>
		<p>
			<input class="submit" type="submit" value="Submit"/>
		</p>
	</fieldset>
</form>

Note how the classes required, email and url could also be used to style the element via CSS.

Now, to validate that form, we need to include the necessary files on our page, and a bit of code to trigger the validation.

<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.delegate.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>

Of course jQuery itself is required (jquery.js), in addition the delegate plugin is necessary (jquery.delegate.js), and the validation plugin itself (jquery.validate.js). Once that is done, running the validation requires only a document-ready-block, a selection of the form to validate and a call to the plugin method. The very basics of using jQuery.

$(document).ready(function() {
  $("#commentForm").validate();
});

This example uses default messages. Those can be heavily customized when needed, as well as the way how to display the messages themselve. How to do that is documented in the jQuery documentation wiki for the validate-method.

Remote validation

Adding client-side validation to a form can significantly improve the usability of that form, making it much easier for users to fill them out successfully. But pure client-side validation has severe limits where necessary information is available only on the server. Ajax helps to bridge the gap, but synchronizing validation on form submit isn’t exactly an easy task. The validation plugin makes it as simple as pure client-side validation. All you need to do is to specify a rule “remote” for a field and provide a parameter that points to a server-side resource that handles the validation.

Taken from the Marketo demo, the HTML looks like this:

<input id="email" class="required email" remote="emails.php" maxlength="40" name="email" />

If you enter an email address, the validation plugin sends a request to the server with a parameter “email” and the value you entered. The server checks if that address is already in use – here just checking a list of fake addresses, usually a database lookup – and if the server returns a JSON false (just “false” in the response), shows the validation message:

Marketo form, remote email address validation

Dynamic forms

Consider an order form, where you from a list of items and enter the amount for each. Wouldn’t it be nice to dynamically add more inputs without refreshing the page, and validating those? While this has been challenging in the past, its now really easy due to some event delegation tricks utilized. Where previously events like keyup and blur where registered on each plugin, they are now added to the form, enabling to add and remove elements from and to the form without having to reapply those events. That also improves performance a lot, especially for large forms, because there are always no more then five event handlers registered, while previous version registered up to three event handlers for each element.

In the dynamic form example, the user starts with one row of inputs, and can add more by clicking the button below the form. The totals field is also checked to not exceed a value of 25:

Validate dynamic forms

Currently the code to generate new inputs isn’t too pretty, because each input needs a unique name. Allowing PHP style array names (“quanity[]”) is one of the things on the roadmap, among:

Roadmap

  • Integrating the datejs.com library for proper date validation – the current methods for dates just check formats, but not ranges
  • Improving remote validation to batch requests on form submit, and accepting messages back from the server to display
  • Adding more integration examples, like date- and timepickers, password-strength-meters, richtext editors

I’m also planning the 2.0 API, cleaning up inconsistencies that resulted from the evolution of the plugin, providing methods to validate a form and elements without triggering the UI (showing messages), and moving a few less-useful features and validation methods so make the core lighter with more pluggable components.

-Jörn

No more comments.
  1. Jacob

    this is the best validation-plugin i’ve ever seen! great respect and million thx for this!

  2. Great work!

  3. Really usefull.
    Lots of thanks!

  4. I loved the captcha validation part!!

    A tiny untechnical correction:
    # cmxforms.js – only used for form layout, optional, see article by Kevin Cornell
    should be:
    # cmxforms.js – only used for form layout, optional, see article by Nick Rigby

  5. Great man! Congrats. for great job.

  6. Gut gemacht, wie immer. Weiter so und danke.
    thomas

  7. Martin Fairfax

    This is a brilliant plugin. Thank you, Jörn!

    One note: the included email validation with release 1.2 allows for email addresses that do not have an extension (such as me@test). I’m not sure if that is intentional, but if you change the second to last * to a + then this seems to be solved.

  8. @Martin: That’ll be fixed in 1.2.1, which should be out in one to three days.

  9. Pramod

    I have used this plugins.
    But i found some error in IE 7 with google toobar.
    It shows message “Your Google Toolbar can fill this in for you. Select AutoFill “.

    How should it be removed.

  10. Praveen Vijayan

    Great plug in..
    Thanks…

  11. John Morrison

    Hi,

    I’ve got a textbox which has a remote rule on it which works very well thanks. However I get a request on every keypress, would it be possible to add a (definable?) delay after the keypress before the request is submitted which, if another key is input before the delay times out causes the delay to be reset.

    I hope my rambling makes sense!

    If not, I think http://www.selfcontained.us/2007/10/07/ajax-requests-when-users-stop-typing/ describes the issue.

    Once more – thanks for all your hard work!

    J.

  12. First of all: great plugin! I’m really grateful to discover something that does 99% of what I need, just right out of the box, especially since it’s in jQuery and ties in nicely to everything else I’m doing. I am however encountering a problem: I’m trying to implement the validation plugin on a site where my layout requires the error message to be contained within an inline element.

    Unfortunately it appears that the default behaviour of .show() gives elements a display mode of block; this means that if a particular field is given invalid input, then corrected, then accidentally made invalid again, the label containing the error is given display:block and the layout is broken. This seems to be as much a bug in jQuery as anything else, but I’m loath to start forking this fine plugin myself. Is there any way that the plugin could be made to give previously-hidden error containers the same display mode they had prior to being hidden?

  13. @Pramod, John and Ben: Your feedback is welcome, but please post issues or support requests to the jQuery discussion list. I won’t answer them here. Thanks.

  14. Cool Script! A piece of art?

    A couple of questions:

    1. How do i validate a range from 2 to 30 chars?

    2. How do a use non-english messages, like spanish language?

    Thanks in advance.

  15. Ok! Here es is tha demo:
    http://jquery.bassistance.de/validate/demo/

    But in cakephp the name and id are not the same, how can i avoid this?
    name=”data[User][email]” maxlength=”255″ value=”” id=”UserEmail”

    thanks in advance.

  16. @josoroma: Please post the jQuery discussion list. This is not a support forum.