15.3 Scripting Form ElementsThe 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 ElementsEvery 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 PropertiesAll (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.
15.3.3 Form Element Event HandlersMost form elements support most of the following event handlers:
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 ButtonsThe 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 ButtonsThe 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 FieldsThe 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 ElementsThe 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 ElementsAs 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 ElementsThe 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. |