Using Dojo for Client-Side Validation

We all make mistakes, so input forms must anticipate that users will inadvertently enter bad data. Identifying and correcting these mistakes is an important job of an HTML form, and this chapter describes Dojo features that allow you to easily add validation.

2.1 Validating Form Fields

Validating input data on web pages is usually a function performed by the server. The web page allows the user to enter data, and when the Submit button is pressed, the browser wraps up the data into an HTTP request and sends it to the server. The server checks each data field to make sure it is valid, and if any problems are found, a new form along with error messages is sent back to the browser. Wouldn't it be much more useful if problems could be detected in the browser before a server request is made? This approach would provide two primary advantages. It would lighten the load on the server, and, more importantly, it would notify the user of a problem with a data field almost immediately after he or she entered the bad data. This supports the truism that errors are cheapest to fix the closer the detection is to the original creation of the error. For example, if there is a problem with a zip code field and the user is notified just after he enters the bad zip code, then he is still thinking about zip code and can easily make the correction. If the user isn't notified until the server response comes back, he's already stopped thinking about zip code—his mind has moved on to other concerns. This problem of context switching is especially difficult when the server returns errors for many different fields.

How can we drive validation closer to the entry of the data? There are two primary techniques available. The first technique involves trying to prevent the error from being entered at all. For example, if the form requires the user to enter a field that must contain a numeric value of a certain length, we can use the size attribute available in HTML to specify the maximum amount of characters the user can enter. So the user is prevented by the browser from entering more characters than are allowed. Following is an example from our form for the zip code field.

This initial validation markup gives us more optimism than is deserved. We might be hoping for many other attributes to provide some kind of client-side validation. Unfortunately, the size attribute is basically the extent of HTML-based validation techniques. There are no markup tags or attributes for minimum size or for data type. Nor is there a way in HTML to designate that a field is required.

That brings us to the second type of validation available to us in the browser. We can use JavaScript. Given the power of JavaScript, the sky is the limit in terms of types of validations we can perform. We can trigger a JavaScript function to run after the user enters a field, and that function can check to see if data is entered, check for a minimum or maximum length, or even perform sophisticated pattern matching using regular expressions.

Problem solved,correct? Not quite. The problem with depending on JavaScript as our validation technique is that we have to write lots of code to implement the checks. JavaScript code is required to perform the validation. Other JavaScript code tells the validation when to run. And even more JavaScript code is needed to display the error messages back to the user. Code, code, and more code. Suddenly, this approach doesn't seem as desirable anymore.

But this is where Dojo can come to the rescue. In this part of the tutorial, we explore how Dojo can help us with validation by combining the two techniques we've discussed. In other words, we'll be able to turn on validation by using simple HTML markup, but we'll let Dojo provide the complex JavaScript code automatically. Let's get started.

2.2 Tutorial Step 2—Adding Client-side Validation

In this step of the tutorial,we use Dojo to provide basic client-side validations. We look at a number of useful techniques within the context of making real enhancements to our form. One by one, we examine the fields that these techniques are appropriate for.

2.2.1 Validate the First Name Field

Let's look at the "First Name" field first. What are the validations that we need to apply? The data on this form feeds into our billing system, so the customer's name is very important—the field must be required.Are there any other validations? Not only do we want to get the data, but also we'd like it to be in a consistent format. Possibly the data should be stored in all capital letters. Or maybe we want to ensure that the data is not in all capitals. Let's choose the latter—but we'll still want to make sure that at least the first letter is capitalized. As in many of the issues related to validation,things are more complicated then they might first appear. For example, are we allowing enough room to enter long names? Will single-word names such as "Bono" be allowed? For our purposes, we'll keep it simple.

We turn on validation by using special attribute values in the HTML markup for these fields. The following code will add validation to the fields.

The code is formatted to be more readable by using line breaks. To summarize what has happened: All we've done is add some new attributes to the <input> tag for the field. Each of the new attributes affects the validation in some way.

Notice the following line of code from the preceding example:

This attribute is not a standard HTML <input> tag attribute. Depending on which editor you are using to modify the file, it may even be highlighted as an error. The dojoType attribute is only meaningful to the Dojo parser, which was referenced in step 1. Remember the code we needed to include the parser? It is shown here:

The parser reads through the HTML and looks for any tag that contains dojoType as one of its attributes. Then the magic happens.The parser replaces the element with the Dojo widget specified by dojoType. In this case, the widget dijit.form.ValidationTextBox is substituted for the Document Object Model (DOM) element created from the <input> tag.

