Vol. 1, No. 26
JavaScript and Forms
With Tripod's new CGI capabilities, one finds that HTML forms are
increasingly important. JavaScript, which we've dealt with before,
deals quite handily with forms. With its healthy string-handling
skills, it can validate the input your users type into forms before
the input is sent to the server, or modify the values of form fields
on the fly. Yes, JavaScript is pretty slick when it comes to forms.
Let's take a look at how to handle forms with JavaScript.
JavaScript accesses form fields as elements of the document object.
So to put the value of a form field into a JavaScript variable,
you say something like:
contents = document.formname.fieldname.value;
Conversely, to change the contents of a form field (typically in
response to some event), you simply set the field value equal to
the variable:
document.formname.fieldname.value = newcontents;
"document," as you recall, is JavaScript's name for the current page,
and "value" is what it calls the contents of a form. You plug in the
name of your form and form field into the middle two terms, respectively.
If you have a form called "story" and you want to read a field called
"headline" within the form into a variable called "oldhead", you would
say:
oldhead = document.story.headline.value;
Let's start by creating a simple form-manipulation script. This will
take the input that is typed into one field and, when a button is
clicked, reproduce it in another field backwards. Here we go.
<script language="JavaScript">
<!--
function reverse() {
forwards = ""; // prevent carry-over of previous values
backwards = "";
forwards = document.myform.entry.value; // read entry into variable
for (i = 0; i < forwards.length; i++) { // add each character in the entry string
backwards = forwards.charAt(i) + backwards; // one at a time to the new string in reverse order
}
return backwards; // send the backwards string back to the form
}
// -->
</script>
<form name="myform">
<input name="entry" type=text size=20 maxlength=20>
<input name="yrtne" type=text size=20 maxlength=20>
<BR><input name="mybutton" type=button value="Reverse!" onClick="document.myform.yrtne.value=reverse()">
</form>
See it in action here.
What's happening here is very simple. The user types some text into
the first field, and then presses the "Submit" button. The button
calls the "reverse()" function. (Remember, JavaScript functions
don't do anything until they are explicitly summoned.) The function
does the following:
1. It reads the contents of the entry field into a variable called
"forwards."
2. For each progressive value of "i," the corresponding character
from the entry string from the first to the last is appended
to the beginning of the variable called "backwards." (In a moment,
we'll brush up on "for loops"). So to make the string backwards,
first the first character is written, then, to the left of that,
the second character. Then, to the left of that added character
comes the third, and so on.
3. When that's finished, the JavaScript sends the string back to
the "onClick" handler that called it, which writes it into the
second form field.
Easy enough, right? The function uses a few little techniques that
we'll go over. Firstly: "for loops." This is a simple way of doing
things again and again until they're done right. The syntax is like
this:
for (i = initialvalue; i == finalvalue; i++) {
do something;
}
First, the variable "i" is set to the initial value, and the statements
within the curly brackets are executed once. Then the operation at the
end of the "for" statement is run. In this case it is "i++," which
means "add 1 to "i", but you can make it "i--" or "i=i+5" or whatever
you like.
Next, the middle statement ("i = finalvalue") is evaluated. If it's
true, then the "for loop" ends. If it's not true, the statements
within the curly brackets are run again, and the process begins
anew. In plain English, the "for loop" keeps running until "i" has
reached its final value. (You can call your variable "victor" or
"k" or anything you please. But "i" is traditional.)
In the example above, the "for loop" starts with "i" equal to zero,
and keeps running as long as "i" is less than the length of the
entry string, adding one each time.
The length of a string is determined with the length method. Very
simply, "string.length" equals the length of the variable "string."
"string.charAt" returns the character at the specified position within
the variable "string." Counting begins at the left of the string, with
the first character being number "0," the second number "1," and so
forth. (Confusing perhaps, but that's how programmers count.) So if
string = "A fool and his monkey are soon parted," charAt(2) would be "f."
(Just an aside: "string.substring" is similar, but it will give you
any length substring you want. Just specify the starting and ending
positions. Thus, string.substring(11,20) would be "his monkey.")
You can use this technique to do pretty much anything you want that
involves reading from and writing to form fields.
Validating Form Input
Let's suppose you have set up a form on your site that asks users
for their names. Typically, hordes of pranksters are entering things
like "R2-D2" and "*&@$@!!" This simply will not do. You need to
set up a JavaScript function to make sure that people enter valid
names. We will not permit numbers or punctuation. Oh, but we will
allow spaces and hyphens. Here's an easy way to do it:
<script language="JavaScript">
<!--
function namevalid(string) {
if (!string) return false; // not valid if blank
var valchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -"; // these are allowable characters
for (i = 0; i < string.length; i++) { // check each character
if (valchars.indexOf(string.charAt(i)) == -1) // to see if it's in the list
return false; // if not, exit with an error
}
return true;
}
// -->
</script>
<form>
Enter your name: <input type="text" onBlur="if (!namevalid(this.value)) alert('That is not your real name.')">
</form>
See it in action here.
This is primarily made up of commands you've seen before. That "for
loop" in particular looks eerily familiar, no? But let's go over
a couple of elements that may be new to you.
"indexOf" is the inverse of "charAt" give it a string and a
character, and it will give you back the position in the string in
which the character appears. If the character isn't found in the
string, "indexOf" returns a value of "-1." In our example, we are
looking for just that if "-1" is the answer to our query, we
flash a warning.
In the form, we're using the useful "onBlur" event handler. This
causes our function to be called as soon as the field in question
"blurs;" that is, as soon as the user clicks anywhere outside the
field, or tabs to the next field. Since they have to do so to submit
the form, this will ensure that they can't submit data that our
script hasn't validated. "this.value" refers to the contents of the
current field JavaScript, like English, uses "this" as shorthand
to mean "the thing we are dealing with right here; the one I'm
standing on."
HINTS, POINTERS, AND TIPS 'O THE TRADE:
Validation is essential in many situations where your users are
sending data to CGI scripts. If you're running a script that sends
e-mail to a user-specified address, you probably want to make sure
that your users are inputting actual e-mail addresses. An easy way
to do this is to just check for the characters @ and "." both of
which no valid e-mail address should be without. If your users are
simply submitting text to appear on a message board or in a guestbook,
you may well want to make sure there's no HTML in the text. A simple
"</textarea>" tag closing your form before you're ready could screw
up your whole page. And if they include JavaScript, it could be far
worse. Be paranoid validate your forms.
It's a good idea to run some sort of validation on the server side
too, in the CGI script that's getting the input. If, for example,
some users surf with JavaScript turned off (heresy!) they won't be
stopped by your
validation script.
JavaScript has some reserved words, like "var" and "finally" and
"abstract." If your form or form fields happen to share a name with
one of these words, JavaScript will choke and give you a baffling
error message. This can be sidestepped by the following method:
Suppose a form called "abstract" has a field called "finally." You
can refer to that field with code like this:
myvariable = document.form['abstract'].elements['finally'].value;
A lot more can be done with JavaScript regular expressions, which
are super-powerful but only supported in JavaScript 1.2 and later.
If you're lucky, they'll be covered in an upcoming tutorial.
Nobody works well in a cluttered workspace.
RESOURCES:
Webmonkey: Thau's JavaScript Tutorial
Webmonkey: HTML Basics Good Forms
Internet Related Technologies: JavaScript Form Contents
JavaScript Reserved Words