This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND

Get Instant Validation with JScript Procedures
Carl Nolan

Does your Web site suffer from an endless parade of database errors? Turn your code from chump to champ with client-side validation, before the problems start.

Download the code (3KB)

When it comes to reusing code while developing browser-centric applications, developers are still in their infancy. I'm not talking about cutting and pasting already developed code, but the complete reuse of developed objects and source libraries. This problem has been addressed with the advent of scriptlets and with behaviors in Microsoft® Internet Explorer 5.0. However, if you support other browsers, your options are a bit more limited.
      In a recent project I wanted to reuse code for something that is fundamental to most if not all database-centric applications: form submission validation. For basic validation, tools such as Microsoft FrontPage® accomplish this very well on a per-form basis. But I wanted to deliver more specific validation routines that could be centrally managed and easily applied to the pages of a Web site.
      I needed the ability to handle very specific field type validation with very little code. This would improve the development, readability, and maintainability of my Web pages. More importantly, the solution had to provide reusable HTML code—a must for any large-scale Web-oriented project.

The JScript Solution
      In developing reusable HTML code, I wanted all the provided functionality to be encapsulated into a single, easy-to-use object. As an object-oriented language, JScript® is ideal for this purpose. The method described here has some advantages and disadvantages (see Figure 1). Although my solution uses JScript, the implementation can be in either VBScript or JScript because a page isn't restricted to a single scripting language. Hence, implementation samples will be given in both languages.
      The basis of the solution is a JScript file I'll create that will be included in each page requiring form field validation. The page will reference the JScript file by having the following script tag in the <head> section of the page:


 <script language="JavaScript" src="validation.js"></script>
After this inclusion, the code and created object are available for use within the page. This is a conventional HTML script tag, but instead of including script between the opening and closing tags, the script is provided by the file listed in the source attribute.

The Validation Object
      The purpose of this script file is to construct a JScript object called Validation whose functions are used for form field validation. As a simple example, consider the often-used validation applied to comboboxes. The first item is not a valid selection (it is used to indicate a required action). The defined Validation object function itemSelected will return a value of True if a valid selection has been made, and a False value if the first item has been selected, notifying the user of the exception. This allows a field item to be validated with a single statement:


 validation.itemSelected(document.all.lstMyComboBox);
      So what's in this source file that makes field validation so simple? The following two lines of JScript create the Validation object:

 var validation = new Object;
 validation = validation_construct();
These lines are not part of any function, causing them to be executed as the Web page is constructed. The Validation object is first declared, and then the constructor validation_ construct is called. See Figure 2 for the complete validation file source code.
      In the function validation_construct, "this" refers to the actual Validation object. This property and the assignment of function pointers as object properties allows the validation function to be constructed. (I used JScript here because VBScript did not let you construct objects until version 5.0.)
      The display_name function provides a means for obtaining the name of the field being validated. Within the Web page, an attribute must be added to the element being validated using the Validation object. This attribute should specify the name used for reporting exceptions. This can be achieved within the field tag definition or by using Dynamic HTML:

 document.all.lstMyComboBox.setAttribute("DisplayName","My Combobox selection");
      The Validation object functions are designed to work as part of a validation event function pair. The event function is defined to allow an event to hook directly into the Validation object. In JScript this is usually achieved by using a function pointer on the onchange event:

 document.all.lstMyComboBox.onchange = validation.eventItemSelected;
      A better implementation of the Validation object would be to use the methods during the form's submission. This would allow a user to input a form of data without being interrupted by exception messages. Using this standard technique, the Validation object can be implemented using JScript (see Figure 3) or VBScript (see Figure 4). The important point to note in each of these samples is the method in which the form submission is canceled. For a more detailed look at DHTML and form processing, I recommend the book Inside Dynamic HTML, by Scott Isaacs (Microsoft Press, 1998).

Adding Complexity
      The simple samples I just covered are stepping stones to creating a set of easily reusable code for use throughout the enterprise. Let's say you're developing a human resources Web-based application. You'll need to develop pages that create new employee records, maintain employee personal information, spouse personal information, and employee banking information.
      Every page will hold some simple address information, in addition to many other repeated data fields. In the same way a relational database may contain user-defined data type definitions for items with the same specifications, creating a validation method that encompasses the types of data to be validated has enormous benefits. Not only is all the code for validation centralized and easy to change as the application demands, but the pages that implement these validations are greatly simplified in content and maintainability.

Figure 5: Personal Information Form
      Figure 5: Personal Information Form

      The personal information form in Figure 5 shows some of the basic types of data that may be duplicated across many pages within a Web site. If you were developing this page, you would have to include code that would be duplicated across many pages. Figure 6 shows that code for a page that utilizes the JScript Validation object. Not only has the page's development and readability been simplified, but you can also easily make modifications to the requirement for the field validations across all pages with the developed application.
       Figure 7 uses a Validation object that provides validations for non-blank entries, numbers, hourly time entries in quarterly increments, dates, ZIP code formats, and Social Security numbers. This list is by no means exhaustive, but it does provide a good idea of the capabilities of such a centralized method of code creation.
      The samples I've given are for some general types of data, but in an enterprise application, the object can validate more application-specific types of data. Such items may include product codes requiring a particular pattern of numbers, phone numbers, business accounting codes, and so on.
      The power of this solution becomes even more apparent as the application requirements change. Say your application initially accepts only U.S. ZIP codes, but changing circumstances require the user to input Canadian postal codes as well. To make this change all you need to do is edit the single ZIP code validation routine to accept whatever additional formats you require—a far cry from modifying all the pages that allow ZIP codes to be entered.

