Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
143023864X_HT5.pdf
Скачиваний:
8
Добавлен:
21.02.2016
Размер:
7.98 Mб
Скачать

CHAPTER 8 USING THE FORMS API

<input type="text" id="firstname" name="first" required>

If no value is set on this field, either programmatically or by the user, the ability to submit this form is blocked. The required attribute is the simplest type of form validation, but the capabilities of validation are vast. Let’s discuss form validation in more detail now.

Checking Forms with Validation

Before we get too deep into specifics, let’s review what form validation really entails. At its core, form validation is a system for detecting invalid control data and flagging those errors for end users. In other words, form validation is a series of checks and notifications that let a user correct the controls of a form before submitting it to the server.

But what is form validation, really? It is an optimization.

Form validation is an optimization because it alone is not sufficient to guarantee that forms submitted to the server are correct and valid. It is an optimization because it is designed to help a web application fail fast. In other words, it is better to notify a user that a page contains invalid form controls right inside the page, using the browser’s built-in processing. Why bother with the expense of a network round trip just so the server can inform a user that there was a typo in the data entry? If the browser has all the knowledge and capability to catch errors before they leave the client, we should take advantage of that.

However, browser form checking is not sufficient to handle all errors.

Malicious or Misunderstood?

Brian says: “Even though the HTML5 specification goes a long way in improving the ability to check forms within the browser, it is still not a replacement for server validation. It may never be.

Obviously, there are many error conditions that require server interaction to verify, such as whether or not a credit card is authorized to make a purchase, or even basic authentication. However, even mundane validation cannot rely solely on clients. Some users may be using browsers that don’t support the form validation features. A few may turn off scripting altogether, which can end up disabling all but the simplest attribute-based validators. Yet other users can utilize an assortment of tools such as the Greasemonkey browser add-on to modify a page’s content to their…. err, content. This could include removing all form validation checks. Ultimately, it is not sufficient to rely on client-side validation as the sole means of checking any important data. If it exists on the client, it can be manipulated.

HTML5 Form validation lets users get important feedback fast, but don’t rely on it for absolute correctness!”

That being said, HTML5 does introduce eight handy ways to enforce correctness on form control entry. Let’s examine them in turn, starting with the object that gives us access to their status: the

ValidityState.

The ValidityState can be accessed from any form control in a browser that supports HTML5 Form validation:

var valCheck = document.myForm.myInput.validity;

204

CHAPTER 8 USING THE FORMS API

This simple command grabs a reference to the ValidityState object of a form element conspicuously named myInput. This object contains handy references to each of the eight possible validity statuses, as well as an overall validity summary check. You can get the overall state of this form by calling:

valCheck.valid

This call will provide a Boolean value which informs us whether or not all validity constraints are currently met on this particular form control. Think of the valid flag as a summary: if all eight constraints are passing, the valid flag will be true. Otherwise, if any of the validity constraints fail, the valid attribute will be false.

Note The ValidityState object is a live object. Once you grab a reference to it, you can keep a hold of it and the validity checks it returns will update as needed when changes occur.

As mentioned before, there are eight possible validity constraints on any given form element. Each can be accessed from the ValidityState by accessing the field with the appropriate name. Let’s look at what they mean, how they can be enforced on a form control, and how you can use the ValidityState to check for them:

valueMissing

Purpose: Ensure that some value is set on this form control Usage: Set the required attribute on the form control to true

Usage example: <input type="text" name="myText" required>

Details: If the required attribute is set on a form control, the control will be in an invalid state unless the user or a programmatic call sets some value to the field. For example, a blank text field will fail a required check, but will pass as soon as any text is entered. When blank, the valueMissing will return true.

typeMismatch

Purpose: Guarantee that the type of the value matches expectations (number, email, URL, and so

on)

Usage: Specify one of the appropriate type attributes on the form control

Usage example: <input type="email" name="myEmail">

Details: Special form control types aren’t just for customized phone keyboards! If your browser can determine that the value entered into a form control doesn’t conform to the rules for that type—for example, an email address without an @ symbol—the browser can flag this control as having a type mismatch. Another example would be a number field that cannot parse to a valid number. In either case, the typeMismatch will return true.

patternMismatch

Purpose: Enforce any pattern rule set on a form control which details specific valid formats Usage: Set the pattern attribute on the form control with the appropriate pattern

Usage example: <input type="number" name="creditcardnumber" pattern="[0-9]{16}" title="A credit card number is 16 digits with no spaces or dashes">

205

CHAPTER 8 USING THE FORMS API

Details: The pattern attribute gives developers a powerful and flexible way of enforcing a regular expression pattern on the value of a form control. When a pattern is set on a control, the patternMismatch will return true whenever the value does not conform to the rules of the pattern. To assist users and assistive technology, you should set the title on any pattern-controlled field to describe the rules of the format.

tooLong

Purpose: Make sure that a value does not contain too many characters Usage: Put a maxLength attribute on the form control

Usage example: <input type="text" name="limitedText" maxLength="140">

Details: This humorously-named constraint will return true if the value length exceeds the maxLength. While form controls will generally try to enforce the maximum length during user entry, certain situations including programmatic settings can cause the value to exceed the maximum.

rangeUnderflow

Purpose: Enforce the minimum value of a numeric control Usage: Set a min attribute with the minimum allowed value

Usage example: <input type="range" name="ageCheck" min="18">

