Advanced:
Client Side Form Validation.
The
introduction of JavaScript has made possible many new things
that can be done with a web page, all of which hinge around
the ability to respond to input from the client, or visitor
end of the Internet connection. Client side form validation
is arguably the most powerful and useful of these possibilities.
With form validation we can save time and aggravation on
the part of our visitors by performing some error checking
before submitting visitor information to the server and
making them wait, perhaps only to find that they have forgotten
to enter data in a field or that they have perhaps mistyped
something. In this example, we will discuss how form validation
can be done.
Table
of Contents
How
a Form Works
Validating
the Form Before Submission
Capturing
a Submit with JavaScript
The
NOSCRIPT Safety Catch
The
Working Example
How
a Form Works
Let's
begin by examining how a form works through a typical exchange
between a visitor and a web server. The visitor types in
the URL they want to visit, or clicks a hyper link, and
then the server searches for, and hopefully finds, the requested
page and sends it to the visitor's IP to be displayed by
the web browser. Let's say that the web page contains a
form requesting visitor information, which is then filled
out and submitted by the visitor. All of the input from
that form is passed to the server, along with the URL of
a web page or CGI program, which then must attempt to make
sense of it and respond appropriately. This process has
been an integral piece of the Internet for many years now.
However, this exchange takes up precious time, and it can
be very annoying if, for example, we make a mistake when
filling out a form field. The exchange can be time-consuming
because when we fill out a form, the information is passed
to the server, which then has to determine if an error has
occurred. The server then must send us an error page which
informs us that an error has occurred, along with information
telling us how to correct the error.
With
JavaScript we can build forms which can check things before
we send them to the server. This way, if an error has occurred,
we can inform the visitor before they have to wait for the
error to be discovered and indicated by the server. Let's
look at this problem in more detail by creating a form and
seeing how it behaves. Here is a basic form with a few of
the most commonly used controls.
<FORM NAME="MY_FORM" METHOD="GET" ACTION="/cgi-bin/respond">
<TABLE BORDER=1 WIDTH=90% ALIGN=CENTER>
<TR>
<TD>Hidden Variable Here</TD>
<TD><INPUT TYPE="HIDDEN" NAME="HIDDEN_VAR" VALUE="BLAH BLAH"></TD>
</TR>
<TR>
<TD>User Name</TD>
<TD><INPUT TYPE="TEXT" NAME="USER_NAME" VALUE=""></TD>
</TR>
<TR>
<TD>MY REAL NAME?</TD>
<TD><INPUT TYPE="CHECKBOX" NAME="REAL_NAME"></TD>
</TR>
<TR>
<TD>Select Box</TD>
<TD><SELECT NAME="HEIGHT">
<OPTION NAME="HEIGHT" VALUE="" SELECTED>SELECT ONE</OPTION>
<OPTION NAME="HEIGHT" VALUE="TALL">TALL</OPTION>
<OPTION NAME="HEIGHT" VALUE="SMALL">SMALL</OPTION>
</SELECT></TD>
</TR>
<TR>
<TD><INPUT TYPE="SUBMIT" VALUE="Submit"></TD>
<TD><INPUT TYPE="RESET" VALUE="Reset"></TD>
</TR>
</TABLE>
</FORM>
The
visitor who visits the web page containing the HTML form
declaration above will see the code rendered by their web
browser as the following output:
Let's
say that our visitor declares his name as "John,"
indicating with a check mark that it is his real name, and
that "John" considers himself to be TALL. (The
completed form appears below.)
When
our visitor presses the "Submit" button, the following
URL is produced in the address field of our Internet browser.
/cgi-bin/respond?HIDDEN_VAR=BLAH+BLAH&USER_NAME=JOHN&REAL_NAME=on&HEIGHT=TALL
The
click of the "Submit" button generates a form
submit event. This event causes all of the fields that appear
on that form (and any type="hidden" fields which
do not get drawn in the visitor's browser) to be combined
together in name and value pairs and then
appended to the end of the address contained in the ACTION="..."
section of the form. By looking at the example above, we
know that our form action was set as ACTION="/cgi-bin/respond,"
which we see at the beginning of the URL. This is the web
page or CGI that we are requesting from the server. Following
the file path and file name, we see a question mark (this
is the start of the "search" part of the URL,
and it is followed by each field in the form that had any
data (in the order that the fields were created). We see
our hidden variable first: its name was "HIDDEN_VAR",
and the value we set "BLAH BLAH" has been "URL
encoded" to "BLAH+BLAH" (changing the spaces
to "+" signs, which are more friendly to web servers.)
The name/value pairs are separate by "&" ampersands,
which always indicate a split between variables in a URL.
The second variable USER_NAME our visitor entered as "JOHN",
then the checkbox REAL_NAME which was checked, so the value
is "on," and last HEIGHT in which TALL was selected.
Validating
the Form Before Submission
By
carrying the example forward, let's say that the server
is going to check to make sure that there is a name in the
User Name field. It's also going to check that the visitor
has explicitly stated that this is his or her "real"
name by placing a check mark in the checkbox field. The
server will also check that either TALL or SMALL has been
selected. With client validation we will check each of these
condition first, before the form is ever submitted. We can
do this by writing some JavaScript to examine each field
we want to validate and then continuing or returning to
the form, depending on whether the user has filled out that
specific piece of information. Here is how to check the
form that we have created in our example.
<SCRIPT><!--
function validate(){
if(document.MY_FORM.USER_NAME.value.length<1){
alert('Please fill out your name');
return;
}
if(document.MY_FORM.REAL_NAME.checked==false){
alert('Please supply your real name.');
return;
}
if(document.MY_FORM.HEIGHT.selectedIndex<1){
alert('Please select your height');
return;
}
// Just in case you want to determine the
// -VALUE- of what was selected
// rather than just whether an item greater
// than index item 0 was selected here is how.
//
// document.MY_FORM.HEIGHT[MY_FORM.HEIGHT.selectedIndex]Value
//
// (the breakdown...)
// first "document.MY_FORM.HEIGHT..." is the form name and specific control.
// second "[MY_FORM.HEIGHT.selectedIndex]" is the array index of the selected item
// third "value" is of course the value of that item.
}
//--></SCRIPT>
To access
each of our controls, we have to use JavaScript to progress
down through the Document Object Model of the web page.
The uppermost* part of this DOM is the "document"
object. Below that is our form element, which we named "MY_FORM".
If you get in the habit of assigning a name to the significant
elements of your HTML, then accessing them later through
JavaScript or other client technologies like VBScript, for
example, become much easier and more intuitive. Below the
form elements are the specific controls within that form.
Our first control to validate is "USER_NAME",
which we access with the name that we assigned. The properties
of that control include "value," which is the
container that our visitor entered data into; one of the
properties of "value" is "length," which
as you might have guessed is the length, in characters,
of that value. So, document.MY_FORM.USER_NAME.value.length
returns the number of characters that the visitor typed
into the control requesting his or her name. The name "John"
has four characters, so the value returned is .... tada
4.
The
second control we want to validate is the checkbox accessed
at document.MY_FORM.REAL_NAME, and in this case the value
we are looking for is whether the box is checked. The condition
"checked" is a boolean condition, meaning it is
either TRUE if it is checked, or FALSE if it is not checked.
So we examine the control to see if it is false, and if
it is, then we display an error message and return to the
form instead of continuing to the next check.
The
final validation we perform is to confirm that the visitor
has selected on of the options in the HEIGHT control. A
"select" control is actually an array of containers,
accessing it can be complicated if you are not familiar
with arrays. In our case, validation is fairly simple because
we are merely checking the value of "selectedIndex"
to see that it is greater than 0. The "selectedIndex"
property is a number which indicates whether the visitor
has click on a item on the "select" list. If nothing
has been selected, the value will be -1; if the first item
has been selected, then the value will be 0, and so on.
Capturing
a Submit with JavaScript
So
now how do we make the form use the JavaScript that we created?
Well, this can be done a few ways, some better than others.
First, to simply make this work, we need to capture an event
and have the validate function that we wrote, called when
the event occurs. In this case, we case use either "onsubmit"
or the "onclick" event.
To
use onsubmit, add "onsubmit='javascript:validate();'"
to the <FORM> tag, such as <FORM NAME="MY_FORM"
ONSUBMIT="javascript:validate()">. This method
is not very good, however, because it doesn't intercept
the form submission; it simply calls the validate function
-in addition- to submitting the form.
To
use the onclick event, add "onclick='javascript:validate();'"
to the <INPUT TYPE="SUBMIT"> button, such
as <INPUT TYPE="SUBMIT ONCLICK="javascript:validate();">.
This method is better than the ONSUBMIT method, BUT it suffers
from the same problem; it does not intercept the submission;
instead, it simply calls the validate function BEFORE submitting
the form. Well, that's what we want to do, right? Yes, but
what if we detect an error? If we detect an error, then
we do not want to submit the form at all, and instead we
want to inform users of the problem and put them in a position
to resolve the problem WITHOUT having to wait to have the
server report the same error again. So the solution is to
change the "SUBMIT" input instead to a "BUTTON"
input.
<INPUT TYPE="BUTTON" VALUE="Submit" ONCLICK="javascript:validate();">
This
way when the user presses the button, no submit event is
ever generated, so we don't have to worry about stopping
it in the case of an error. This way we can validate the
input, and if there is NO error and we are ready to submit
the users input, we generate the submit event ourselves,
like this.
document.MY_FORM.submit();
This
does exactly what we need. It allows the form to be checked
for validity first, and if there was no error, it will be
submitted to the server to complete the process.
The
NOSCRIPT Safety Catch
We've
now managed to get our form working with client side validation,
and we're ready to roll it out and watch the traffic come
to visit, right? Yes, but there is still the issue (albeit
dwindling daily) of non-javascript capable browsers. There
are a few people roaming around the Internet that still
use old browsers or Internet access software which does
not support JavaScript. You may not want to alienate this
traffic, and you may not have to. By altering the addition
of the submit button slightly, we can still have the client
side validation services for those who have innovated, and
yet have a lowest common denominator to fall back on for
the few remaining stragglers. Our alteration would look
like this.
<TD>
<SCRIPT><!--
document.write('<INPUT TYPE="BUTTON" VALUE="Submit" ONCLICK="validate();">');
//--></SCRIPT>
<NOSCRIPT>
<INPUT TYPE="SUBMIT" VALUE="Submit">
</NOSCRIPT>
</TD>
This
alteration will allow a JavaScript capable browser to add
the button which uses the validation services, and also
allow browsers which don't support JavaScript to use an
old fashioned submit button, which doesn't use any of the
client validation services. While these poor folks will
have to deal with the delays we talked about at the beginning
of this example, at least the forms will still work for
them, and perhaps you can add some verbiage to the NOSCRIPT
section to suggest that they upgrade to a slightly more
recent browser.
The
working example
Let's
put together everything we've discussed and watch it work.
Here is a functional version of the form we've been working
on. Try it out.
*Actually
above the "document" object is the "window"
object, but since it is assumed by the major browsers, it
does not need to be called in the DOM heiarchy in order
to access its child, the "document."
Back to Build
Your Site
Back
to Table of Contents
|