Sunday, July 24, 2005
Properties VI: Form Control Elements
Blog Entry #17
As detailed by the Forms sector of the HTML 4.01 Specification, there are at least twelve types of form controls, which we can put into three categories:
(1) Field-type controls, for which the user inputs information, usually a text string, into a rectangular box, including:
(a) the text box;
(b) the textarea box;
(c) the password box;
(d) the file select box;
(e) the hidden field, for which the form author does the inputting, also belongs in this category.
(2) Menu-type controls, for which the user chooses one or more options on a list of items, including:
(a) the radio button;
(b) the checkbox;
(c) the selection list.
(3) Button-type controls, including:
(a) the general push button;
(b) the non-image (regular) submit button;
(c) the image submit button;
(d) the reset button.
As noted in the last entry, we want to be able to utilize a user's responses to a form in JavaScript command statements. In this regard, we are mostly interested in the field-type and menu-type controls, which constitute the meat of a form in relation to user input and, moreover, whose name and value information would be sent to the processing agent if/when the form is submitted.
Each of the controls above is represented in JavaScript by a specific, corresponding object - a Text object, a Textarea object, a Password object, etc. - except for the image submit button*. With respect to the manipulation of form information by JavaScript, we have two general concerns:
(1) How do we refer to form control elements in JavaScript command statements?
(2) How do we determine the user's input?
As you can guess, we will use the properties of form control objects to answer these questions.
*Although supported by Netscape 4.x, the <input type="image"> element has no 'reflection' in JavaScript 1.3's set of client-side objects. Re the following section, programmatic access to this element is browser-dependent on my computer: MSIE/JScript treats it normally but Netscape/JavaScript doesn't recognize it at all.
Referencing form control objects
Each type of form control can be referenced in JavaScript as a member of a form's elements[ ] collection:
document.form_name.elements[i].property_or_method
And except for groups of radio buttons and checkboxes with the same name, each type of form control can also be referenced by its name:
document.form_name.control_name.property_or_method
The name of a control is usually preset by a name="control_name" attribute in the control element's opening HTML tag. However, each type of form control object has a read/write name property that can also be used to set the control's name.
A group of radio buttons or checkboxes with the same name constitutes a control_name collection of the containing form, and the individual radio buttons or checkboxes of the group can be referenced as a member of this collection. For example, consider a form with three radio buttons:
<form name="fr">
<input type="radio" name="letter" value="A"> A<br>
<input type="radio" name="letter" value="B"> B<br>
<input type="radio" name="letter" value="C"> C<br>
</form>
The first radio button can be referenced as:
document.fr.letter[0].property_or_method
The second radio button can be referenced as document.fr.letter[1].property_or_method, etc.
Unlike radio buttons, the individual checkboxes of a checkbox group do not need to have the same name, and if you were to assign different names to these checkboxes, then each checkbox can be referenced by its name, as for other types of controls. Moreover, a solitary radio button or checkbox in a form can also be referenced by its name.
(Note: a group of radio buttons with the same name is supposedly "stored as a single element of the elements array of the Form object" (to quote DevGuru's Radio object page); this isn't how it works on my computer (a Windows implementation, perhaps?), which gives identical returns for document.form_name.radio_group_name[i].property and document.form_name.elements[i].property commands for the same value of i, as shown in the "Radio Button User Input Test Div" demo below.)
Determining user input: field-type controls
The all-important property of all of the field-type control objects that determines - indeed, constitutes - a user's input is the value property. Let's illustrate with a simple example; type your first name into the text box below, and then click outside of it:
The code for this is:
<form name="fv">
Please tell us your first name: <input name="tv" onblur="window.alert('Glad you could stop by, ' + document.fv.tv.value + '.');">
</form>
in which the command:
document.fv.tv.value
returns the value, or user input, of the text box named tv, in the form named fv, in the document.
Next question: how do you ensure that the user's input is legitimate? Suppose you are running an e-business; how do you prevent the user from entering a six-digit number into the zip code field on your shopping cart page? Now we are getting into the realm of data validation, a topic that is beyond the scope of this blog entry but that we'll get a taste of in HTML Goodies' JavaScript Primers #29.
Determining user input: selection lists
It's easier to determine user input for a selection list than for a group of radio buttons or checkboxes, so we'll deal with selection lists first. The two key properties of the Select object relating to user input are the options property, which represents the collection of option elements composing the selection list and allows us to access those <option>s, and the read/write selectedIndex property, which sets or returns the index number (0, 1, 2, ...) of the currently selected option of the options[ ] collection. (Unique among the form control objects, the Select object does not have a value property.) To complete the picture, we then turn to the JavaScript Option object, whose read/write text property sets or returns the text of a given <option>. We put it all together in two lines of code:
var si = document.form_name.select_name.selectedIndex;
var user_input = document.form_name.select_name.options[si].text;
or one line, if you prefer:
var user_input = document.form_name.select_name.options[document.form_name.select_name.selectedIndex].text;
In summary, we first determine the index of the selected option and then plug that number into the options[ ] collection to determine the text of the selected option. Try it out with the demo below:
The code for this is:
<form name="fs">
Choose your favorite day of the week from the selection list below:<br>
<select name="favday" onchange="var si = document.fs.favday.selectedIndex; window.alert(document.fs.favday.options[si].text + ' is my favorite day, too!');">
<option>Monday</option>
<option>Tuesday</option>
<option>Wednesday</option>
<option>Thursday</option>
<option>Friday</option>
<option>Saturday</option>
<option>Sunday</option>
</select>
</form>
Determining user input: radio buttons and checkboxes
When a HTML form is submitted, the values of its user-chosen radio buttons, checkboxes, and selection-list options (and of its other "successful controls") are sent to the processing agent. In JavaScript, however, there is no relation between the value property of the Radio, Checkbox, and Option objects and whether the corresponding control elements are 'switched on'.
Moreover, for collections of radio buttons and checkboxes, there is unfortunately no collection-wide selectedIndex-type property that returns the index number of a chosen radio button or checkbox, and even if there was such a property, it would probably have only limited utility with checkboxes; when a selection list is set up with the multiple attribute to allow more than one option to be selected, selectedIndex only returns the index of the first selected option.
The Radio and Checkbox objects do at least have a checked property that returns true if the corresponding control is checked and false if it isn't (the Option object has an analogous selected property). To determine the user input for a group of radio buttons or checkboxes, then, a trial-and-error approach is required; we're going to have to go through the group and determine the checked status of each radio button or checkbox. This might sound like a complicated or tedious process, but it actually isn't. We'll need to use a for loop - the for loop is introduced in Primer #24 - and an if conditional statement - if statements are introduced in Primer #13 - so yes, we'll be getting ahead of ourselves once again, and yet only three lines of code are required, so I'm going to give you the lowdown anyway.
The div below illustrates the determination of user input for a group of radio buttons in a form named fr2.
The Radio Button User Input Test Div
We're just about ready to wrap up our discussion of JavaScript properties, at least for the time being, and move on to Primer #8. I still want to go over some of the properties of the window, History, Location, and Date objects - I don't know if I'll cover them all in one post - I'll start writing and then see how it goes.
reptile7
Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)