Details: In any form controls that do numeric-range checking, it is possible for the value to get temporarily set below the allowable range. In these cases, the ValidityState will return true for the rangeUnderflow field.

rangeOverflow

Purpose: Enforce the maximum value of a numeric control Usage: Set a max attribute with the maximum allowed value

Usage example: <input type="range" name="kidAgeCheck" max="12">

Details: Similar to its counterpart rangeUnderflow, this validity constraint will return true if the value of a form control becomes greater than the max attribute.

stepMismatch

Purpose: Guarantee that a value conforms to the combination of min, max, and step Usage: Set a step attribute to specify the granular steps of a numeric value

Usage example: <input type="range" name="confidenceLevel" min="0" max="100" step="5">

Details: This constraint enforces the sanity of the combinations of min, max, and step. Specifically, the current value must be a multiple of the step added to the minimum value. For example, a range from 0 to 100 with steps at every 5 would not allow a value of 17 without stepMismatch returning true.

customError

Purpose: Handle errors explicitly calculated and set by the application code

Usage: Call setCustomValidity(message) to put a form control into the customError state Usage example: passwordConfirmationField.setCustomValidity("Password values do not

match.");

Details: For those cases where the built-in validity checks don’t apply, the custom validity errors can suffice. Application code should set a custom validity message whenever a field does not conform to semantic rules.

One common use case for custom validity is when consistency between controls is not achieved, for example if password confirmation fields don’t match. (We’ll delve into this specific example in the

206

CHAPTER 8 USING THE FORMS API

“Practical Extras” section.) Whenever a custom validity message is set, the control will be invalid and return the customError constraint as true. To clear the error, simply call setCustomValidity("") on the control with an empty string value.

Validation Fields and Functions

Together, these eight constraints allow a developer to find out exactly why a given form control is failing a validation check. Or, if you don’t care which specific reason is causing the failure, simply access the Boolean value valid on the ValidityState; it is an aggregate of the other eight constraints. If all eight constraints return false, then the valid field will return true. There are a few other helpful fields and functions on the form controls which can assist you in programming for validation checking.

The willValidate Attribute

The willValidate attribute simply indicates whether validation will be checked on this form control at all. If any of the above constraints—e.g. the required attribute, pattern attribute, etc.—are set on the control, the willValidate field will let you know that validation checking is going to be enforced.

The checkValidity Function

The checkValidity function allows you to check validation on the form without any explicit user input. Normally, a form’s validation is checked whenever the user or script code submits the form. This function allows validation to be done at any time.

Note Calling checkValidity on a form control doesn’t just check validation, it causes all resulting events and UI triggers to occur just as if the form had been submitted.

The validationMessage Attribute

This attribute isn’t yet supported by any current browser versions, but it might be by the time you read this. The validationMessage attribute lets you query programmatically a localized error message that the browser would display based on the current state of validation. For example, if a required field has no value, the browser might present an error message to the user that “This field requires a value.” Once supported, this is the text string that would be returned by the validationMessage field, and it would adjust according to the current state of validation on the control.

Validation Feedback

On the subject of validation feedback… one topic we’ve avoided thus far is how and when the browser should present the user with feedback on a validation error. The specification does not dictate the terms of how the user interface is updated to present an error message, and existing implementations differ fairly significantly. Consider the case for Opera. In Opera 10.5, the browser indicates that a validation error has occurred by marking the field in error with a popup message and a flashing red field:

207

CHAPTER 8 USING THE FORMS API

In contrast, at the time of this writing the Google Chrome 13 browser only navigates to the offending field and puts the focus there when an error is found. What is the correct behavior?

Neither is specified. However, if you would like to take control of the feedback shown to the user when a validation error occurs, there is an appropriate handler for you to do so: the invalid event.

Whenever a form is checked for validity—either due to the form being submitted, or due to the checkValidity function being called directly—any form in an invalid state will be delivered an invalid event. This event can be ignored, observed, or even cancelled. To add an event handler to a field which will receive this notification, add some code similar to Listing 8-2.

Listing 8-2. Adding Event Handlers for Invalid Events

// event handler for "invalid" events function invalidHandler(evt) {

var validity = evt.srcElement.validity;

//check the validity to see if a particular constraint failed if (validity.valueMissing) {

//present a UI to the user indicating that the field is missing a value

}

//perhaps check additional constraints here…

//If you do not want the browser to provide default validation feedback,

//cancel the event as shown here

evt.preventDefault();

}

// register an event listener for "invalid" events myField.addEventListener("invalid", invalidHandler, false);

Let’s break that code snippet down a bit.

First, we declare a handler to receive invalid events. The first thing we do inside that handler is check the source of the event. Recall that the invalid event is fired on the form control with a validation error. Therefore, the srcElement of the event will be the misbehaving form control.

From the source, we grab the validity object. Using this ValidityState instance, we can check its individual constraint fields to determine exactly what went wrong. In this case, since we know that our field has a required attribute on it, we first check to see if the valueMissing constraint has been violated.

If our check succeeds, we can modify the user interface on the page to inform the user that a value needs to be entered for the field in error. Perhaps an alert or an informative error region could be displayed? This is up to you to decide.

Once we’ve told the user what the error is and how to correct it, we need to decide if we want the browser itself to display its built-in feedback. By default, the browser will do just that. To prevent the browser from showing its own error message, we can call evt.preventDefault() to stop the default handling and take care of the matter entirely ourselves.

208