Validating Forms With jQuery
Using jQuery’s Ajax Methods
The three main topics of this chapter are closely related cousins. HTML forms contain
and process data, an everyday operation of the Web. More often than not, form data is
processed and posted to a server somewhere asynchronously, rather than the old-fashioned
post-process-reload technique. Here, you explore one of the biggest revolutions in web
development of the past 10 years — Ajax. You also learn how insanely easy jQuery makes it,
simplifying asynchronous communication with the server side.
JQUERY DATA APPRECIATION
An often misused feature of tag elements is using attributes such as alt or class to attach
useful data to an element. For example:
<!DOCTYPE html>
<html>
<head>
<script src=”http://code.jquery.com/jquery-1.6.1.js”></script>
<script type=”text/javascript”>
$(function(){
$( “#randomEl” ).attr( “alt” , “1999” );
});
</script>
</head>
<body>
<img src=”usefulImage.jpg” id=”randomEl”></div>
</body>
</html>
Just for the record, we’re aware of the fact that we can assign “1999” directly to the alt attribute, but just suppose you needed to add the string programmatically. There’s a semantic problem with this because the attribute used to store the data isn’t meaningfully associated. Is 1999 a year, a random integer, or what? A better approach is to use jQuery’s .data() method, which stores arbitrary data for an element with a meaningful key. It takes the following form: $.data( element, key, value ); Or, to retrieve the stored data use: $.data( element, key ); For example: <!DOCTYPE html> <html> <head> <script src=””></script> <script type=”text/javascript”> $(function(){ $( “#randomEl” ).data( “itemPrice”, “1999” ); }); </script> </head> <body> <img src=”usefulImage.jpg” id=”randomEl”></div> </body> </html>
Now it’s obvious that 1999 isn’t a year, but rather a price. HTML5 introduces custom data attributes, where any attribute that is prefi xed with data- can be used in a standardized, programmatic way. For example, the following div element contains the data attribute data-age. That’s an alternative for storing information on the client side.
<div id=”person” data-age=”31”></div>
Microsoft contributed to the community three additional plugins that were, for a time, offi cially endorsed by the jQuery project; Data Link, Template, and Globalization. In a later chapter we review the Template plugin. The Data Link plugin allows two-way binding between objects. In other words, it links the fi eld of one object to another, so changing the value of one fi eld changes the corresponding fi eld on the second object. You can use this feature to simplify communication between a form and an object because it removes glue code. For example:
<!DOCTYPE html> <html> <head> <script src=”http://code.jquery.com/jquery-1.6.1.js”></script> <script src=”jquery.datalink.js”></script> <script type=”text/javascript”> $(document).ready(function(){
var registration = {}; $( “form” ).link(registration); // set some default values $( registration ).setField( “name”, “New User Registration” ); $( registration ).setField( “email”, “i_dont_exist@mail.com” ); $( “form” ).change(function(){ console.log( registration.name + “ “ + registration.email ); }); }); </script> </head> <body> <form method=”post”> <label for=”name”>User Name </label> <input type=”text” name=”name” /> <label for=”email”>email </label> <input type=”email” name=”email” /> <input type=”submit” value=”send it” /> </form> </body> </html>
In this example, after changing the value of the form, there’s a console.log showing the value of the registration object, which refl ects the new changes. So you’ve seen that jQuery has some shortcuts and methods for working with data, but end users can’t be trusted! The following section explains the ins-and-outs of data validation.
USING FORM VALIDATIONS
Form validation is important for a list of reasons, anywhere from preventing unintentionally messing up a database to securing your system from malicious injection attacks, as well as the more mundane reasons such as making sure that the data entered makes sense. For example, a fi rst name fi eld probably shouldn’t permit special characters like $%&#@ or numbers. Traditionally, you would use jQuery, or some form of JavaScript, to either mask a fi eld or validate the data entered. The simplest example is to check that data has been entered for a required fi eld: if($(“#myInput”).val() !== ‘’){ // handle here } A note of caution: your carefully crafted validation is useless if end users turn off JavaScript features on their browsers. Data should be sanitized on both the server and client side before saving.
Feature Detection with Modernizr
Before going any further with HTML5 forms and jQuery, it’s a good time to mention the Modernizr library. It can greatly simplify the task of detecting browser features that aren’t yet implemented in all mainstream browsers. Modernizr does this by using a process called feature detection. Instead of relying on the old-school method of User Agent (UA) Sniffi ng, detecting a browser’s capabilities based on the unreliable navigator.userAgent string, feature detection tests for specifi c browser capabilities. This is a much more future-proof and user-friendly method of feature testing. It doesn’t matter if some new browser appears or some version of Chrome or Firefox hits the Web with a novel navigator.userAgent string. If the feature is supported, Modernizr will report it as being available.
For example, you could use Modernizer to detect if a browser supports the canvas element: In this sample, you’ll see one of the great features of Modernizr. For every feature it detects it stores a Boolean fl ag in the Modernizr object representing the result of the test. In this example, with supporting browsers, Modernizr.canvas will evaluate to true. In addition to this Modernizr also adds CSS classes to the html element indicating the availability of features.
<!DOCTYPE html> <html> <head> <script src=”http://code.jquery.com/jquery-1.6.1.js”></script> <!-- Link to modernizr, useful for feature detection --> <script src=”http://ajax.cdnjs.com/ajax/libs/modernizr/1.7/modernizr-1.7.min.js”> </script> <script type=”text/javascript”> if(Modernizr.canvas){ // code that depends on canvas here } else { // oops, canvas doesn’t exist, deal with situation // here } </script> </head> <body> </body> </html>
Anywhere I need to use Modernizr, we link to the code using the public JavaScript CDN ajax.cdnjs .com. Let’s put Modernizr to some use. Another great feature of HTML5 forms is the required fi eld fl ag. For example, the following form: <!DOCTYPE html> <html> <body> <form> <input type=”text” name=”userName” required/>
<input type=”password” name=”password” required/> <input type=”submit” value=”send it” /> </form> </body> </html>
renders the message seen in Figure 6-1 in supporting browsers, in this case, Chrome, after attempting to submit a blank form. Not all browsers support this feature, or even any of the other HTML5 features. Again, jQuery comes to the rescue for validating forms. As the following code illustrates you can use feature detection to determine if a browser has the “required fi eld” feature, and if it doesn’t use jQuery techniques instead. Modernizr tests for the presence of the “required fi eld” feature, and if it’s absent, a message div is appended to the document and a simple form handler is attached to the form. This handler tests to see if any of the required fi elds are empty using the jQuery form utility .val(). If one is empty it throws up the message div, adds a small border to the form fi eld and prevents submission of the form. This is clearly a simplifi ed form validation example, but it illustrates the basic concepts of form validation with jQuery and the basic concepts of using feature detection to take advantage of modern browser features.
<!DOCTYPE html> <html> <head> <script src=”http://code.jquery.com/jquery-1.7.1.js”></script> <script src=”http://ajax.cdnjs.com/ajax/libs/modernizr/1.7/modernizr-1.7.min.js”> </script> <script type=”text/javascript”> $(function(){ if( !Modernizr.input.required ){ var $msg = $( “<div id=’reqMessage’>Required Fields Missing</div>” ); $msg.css( “background-color”, “yellow” ) .hide(); $( “body” ).append( $msg ); $( “#fDet” ).on(“submit”, function(e){ $( “input[required]” ).each(function(){ if ( $(this).val() === “” ) { $( “#reqMessage” ).show(); $( this ).css( “border” , “1px solid red” ); e.preventDefault(); } }); }); } }); </script> </head> <body>
<form id=”fDet” action=”#”> <input type=”text” name=”userName” required/> <input type=”password” name=”password” required/> <input type=”submit” value=”send it” /> </form> </body> <html>