The Validation Object Revisited
      So how does the Validation object actually perform validation? In the Web page itself, only two items have to be executed. After the page is loaded, the items to be validated have attributes set, describing both the display name of the field and a default value (even this is an optional step). This is performed by the setAttribute function of HTML tag parameters. The second step is where the actual validation takes place. As I mentioned earlier, this can be performed in the item's onchange, or possibly onblur, event. The preferred method is processing all the form fields upon submission.
      When the personal information form is submitted, the frmPersonalSubmit function is executed. This routine just calls the appropriate validation methods and return the appropriate value. If an item fails the validation, a message box is displayed explaining the reason for the error, and that item then receives the focus on the page.
      The functions that actually perform the validation are those that begin with the prefix "vs;" those for event processing have an "es" prefix. (The names are designed to prevent function name collisions, as all functions in the source file are exposed to the implementation page.) Utilizing the document object that is passed into the function, the appropriate validation is performed. If validation fails, a value of False is returned and an alert box appears. The form submission uses this return value in deciding to cancel the form submission:


 item.focus();
 alert(strErrorMsg);
 return false;
      The actual method used for validation can vary immensely. You can use string scanning (using the charAt function), simple math routines, and JScript regular expressions. Regular expressions are powerful in that you can test a string to see if it matches a defined pattern. This technique is used for the validation of ZIP codes, Social Security numbers, and email addresses. The regular expression test method allows you to test the string. Regular expressions are defined with a pattern enclosed by the / character. An example of a regular expression for a Social Security number is as follows:


 /^\d{3}-\d{2}-\d{4}$/.test(item.value)
Validating a date is performed by parsing the string expression into its equivalent millisecond value. Testing the returned value for a valid number completes the validation check.


 isNaN(Date.parse(item.value))
      As mentioned earlier, each validation routine begins by obtaining the name of the object it is validating by calling the display_name function. If necessary, a default value is also obtained by calling the default_value function. This function returns the value of a field attribute called defaultValue. The validation routine makes this assignment to the field's value when a user has not entered any data, or has blanked out the original value. A defaultValue attribute is not explicitly defined, but is actually the value of the field's value attribute. This value, which is initially displayed when the page is loaded, is also placed into the field when a reset is processed.
      You may have noticed that the validation routines are actually passed the document field objects. The objects are used (rather than the values that are being validated) because all JScript objects are passed by reference. Passing the entire object instead of the value makes it possible for the validation to modify the item's value. This is advantageous for processing such as removing leading and trailing spaces and displaying data in a consistent format.
      This concept of setting and getting field attributes could be further extended for customizable validation parameters. Say you wanted to ensure a date is within a particular range, the Web page could set field attributes called lowDateValue and highDateValue. The validation routine could then get these values (in the same way the displayName attribute is obtained) to perform the appropriate range checking.

Extensions to the JScript Objects
      One positive side effect of having all the functions in the script file exposed is the extensions provided to the built-in JScript objects: String and Date. Using the prototype property, methods can be added to these standard objects, and they can be used as if they were defined as part of the JScript object. This is how the methods Trim and toSimpleForm are defined.
      In the Trim method a function is defined that will return a string equating to the original value, minus its leading and trailing spaces (see the function trim_string in Figure 7). Adding the newly defined function to the String prototype function then extends the String object:


 String.prototype.Trim = trim_string;
Similarly, the date validation routine formats the date into a standard simple format via the toSimpleForm function, assigned to the Date prototype function:

 Date.prototype.toSimpleForm = date_toSimpleForm;
This date conversion function merely converts the original date to a local string, then removes the time portion. The actual date that is output will depend on the user's local date format settings:

 var toSimpleForm = new String;
 toSimpleForm = this.toLocaleString();
 toSimpleForm = toSimpleForm.substring(0,toSimpleForm.indexOf(' '));
JScript handles date calculations so that dates like 01/32/98 are parsed correctly. This date is output intelligently as 02/01/98. In other words, it knows that the 32nd of January should really read the 1st of February.

Including Key Press Processing
      To prevent the accidental input of invalid characters, you can use key press processing. Note that conventional validation still needs to take place, as pasting characters into a field will not initiate a key press event.
      Providing code for processing keystrokes can follow exactly the same format as the conventional validation method. You can construct an object with a series of methods that can be hooked to a field's onkeypress event (see Figure 8). The code can be included directly in the script file for the Validation object, or maintained in a separate script file.
      The code in Figure 8 constructs an object called keyPressInput. This object's methods can be hooked directly to the onkeypress of the required fields. Say a field is designed to collect numeric values. The input must always be a single number or a period, provided one has not already been entered. To prevent the user from typing in alphabetic characters or even a second period, the field onkeypress event could be hooked to the keyPressInput object's numeric method. In JScript, a single line can do this easily:


 document.all.txtNumericField.onkeypress = keyPressInput.numeric
In VBScript, a default function that will call the appropriate function of the defined object must be created:

 Sub txtNumericField _OnKeyPress()
     Call keyPressInput.Numeric()
 End Sub
Build Your Enterprise Objects
      I hope this article has provided you with some new ways to centralize all your Web page scripting code. The samples in the article are fundamental to most, if not all, large-scale Web-oriented projects. Building on this foundation can greatly improve your development team's productivity and make it easier to maintain a Web site.
      Not only can the types of data being validated be expanded, but the functions provided by the Validation object can also be expanded. The object can validate the data and provide a method for returning acceptable values. These values could then be presented on the page by dynamically building a combobox. This would once again improve the Web site's maintainability; as the data validation requirements change, only a single script file would have to be updated.

MSDN
http://msdn.microsoft.com/workshop/languages/jscript/handling.asp

From the January 1999 issue of Microsoft Internet Developer.