JavaScript
An Introduction (cont.)
Part VI: Form Validation
1. Next is an example of a form that uses JavaScript to calculate totals.
You'll use this to add validation, which let's you check the submissions
before they are sent off to a CGI script.
Below is the entire script, without validation (copy and paste this
"as is" into a text editor):
<HTML>
<HEAD><TITLE>Order Form</TITLE>
<SCRIPT>
// function to calculate the total cost field
function Total() {
var tot = 0
tot += (40.00 * document.order.qty1.value);
tot += (69.95 * document.order.qty2.value);
tot += (99.95 * document.order.qty3.value);
tot += (4.95 * document.order.qty4.value);
document.order.totalcost.value = tot;
}
// function to update cost when quantity is changed
function UpdateCost(number, unitcost) {
costname = "cost" + number;
qtyname = "qty" + number;
var q = document.order[qtyname].value;
document.order[costname].value = q * unitcost;
Total();
}
</SCRIPT>
</HEAD>
<BODY>
<H1>Order Form</H1>
<FORM NAME="order">
<B>Name:</B><INPUT TYPE="text" NAME="name1" SIZE=20>
<B>Phone:</B><INPUT TYPE="text" NAME="phone" SIZE=15>
<B>Email:</B><INPUT TYPE="text" NAME="email" SIZE=20><BR>
<B>Shipping Address:</B><BR>
<TEXTAREA NAME="billto" COLS=40 ROWS=4></TEXTAREA>
<B>Products to Order:</B><BR>
QTY: <INPUT TYPE="text" NAME="qty1" VALUE="0" SIZE=4
onChange = "UpdateCost(1, 40.00);">
Cost: <INPUT TYPE="text" NAME="cost1" VALUE="0" SIZE=6>
($40.00 ea) Fictional Spreadsheet 7.0<BR>
QTY: <INPUT TYPE="text" NAME="qty2" VALUE="0" SIZE=4
onChange = "UpdateCost(2, 69.95);">
Cost: <INPUT TYPE="text" NAME="cost2" VALUE="0" SIZE=6>
($69.95 ea) Fictional Word Processor 6.0<BR>
QTY: <INPUT TYPE="text" NAME="qty3" VALUE="0" SIZE=4
onChange = "UpdateCost(3, 99.95);">
Cost: <INPUT TYPE="text" NAME="cost3" VALUE="0" SIZE=6>
($99.95 ea) Fictional Database 7.0<BR>
QTY: <INPUT TYPE="text" NAME="qty4" VALUE="0" SIZE=4
onChange = "UpdateCost(4, 4.95);">
Cost: <INPUT TYPE="text" NAME="cost4" VALUE="0" SIZE=6>
($4.95 ea) Instructional Booklet<HR>
<B> Total Cost:</B>
<INPUT TYPE="text" NAME="totalcost" SIZE=8><HR>
<INPUT TYPE="submit" NAME="submit" VALUE="Send Your Order">
<INPUT TYPE="reset" VALUE="Start Over">
</FORM>
</BODY>
</HTML>
|
It includes a Total function to add up the submissions and
an UpdateCost function to calculate the total cost whenever a
number is changed in the qty text boxes. Notice the onChange
event handlers in the body of the page.
2. To add the validation, you will first determine what should be validated.
You should remember that validation can only do so much, that it really
only saves you trouble before you pass on variables to a CGI script. For
instance, in this example you'll check that the submission to:
- the name field has at least six characters
- the email field has at least five characters and includes the @ symbol
- and that the total cost does not equal zero
3. First you'll create two functions to handle the checking of lengths
and then email. To check the length, you'll use this function:
// function to validate the length of an item
function ValidLength(item, len) {
return (item.length >= len);
}
|
This takes the name of an item and the length you require and checks
to see if the length is greater or equal to the len . Using the
return statement will return a value of true or false for the
function ValidLength.
// function to validate an email address
function ValidEmail(item) {
if (!ValidLength(item,5)) return false;
if (item.indexOf ('@') == -1) return false;
return true;
}
|
This function does two things. First, it uses the previous function
to check if the submission in the email text box is greater or equal to
a length of five. The ! before the function call means "not".
So the line literally reads "if the length of the item is not at
least five characters, then this ValidLength function is false."
Then it uses the indexOf() method (part of the built-in String
object) to find the index value of the character @ in the item. If it
can't find this character, the value will equal -1 and ValidEmail
is again false.
4. Now you can create a larger function to handle all the three validations,
using the previous two functions:
// global variable to catch errors
var errfound = false;
// main Validate function
function Validate() {
errfound = false;
if (!ValidLength(document.order.name1.value,6))
error(document.order.name1,"Yah, try that name again.");
if (!ValidEmail(document.order.email.value))
error(document.order.email, "Try a real email address.");
if (document.order.totalcost.value == "")
error(document.order.qty1, "Come on, moneybags - buy something!");
return !errfound;
// true if there are no errors
}
|
The function includes all three checks for the correct submission. If
any of the conditionals are "not" valid, then the error
function runs. Here's how it is defined:
function error(elem, text) {
// abort if we already found an error
if (errfound) return;
window.alert(text);
elem.select();
elem.focus();
errfound = true;
}
|
In error, you'll first check to see if the variable is actually
true; if so, the script leaves the function. Otherwise an alert window
will pop up with the text specified displayed inside. Next, the script
uses the select() method of the built-in document object
to select all the text inside the elem variable, and then puts your cursor
inside of the text box with the focus()method. This is very powerful,
allowing you to control for the user where they are supposed to look for
the validation and dropping their cursor right inside for them to edit
the text.
5. The last thing is to redo the FORM tag to run the Validate
function when submitted:
<FORM NAME="order" onSubmit="return Validate();">
|
The way this is written, the Validate function is called and
if it returns a false value (if something is invalid) the data doesn't
get submitted to the CGI.
6. Here's the entire script, with the added portions in red:
<HTML>
<HEAD><TITLE>Order Form</TITLE>
<SCRIPT>
// function to calculate the total cost field
function Total() {
var tot = 0
tot += (40.00 * document.order.qty1.value);
tot += (69.95 * document.order.qty2.value);
tot += (99.95 * document.order.qty3.value);
tot += (4.95 * document.order.qty4.value);
document.order.totalcost.value = tot;
}
// function to update cost when quantity is changed
function UpdateCost(number, unitcost) {
costname = "cost" + number;
qtyname = "qty" + number;
var q = document.order[qtyname].value;
document.order[costname].value = q * unitcost;
Total();
}
// function to validate the length of an item
function ValidLength(item, len) {
return (item.length >= len);
}
// function to validate an email address
function ValidEmail(item) {
if (!ValidLength(item,5)) return false;
if (item.indexOf ('@') == -1) return false;
return true;
}
// global variable to catch errors
var errfound = false;
// main Validate function
function Validate() {
errfound = false;
if (!ValidLength(document.order.name1.value,6))
error(document.order.name1,"Yah, try that name again.");
if (!ValidEmail(document.order.email.value))
error(document.order.email, "Try a real email address.");
if (document.order.totalcost.value == "")
error(document.order.qty1, "Come on, moneybags - buy something!");
return !errfound;
// true if there are no errors
}
function error(elem, text) {
// abort if we already found an error
if (errfound) return;
window.alert(text);
elem.select();
elem.focus();
errfound = true;
}
</SCRIPT>
</HEAD>
<BODY>
<H1>Order Form</H1>
<FORM NAME="order" onSubmit="return Validate();">
<B>Name:</B><INPUT TYPE="text" NAME="name1" SIZE=20>
<B>Phone:</B><INPUT TYPE="text" NAME="phone" SIZE=15>
<B>Email:</B><INPUT TYPE="text" NAME="email" SIZE=20><P>
<B>Shipping Address:</B><BR>
<TEXTAREA NAME="billto" COLS=40 ROWS=4></TEXTAREA><P>
<B>Products to Order:</B><BR>
QTY: <INPUT TYPE="text" NAME="qty1" VALUE="0" SIZE=4
onChange = "UpdateCost(1, 40.00);">
Cost: <INPUT TYPE="text" NAME="cost1" VALUE="0" SIZE=6>
($40.00 ea) Fictional Spreadsheet 7.0<BR>
QTY: <INPUT TYPE="text" NAME="qty2" VALUE="0" SIZE=4
onChange = "UpdateCost(2, 69.95);">
Cost: <INPUT TYPE="text" NAME="cost2" VALUE="0" SIZE=6>
($69.95 ea) Fictional Word Processor 6.0<BR>
QTY: <INPUT TYPE="text" NAME="qty3" VALUE="0" SIZE=4
onChange = "UpdateCost(3, 99.95);">
Cost: <INPUT TYPE="text" NAME="cost3" VALUE="0" SIZE=6>
($99.95 ea) Fictional Database 7.0<BR>
QTY: <INPUT TYPE="text" NAME="qty4" VALUE="0" SIZE=4
onChange = "UpdateCost(4, 4.95);">
Cost: <INPUT TYPE="text" NAME="cost4" VALUE="0" SIZE=6>
($4.95 ea) Instructional Booklet<HR>
<B> Total Cost:</B>
<INPUT TYPE="text" NAME="totalcost" SIZE=8><HR>
<INPUT TYPE="submit" NAME="submit" VALUE="Send Your Order">
<INPUT TYPE="reset" VALUE="Start Over">
</FORM>
</BODY>
</HTML>
|
7. To test this script, try load the page and without typing anything
into a text box, hit the submit button. You should be lead sequentially
through the validation process.