How does Dojo know what to replace the tag with? That is determined by the specific widget. Each widget behaves a little differently. HTML markup and JavaScript code is associated with the widget in its definition, and that is how Dojo knows what to replace the original element with—which brings us to the missing piece of the puzzle. We need to tell Dojo to include the code for the widget by specifying the widget in JavaScript. To do that,we include the following JavaScript code after the link to Dojo and after the reference to the Dojo parser.

Notice that the name of the widget specified as the value for the dojoType attribute is the same as the argument for the dojo.require call. This is the linkage that allows Dojo to associate the HTML markup with the JavaScript code for that widget.

To emphasize this process, let's review the HTML markup specified in the original page and then compare it to the HTML markup after the parser runs. To see the original markup, we merely have to view the source of the file form.html. Seeing the new markup is a bit harder. The browser converts the original HTML into a DOM tree representing the various tags. The Dojo parser modifies the DOM elements using JavaScript, but the original source for the page is untouched. We need some tool that will convert the DOM (the browser's internal representation of the page) back into HTML for our review. The Firefox browser provides a DOM Inspector to do just that. An excellent add-on to Firefox, called Firebug, also allows the DOM to be inspected. Firebug also provides a number of excellent tools for developing web pages such as its DOM inspection capabilities we can use to inspect the DOM after the Dojo parser has run—so we can see exactly what it does. But before we see how the DOM changes, let's first review the original <input> tag for the first name field.

The code has been reformatted to make it more readable by adding some line breaks. The attributes from dojoType through trim are not valid HTML attributes. They are meaningful only to the Dojo parser and drive some features of the Dojo widget they pertain to. Now let's see what the HTML looks like after the parser runs.

The preceding code has also been reformatted for readability, adding line breaks and changing the order of the attributes a little. Notice that a number of valid HTML attributes have been added to the <input> DOM element such as tabindex, class, auto-complete, and disabled. And additionally, a number of Dojo-only attributes have been added such as widgetid, dojoattachevent, dojoattachpoint, invalid, and valuenow. We look at these in more detail in Part II,"Dojo Widgets,"but for now it's enough just to point out that the parser is rewriting our HTML. The parser is doing even more work that we can see here. It is associating various event handler functions to events that might occur on this DOM element. For instance, when the user enters or changes the value in the field,Dojo functions get called,which perform validation. And Dojo even creates objects that correspond to the HTML tags.We can't tell that this is happening just from seeing the HTML markup, but behind the scenes, that is exactly what Dojo is doing.

Let's review the other special Dojo attributes. Each Dojo widget has a set of properties that control its behavior. These properties are set by various Dojo widget attribute values.

The required="true" attribute setting tells Dojo that this field must be entered.

The propercase="true" attribute setting tells Dojo to reformat the field value entered by the user. In this case, the setting for propercase tells Dojo to make sure that the first letter is capitalized and subsequent letters are in lowercase. In other words, Dojo will put the entered value into the format for a typical proper noun.

The promptMessage="Enter first name." attribute setting tells Dojo to display a message next to the field to instruct the user on what kind of data can be entered into the field. The prompt message displays while the field is in focus.

The invalidMessage="First name is required." attribute setting causes Dojo to display a message next to the field if it fails the validation. In our case, if the user does not enter a value, then a message will appear.

The trim="true" attribute setting tells Dojo to remove any leading or trailing spaces from the entered value before sending it to the server.

Now let's run the page and see how it behaves. Because this is the first field on the page, the field gets focus, and the cursor immediately is placed on the input area for the "First Name" field.

Notice that we get a message box that says "Enter first name." Dojo calls this a Tool Tip, and it has dynamic behavior. It is only displayed when the field has focus (the cursor is in the field), and once the field loses focus, the message disappears. The message appears on top of any visible element below it, so there is no need to leave room for it when designing your page.

Try entering different values in the field and then press <tab> to leave the field. For example, enter "joe" and watch it be transformed into "Joe" with leading and trailing spaces removed and the first letter of the name capitalized.

NOTE: You might not agree with the various validations I have chosen. For example, one early review of this text pointed out that "LaToya" would be a hard name to validate. You could probably make a case for different validations, and I could probably agree with you. But I've chosen the ones I have not only to represent my example application, but also to highlight certain Dojo features—so I'm sticking to them!