15.3 Scripting Form Elements
The
previous
section listed the form elements provided by HTML and explained how
to embed these elements in your HTML documents. This section takes
the next step and shows you how you can work with those elements in
your JavaScript programs.
15.3.1 Naming Forms and Form Elements
Every form element has a
name
attribute that must be set in its HTML tag if the form is to be
submitted to a server-side program. While form submission is not
generally of interest to JavaScript programs, there is another useful
reason to specify this name attribute, as
you'll see shortly.
The <form> tag
itself also has a name attribute that you can set.
This attribute has nothing to do with form submission. It exists for
the convenience of JavaScript programmers. If the
name attribute is defined in
a
<form> tag, when the Form object is created
for that form, it is stored as an element in the
forms[] array of the
Document object, as usual, and it is also stored in its own personal
property of the Document object. The name of this newly defined
property is the value of the name attribute. In
Example 15-1, for instance, we defined a form with a
tag like this:
<form name="everything">This allowed us to refer to the Form object as: document.everything
Often, you'll find this more convenient than the array
notation:
document.forms[0]
Furthermore, using a form name makes your code position-independent:
it works even if the document is rearranged so that forms appear in a
different order.
<img>, <applet>,
and other HTML tags also have name attributes that
work the same as the name attribute of
<form>. With forms, however, this style of
naming goes a step further, because all elements contained within a
form also have name attributes. When you give a
form element a name, you create a new property of
the Form object that refers to that element. The name of this
property is the value of the attribute. Thus, you can refer to an
element named "zipcode" in a form named
"address" as:
document.address.zipcode
With reasonably chosen names, this syntax is much more elegant than
the alternative, which relies on hardcoded (and position-dependent)
array indices:
document.forms[1].elements[4]
In order for a group of Radio elements in
an HTML form to exhibit mutually exclusive "radio-button"
behavior, they must all be given the same name. In
Example 15-1, for instance, we define three Radio
elements that all have a name attribute of
"browser". Although it is not strictly necessary, it is
also common practice to define related groups of Checkbox elements
with the same name attribute. Sharing a
name attribute like this works naturally for
server-side programming, but it is a little awkward on the client
side. The solution is straightforward, though: when more than one
element in a form has the same name attribute,
JavaScript simply places those elements into an array with the
specified name. The elements of the array are in the same order as
they appear in the document. So, the Radio objects in Example 15-1 can be referred to as:
document.everything.browser[0]
document.everything.browser[1]
document.everything.browser[2]
15.3.2 Form Element Properties
All (or most) form elements have the following
properties in common. Some elements have other special-purpose
properties that are described later, when we consider the various
types of form elements individually.
type
A read-only string that identifies the type of the form element. The
third column of Table 15-1 lists the value of this
property for each form element.
form
A read-only reference to the Form object in which this element is
contained.
name
A read-only string specified by the HTML name
attribute.
value
A read/write string that specifies the "value" contained
or represented by the form element. This is the string that is sent
to the web server when the form is submitted, and it is only
sometimes of interest to JavaScript programs. For Text and Textarea
elements, this property contains the text that the user entered. For
Button elements, this property specifies the text displayed within
the button, which is something that you might occasionally want to
change from a script. For Radio and Checkbox elements, however, the
value property is not edited or displayed to the
user in any way. It is simply a string set by the HTML
value attribute that is passed to the web server
when the form is submitted. We'll discuss the
value property when we consider the different
categories of form elements later in this chapter.
15.3.3 Form Element Event Handlers
Most form elements support most of the
following event handlers:
onclick
Triggered when the user clicks the mouse on the element. This handler
is particularly useful for Button and related form elements.
onchange
Triggered when the user changes the value represented by the element
by entering text or selecting an option, for example. Button and
related elements typically do not support this event handler because
they do not have an editable value. Note that this handler is not
triggered every time the user types a key in a text field, for
example. It is triggered only when the user changes the value of an
element and then moves the input focus to some other form element.
That is, the invocation of this event handler indicates a completed
change.
onfocus
Triggered when the form element receives the input focus.onblur
Triggered when the form element loses the input focus.Example 15-1 shows how you can define these event
handlers for form elements. The example is designed to report events
as they occur by listing them in a large Textarea element. This makes
the example a useful way to experiment with form elements and the
event handlers they trigger.
An important thing to know about event handlers is that within the
code of an event handler, the
this keyword always refers to the document
element that triggered the event. Since all form elements have a
form property that refers to the containing form,
the event handlers of a form element can always refer to the Form
object as this.form. Going a step further, this
means that an event handler for one form element can refer to a
sibling form element named x as
this.form.x.
Note that the four form element event handlers listed in this section
are the ones that have particular significance for form elements.
Form elements also support the various event handlers (such as
onmousedown) that are supported by (nearly) all
HTML elements. See Chapter 19 for a full discussion
of events and event handlers.
15.3.4 Buttons
The Button form element is one of the most
commonly used, because it provides a clear visual way to allow the
user to trigger some scripted action. The Button object has no
default behavior of its own, and it is never useful in a form unless
it has an onclick (or other) event handler. The
value
property of a Button element controls the text that appears within
the button itself. In fourth-generation browsers, you can set this
property to change the text (plain text only, not HTML) that appears
in the button, which can occasionally be a useful thing to do.
Note that hyperlinks provide the same
onclick event handler that buttons do, and any
button object can be replaced with a link that does the same thing
when clicked. Use a button when you want an element that looks like a
graphical push button. Use a link when the action to be triggered by
the onclick handler can be conceptualized as
"following a link."
Submit and
Reset elements are just like Button elements, but they have default
actions (submitting and resetting a form) associated with them.
Because these elements have default actions, they can be useful even
without an onclick event handler. On the other
hand, because of their default actions, they are more useful for
forms that are submitted to a web server than for pure client-side
JavaScript programs. If the onclick event handler
returns false, the default action of these buttons
is not performed. You can use the onclick handler
of a Submit element to perform form validation, but it is more common
to do this with the onsubmit handler of the Form
object itself.
In HTML 4, you can create Button, Submit, and Reset buttons with the
<button> tag instead of the traditional
<input> tag.
<button> is more flexible, because instead
of simply displaying the plain text specified by the
value attribute, it displays any HTML content
(formatted text and/or images) that appears between
<button> and
</button>. The Button objects created by a
<button> tag are technically different from
those created by an <input> tag, but they
have the same value for the type field and
otherwise behave quite similarly. The main difference is that because
the <button> tag doesn't use its
value attribute to define the appearance of the
button, you can't change that appearance by setting the
value property. In this book, we use the terms
Button, Submit, and Reset to refer to objects created with either
<input> or
<button>.
15.3.5 Toggle Buttons
The
Checkbox
and Radio elements are toggle buttons, or buttons that have two
visually distinct states: they can be checked or unchecked. The user
can change the state of a toggle button by clicking on it. Radio
elements are designed to be used in groups of related elements, all
of which have the same value for the HTML name
attribute. Radio elements created in this way are mutually
exclusive -- when you check one, the one that was previously
checked becomes unchecked. Checkboxes are also often used in groups
that share a name attribute, and when you refer to
these elements by name, you must remember that the object you refer
to by name is an array of same-named elements. In Example 15-1, we saw three Checkbox objects with the name
"peripherals". In this example, we can refer to an array
of these three Checkbox objects as:
document.everything.peripherals
To refer to an individual Checkbox element, we must index the array: document.everything.peripherals[0] // First form element named "peripherals"
Radio and Checkbox elements both define a
checked
property. This read/write boolean
value specifies whether the element is currently checked. The
defaultChecked
property is a read-only boolean that has the value of the
HTML
checked attribute; it specifies whether the
element was checked when the page was first loaded.
Radio and Checkbox elements do not display any text themselves and
are typically displayed with adjacent HTML text (or, in HTML 4, with
an associated <label> tag.) This means that
setting the value
property of a Checkbox or Radio
element does not alter the visual appearance of the element, as it
does for Button elements. You can set value, but
this changes only the string that is sent to the web server when the
form is submitted.
When the user clicks on a toggle button, the Radio or Checkbox
element triggers its onclick event handler to
notify the JavaScript program of the change of state. Newer web
browsers also trigger the
onchange handler for these elements. Both
event handlers convey the same essential information, but the
onclick handler is more portable.
15.3.6 Text Fields
The Text element
is probably the most commonly used element in HTML forms and
JavaScript programs. It allows the user to enter a short, single-line
string of text. The value
property represents the text the user has entered. You can set this
property to specify explicitly the text that should be displayed in
the field. The
onchange event handler is triggered when the
user enters new text or edits existing text and then indicates that
he is finished editing by moving input focus out of the text field.
The Textarea
element is just like the Text element, except that it allows the user
to input (and your JavaScript programs to display) multiline text.
Textarea elements are created with a
<textarea> tag using a syntax significantly
different from the <input> tag used to
create a Text element. Nevertheless, the two types of element behave
quite similarly, and Textarea can be considered to inherit from
HTMLInputElement, even though it technically does not. You can use
the value property and onchange
event handler of a Textarea element just as you would for a Text
element.
The Password
element is a modified Text element that displays asterisks as the
user types into it. As the name indicates, this is useful to allow
the user to enter passwords without worrying about others reading
over their shoulders. Password triggers its
onchange event handler just as Text does, but
there are some restrictions (or bugs) on the use of its
value property. Some old browsers (such as
Netscape 3) implement an ineffective
security measure that prevents
JavaScript from reading the value the user has entered into a
Password element. In other browsers (such as Netscape 4), the
value property may be set, but setting it does not
cause any change to the visual appearance of the form element. Note
that the Password element protects the user's input from prying
eyes, but when the form is submitted, that input is not encrypted in
any way (unless it is submitted over a secure HTTPS connection), and
it may be visible as it is transmitted over the network.
Finally, the FileUpload object is designed to allow
the user to enter the name of a file to be uploaded to the web
server. It is essentially a Text element combined with a built-in
button that pops up a file-chooser dialog box. FileUpload has an
onchange event
handler, like the Text element. Unlike Text, however, the
value property of FileUpload is read-only.
This prevents malicious JavaScript programs from tricking the user
into uploading a file that should not be shared.
Netscape 4 and later and Internet Explorer 4 and later define
onkeypress , onkeydown, and
onkeyup event handlers (note, however, that they
are not yet part of the DOM standard). These handlers can be
specified for any Document object, but they are most useful (and, in
Netscape 4, only useful) when specified on Text and related form
elements that actually accept keyboard input. You may return
false from the onkeypress or
onkeydown event handlers to prevent the
user's keystroke from being recorded. This can be useful, for
example, when you want to force the user to enter only digits. See
"HTMLElement" in the client-side and DOM reference
sections for more details on these and other event handlers that are
supported by all HTML elements.
15.3.7 Select and Option Elements
The
Select element
represents a set of options (represented by Option elements) from
which the user can select. Browsers typically render Select elements
in drop-down menus or list boxes. The Select element can operate in
two very distinct ways, and the value of the type
property depends on how it is configured. If the
<select> tag has the
multiple
attribute, the user is allowed to select multiple options, and the
type property of the Select object is
"select-multiple". Otherwise, if the
multiple attribute is not present, only a single
item may be selected, and the
type
property is "select-one".
In some ways, a "select-multiple" element is like a set
of Checkbox elements, and a "select-one" element is like
a set of Radio elements. The Select element differs from the
toggle-button elements in that a single Select element represents an
entire set of options. These options are specified in HTML with the
<option> tag, and they are represented in
JavaScript by Option objects stored in the
options[]
array of the Select element. Because a Select element represents a
set of choices, it does not have a value property,
as all other form elements do. Instead, as we'll discuss
shortly, each Option object contained by the Select element defines a
value property.
When the user selects or deselects an option, the Select element
triggers its onchange event
handler. For "select-one" Select elements, the read/write
selectedIndex
property specifies by number which one of the options is currently
selected. For "select-multiple" elements, the single
selectedIndex property is not sufficient to
represent the complete set of selected options. In this case, to
determine which options are selected you must loop through the
elements of the options[] array and check the
value of the selected property for each Option object.
In addition to its selected property, the Option
element has a text
property that specifies the string of plain text that appears in the
Select element for that option. You can set this property to change
the text that is displayed to the user. The
value
property is also a read/write string that specifies the text to be
sent to the web server when the form is submitted. Even if you are
writing a pure client-side program and your form never gets
submitted, the value property (or its
corresponding HTML value attribute) can be a
useful place to store any data that you'll need if the user
selects a particular option. Note that the Option element does not
define form-related event handlers; use the
onchange handler of the containing Select element
instead.
In addition to setting the text property of Option
objects, there are other ways you can dynamically change the options
displayed in a Select element. You can truncate the array of Option
elements by setting options.length to the desired
number of options, and you can remove all Option objects by setting
options.length to zero. Suppose we have a Select
object named "country" in a form named
"address". We can remove all options from the element
like this:
document.address.country.options.length = 0; // Remove all options
We can remove an individual Option object
from the Select element by setting its spot in the
options[] array to null.
This deletes the Option object, and any higher elements in the
options[] array automatically get moved down to
fill the empty spot:
// Remove a single Option object from the Select element
// The Option that was previously at options[11] gets moved to options[10]...
document.address.country.options[10] = null;
Finally, the Option element defines an Option(
) constructor that you can use (in
JavaScript 1.1 and later) to dynamically create new Option elements,
and you can append new options to a Select element by assigning them
to the end of the options[] array. For example:
// Create a new Option object
var zaire = new Option("Zaire", // The text property
"zaire", // The value property
false, // The defaultSelected property
false); // The selected property
// Display it in a Select element by appending it to the options array:
var countries = document.address.country; // Get the Select object
countries.options[countries.options.length] = zaire;
In HTML 4, you can use the
<optgroup>
tag to group
related options within a Select element. The
<optgroup> tag has a
label attribute that specifies text to appear in
the Select element. Despite its visual presence, however, an
<optgroup> tag is not selectable by the
user, and HTMLOptGroupElement objects never appear
in the options[] array of the Select element.
15.3.8 Hidden Elements
As its name implies, the Hidden element has no visual
representation in a form. It exists to allow arbitrary text to be
transmitted to the server when a form is submitted. Server-side
programs use this as a way to save state information that is passed
back to them with form submission. Since they have no visual
appearance, Hidden elements cannot generate events and have no event
handlers. The value property allows to you read
and write the text associated with a Hidden element, but, in general,
Hidden elements are not commonly used in client-side JavaScript
programming.
15.3.9 Fieldset Elements
The HTML 4 standard adds new
<fieldset>
and <label> tags to the set of elements that
can appear within a form. In IE 5 and later, placing a
<fieldset> in a form causes a corresponding
object to be added to the form's elements[]
array. Fieldset elements are not scriptable in interesting ways like
other form elements are, and their objects do not have a
type property like other form elements do.
Therefore, the presence of Fieldset objects in the
elements[] array seems like a mistaken design
decision. This is particularly true since
<label> tags do not cause corresponding
objects to be added to the
elements[]
array. The Mozilla and Netscape 6 browsers have chosen to follow
Microsoft's lead on this in order to be compatible with IE.
What this means is that if you define a form that contains fieldsets,
the contents of the elements[] array differ in
recent, HTML 4-capable browsers and in older, pre-HTML 4 browsers. In
this situation, using position-based numeric indexes in the
elements[] array is not portable, and you should
define name attributes for all your form elements
and refer to them by name.