8.3 Preventing Form Submission upon Validation Failure
NN 2, IE 3
8.3.1 Problem
You want a validation
function that detects incorrect data entry to halt the submission of
the form until the user corrects the data entry.
8.3.2 Solution
Batch validation checking typically
operates from the
onsubmit event handler of the
form element. Submission is aborted if the event
handler evaluates to return
false. Include the return
statement in the event handler assignment, and let the validation
function supply the Boolean value based on its findings:
<form ... onsubmit="return validateForm(this)">
8.3.3 Discussion
You can implement batch validation by way of a master function that
calls the individual validation functions as needed. To demonstrate,
let's create a small form with numerous control
types in it. Text fields execute real-time validation, while the
form's onsubmit event handler
performs the batch validation. Both validation types use the
validation functions shown in Recipe 8.2 (either the string parsing
or regular expression varieties). Here's the
form's HTML:
<form method="GET" action="cgi-bin/register.pl"
name="sampleForm" onsubmit="return validateForm(this)">
First Name: <input type="text" size="30" name="name1" id="name1"
onchange="isNotEmpty(this)" /><br>
Last Name: <input type="text" size="30" name="name2" id="name2"
onchange="isNotEmpty(this)" /><br>
Email Address: <input type="text" size="30" name="eMail" id="eMail"
onchange="if (isNotEmpty(this)) {isEMailAddr(this)}" /><br>
Your Region: <select name="continent" id="continent">
<option value="" selected>Choose One:</option>
<option value="Africa">Africa</option>
<option value="Asia">Asia</option>
<option value="Australia">Australia/Pacific</option>
<option value="Europe">Europe</option>
<option value="North America">North America</option>
<option value="South America">South America</option>
</select><br>
Licensing Terms:
<input type="radio" name="accept" id="accept1" value="agree" />I agree
<input type="radio" name="accept" id="accept2" value="refuse" />I do not agree
<br>
<input type="reset" /> <input type="submit" />
</form>
You can see the form in Figure 8-1. As the user
tabs and clicks through the form, typically the only validation
taking place is in the email text box. Tabbing through the empty name
fields without making any changes won't trigger the
onchange event handlers there (another reason why
batch validation is needed). In this form, we also want to make sure
that a choice is made from a select element, and
that a member of the radio button group is clicked (some designers
might question delivering radio buttons without a default selection,
but this example requires no initial selection).
When the user clicks the Submit button, the validateForm(
) function executes to perform
validations of all required form controls. The calls to the
validations are cascaded so that if there are multiple errors and the
user corrects the first one to be reported, subsequent clicks of the
Submit button find an error lower in the form than a previous one:
function validateForm(form) {
if (isNotEmpty(form.name1)) {
if (isNotEmpty(form.name2)) {
if (isNotEmpty(form.eMail)) {
if (isEMailAddr(form.eMail)) {
if (isChosen(form.continent)) {
if (isValidRadio(form.accept)) {
return true;
}
}
}
}
}
}
return false;
}
Validation functions for a select element and
radio button group are not among routines in Recipe 8.2, but are
shown here:
// validate that the user made a selection other than default
function isChosen(select) {
if (select.selectedIndex = = 0) {
alert("Please make a choice from the list.");
return false;
} else {
return true;
}
}
// validate that the user has checked one of the radio buttons
function isValidRadio(radio) {
var valid = false;
for (var i = 0; i < radio.length; i++) {
if (radio[i].checked) {
return true;
}
}
alert("Make a choice from the radio buttons.");
return false;
}
Note that the select element design assumes that
the first item is an invalid choice.
All of the functions feed back to the main dispatching function. If
any one validation fails, the dispatching function returns
false to the onsubmit event
handler, forcing it to evaluate to return
false and thus aborting the submission. But if all
validations return true, the dispatching function
also returns true to the event handler, allowing
the submission to continue normally.
Relying on the
onsubmit event handler means that the user could
disable JavaScript in the client to bypass client-side validation.
This is a good reason to duplicate validation on the server. But if
you'd rather perform all validation on the client
and you know that all users have scriptable browsers, consider using
a button-type input element
instead of a true submit-type
input element. Let the button's
onclick event handler invoke the batch validation
function and (if validation succeeds) the submit(
) method of the form object. Under these conditions, the
user can't submit the form with JavaScript turned
off.
8.3.4 See Also
Recipe 8.2 for individual data validation functions; Recipe 8.4 for
focusing and selecting text in an invalid text field; Recipe 2.12 for
date field validation suggestions.
|