Section 18.4. Form Verification Example


18.4. Form Verification Example

I'll close the discussion of forms with an extended example showing how you can use unobtrusive client-side JavaScript to perform form validation.[*] Example 18-3, which appears later, is a module of unobtrusive JavaScript code that enables automatic client-side form validation. To use it, simply include the module in your HTML page, define a CSS style to highlight form fields that fail validation, and then add additional attributes to your form fields. To make a field required, simply add a required attribute. To make sure that the user's input matches a regular expression, set the pattern attribute to the desired regexp. Example 18-2 shows how you can use this module, and Figure 18-2 shows what happens when you attempt to submit a form containing invalid input.

[*] Note that client-side form validation is merely a convenience for users: it makes it possible to catch input errors before a form is submitted to the server. But client-side validation is never guaranteed to happen because some users will have JavaScript disabled. Furthermore, client-side validation is trivial for a malicious user to subvert. For these reasons, client-side validation can never take the place of robust server-side validation.

Figure 18-2. A form that failed validation


Example 18-2. Adding form validation to your HTML forms

 <script src="/books/2/427/1/html/2/Validate.js"></script> <!-- include form validation module --> <style> /*  * Validate.js requires us to define styles for the "invalid" class to give  * invalid fields a distinct visual appearance that the user will recognize.  * We can optionally define styles for valid fields as well.  */ input.invalid { background: #faa; } /* Reddish background for invalid fields */ input.valid { background: #afa; }   /* Greenish background for valid fields */ </style> <!--   Now to get form fields validated, simply set required or pattern attributes. --> <form>   <!-- A value (anything other than whitespace) is required in this field -->   Name: <input type="text" name="name" required><br>   <!-- \s* means optional space. \w+ means one or more alphanumeric chars-->   email: <input type="text" name="email" pattern="^\s*\w+@\w+\.\w+\s*$"><br>   <!-- \d{5} means exactly five digits -->   zipcode: <input type="text" name="zip" pattern="^\s*\d{5}\s*$"><br>   <!-- no validation on this field -->   unvalidated: <input type="text"><br>   <input type="submit"> </form> 

Example 18-3 is the code for the form-validation module. Note that including this module in an HTML file does not add any symbols to the global namespace and that it automatically registers an onload event handler that traverses all forms in the document, looking for required and pattern attributes and adding onchange and onsubmit handlers as needed. These event handlers set the className property of each form field they validate to "invalid" or "valid", and you should use CSS to provide a distinct visual appearance for at least the "invalid" class.[*]

[*] At the time of this writing, the AutoFill feature of the Google Toolbar interferes with the use of CSS styles to set the background of certain text fields. Google's browser extension sets the text field background to light yellow to indicate that it may be possible to automatically enter values into the field.

Example 18-3. Automatic form validation with unobtrusive JavaScript

 /**  * Validate.js: unobtrusive HTML form validation.  *  * On document load, this module scans the document for HTML forms and  * textfield form elements. If it finds elements that have a "required" or  * "pattern" attribute, it adds appropriate event handlers for client-side  * form validation.  *  * If a form element has a "pattern" attribute, the value of that attribute  * is used as a JavaScript regular expression, and the element is given an  * onchange event handler that tests the user's input against the pattern.  * If the input does not match the pattern, the background color of the  * input element is changed to bring the error to the user's attention.  * By default, the textfield value must contain some substring that matches  * the pattern. If you want to require the complete value to match precisely,  * use the ^ and $ anchors at the beginning and end of the pattern.  *  * A form element with a "required" attribute must have a value provided.  * The presence of "required" is shorthand for pattern="\S". That is, it  * simply requires that the value contain a single non-whitespace character  *  * If a form element passes validation, its "class" attribute is set to  * "valid". And if it fails validation, its class is set to "invalid".  * In order for this module to be useful, you must use it in conjunction with  * a CSS stylesheet that defines styles for "invalid" class.  For example:  *  *    <!-- attention grabbing orange background for invalid form elements -->  *    <style>input.invalid { background: #fa0; }</style>  *  * When a form is submitted, the textfield elements subject to validation are  * revalidated. If any fail, the submission is blocked and a dialog box  * is displayed to the user letting him know that the form is incomplete  * or incorrect.  *  * You may not use this module to validate any form fields or forms on which  * you define your own onchange or onsubmit event handlers, or any fields  * for which you define a class attribute.  *  * This module places all its code within an anonymous function and does  * not define any symbols in the global namespace.  */ (function( ) { // Do everything in this one anonymous function     // When the document finishes loading, call init( )     if (window.addEventListener) window.addEventListener("load", init, false);     else if (window.attachEvent) window.attachEvent("onload", init);     // Define event handlers for any forms and form elements that need them.     function init( ) {         // Loop through all forms in the document         for(var i = 0; i < document.forms.length; i++) {             var f = document.forms[i];  // the form we're working on now             // Assume, for now, that this form does not need any validation             var needsValidation = false;             // Now loop through the elements in our form             for(j = 0; j < f.elements.length; j++) {                 var e = f.elements[j];  // the element we're working on                 // We're only interested in <input type="text"> textfields                 if (e.type != "text") continue;                 // See if it has attributes that require validation                 var pattern = e.getAttribute("pattern");                 // We could use e.hasAttribute( ), but IE doesn't support it                 var required = e.getAttribute("required") != null;                 // Required is just a shortcut for a simple pattern                 if (required && !pattern) {                     pattern = "\\S";                     e.setAttribute("pattern", pattern);                 }                 // If this element requires validation,                 if (pattern) {                     // validate the element each time it changes                     e.onchange = validateOnChange;                     // Remember to add an onsubmit handler to this form                     needsValidation = true;                 }             }             // If at least one of the form elements needed validation,             // we also need an onsubmit event handler for the form             if (needsValidation) f.onsubmit = validateOnSubmit;         }     }     // This function is the onchange event handler for textfields that     // require validation. Remember that we converted the required attribute     // to a pattern attribute in init( ).     function validateOnChange( ) {         var textfield = this;                            // the textfield         var pattern = textfield.getAttribute("pattern"); // the pattern         var value = this.value;                          // the user's input         // If the value does not match the pattern, set the class to "invalid".         if (value.search(pattern) == -1) textfield.className = "invalid";         else textfield.className = "valid";     }     // This function is the onsubmit event handler for any form that     // requires validation.     function validateOnSubmit( ) {         // When the form is submitted, we revalidate all the fields in the         // form and then check their classNames to see if they are invalid.         // If any of those fields are invalid, display an alert and prevent         // form submission.         var invalid = false;  // Start by assuming everything is valid         // Loop through all form elements         for(var i = 0; i < this.elements.length; i++) {             var e = this.elements[i];             // If the element is a text field and has our onchange handler             if (e.type == "text" && e.onchange == validateOnChange) {                 e.onchange( ); // Invoke the handler to re-validate                 // If validation fails for the element, it fails for the form                 if (e.className == "invalid") invalid = true;             }         }         // If the form is invalid, alert user and block submission         if (invalid) {             alert("The form is incompletely or incorrectly filled out.\n" +                   "Please correct the highlighted fields and try again.");             return false;         }     } })( ); 




JavaScript. The Definitive Guide
JavaScript: The Definitive Guide
ISBN: 0596101996
EAN: 2147483647
Year: 2004
Pages: 767

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net