5.4. Idiosyncrasies of HTML Forms

This section explains how the various form fields (hidden data, text boxes, etc.) are turned into data that is sent to the server. For information on the cosmetic features, such as the attributes that control how big the form object appears on the screen, see Web Design in a Nutshell (O'Reilly), HTML & XHTML: The Definitive Guide (O'Reilly), or the W3C's explanation of HTML 4.01 forms at http://www.w3.org/TR/html401/interact/forms.

5.4.1. Hidden Elements

An input element with type=hidden creates a form pair consisting of the value of its name attribute and the value of its value attribute. For example, this element:

<input type=hidden name="pie" value="meringue">

This doesn't display anything to the user, but when submitted, creates a form pair pie=meringue.

5.4.2. Text Elements

An input element with type=text (or with no type attribute at all) creates a one-line form box in which the user can type whatever she wants to send on this form. If there's a value attribute, its value is what's filled in when the form is first rendered, or when the user hits a Reset form button.

For example, this element:

<input type=text name="pie_filling" value="cherry">

creates a form box with "cherry" filled in. If the user submits the form as is, this will make a form pair pie_filling=cherry. If the user changes this to crème brûlée, this will make a form pair pie_filling=crème brûlée, or, after it gets URL encoded, pie_filling=cr%E8me+br%FBl%E9e.

5.4.3. Password Elements

An input element with type=password works exactly as if it had type=text, except the characters on screen in that box are made unreadable to anyone who might be looking over the user's shoulder. This is typically done by showing every character of the current value as *. For example:

<input type=password name="pie_filling" value="cherry">

This will have the initial value cherry, except it will appear as ******. If the user enters crème brûlée, that will be the current value, but it will display as ************. The form pairs submitted are just as if it were type=text, that is, pie_filling=cherry or pie_filling=crème brûlée.

5.4.4. Checkboxes

An input element with type=checkbox creates an on/off form button. The user cannot change the value of the element beyond just turning it on or off. For example:

<input type=checkbox name="à la mode" value="Pretty please!">

If the user checks this box and submits the form, it will send the form pair consisting of the element's name and value attribute's values. In this case, the pair is à la mode=Pretty please!, or, after it gets URL encoded, %E0+la+mode=Pretty+please%21. Note that if there is no value attribute, you get the pair name=on, as if there were a value="on" in this element. Incidentally, the user doesn't typically see whatever is specified for the value attribute.

Note that this differs from type=text input elements in this way: in type=text input elements, the value attribute sets the default value of the form, but in type=checkbox elements, the value attribute controls what value is sent if the checkbox is turned on when the form is submitted. By default, a checkbox is off upon rendering a new form (or when the user hits Reset); to make a checkbox element on by default, add the checked attribute:

<input type=checkbox name="à la mode" ivalue="Pretty please!" checked>

5.4.5. Radio Buttons

Input elements with type=radio behave like checkboxes, except that turning one radio button element on will turn off any other radio button elements with the same name value in that form. As the name "radio button" suggests, this is meant to be like the station preset buttons on many models of old car radios, where pressing in one button would make any selected one pop out.

Moreover, there is typically no way to turn off a radio button except by selecting another in the same group. An example group of radio buttons:

<input type=radio name="à la mode" value="nope" checked>
 nope <br>
<input type=radio name="à la mode" value="w/lemon" >
 with lemon sorbet <br>
<input type=radio name="à la mode" value="w/vanilla" >
 with vanilla ice cream<br>
<input type=radio name="à la mode" value="w/chocolate" >
 with chocolate ice cream <br>

By default, the nope element is on. If the user submits this form unchanged, this will send the form pair à la mode=nope. Selecting the second option ("with lemon sorbet") also deselects the first one (or whatever other "à la mode" element is selected), and if the user submits this, it well send the form pair à la mode=w/lemon.

Note that the checked attribute can be used to turn a type=radio element on by default, just as with type=checkbox elements. Different browsers behave differently when a radio button group has no checked element in it, or more than one. If you need to emulate the behavior of a particular browser in that case, experiment with the formpairs.pl program explained earlier, to see what form pair(s) are sent.

5.4.6. Submit Buttons

An input element with type=submit produces a button that, when pressed, submits the form data. There are two types of submit buttons: with or without a name attribute.

<input type=submit value="Go!">

The name-less element forms a button on screen that says "Go!". When pressed, that button submits the form data.

<input type=submit value="Go!" name="verb">

This displays the same as the name-less element, but when pressed, it also creates a form pair in the form it submits, consisting of verb=Go! (or after URL encoding, verb=Go%21). Note that the value attribute is doing double duty here, supplying both the value to be submitted as well as what should be displayed on the face of the button.

The purpose of this sort of button is to distinguish which of several submit buttons is pressed. Consider a form that contains these three submit buttons:

<input type=submit name="what_to_do" value="Continue Shopping">
<input type=submit name="what_to_do" value="Check Out">
<input type=submit name="what_to_do" value="Erase Order">

All of these will submit the form, but only if the first one is pressed will there be a what_to_do=Continue Shopping pair in the form data; only if the second one is pressed will there be a what_to_do=Check Out pair in the form data; and only if the third one is pressed will there be a what_to_do=Erase Order pair in the form data.

Note, incidentally, that in some cases, it is possible to submit a form without pressing a submit button! This is not specified in the HTML standard, but many browsers have the feature that if a form contains only one type=text field, if the user hits Enter while the cursor is in that field, the form is submitted. For example, consider this form:

<form type=get action="searcher.cgi">
  <input type=hidden name="session" value="3.14159">
  <input type=text name="key" value="">
  <input type=submit name="verb" value="Search!">
</form>

If the user types "meringue" in the input box, then hits the "Search!" button with the mouse pointer, there will be three form pairs submitted: session=3.14159, key=meringue, and verb=Search!. But if the user merely types "meringue" in the input box and hits the Enter key, there will be only two form pairs submitted: session=3.14159 and key=meringue. No form pair for the submit button is sent then, because it wasn't actually pressed.

5.4.7. Image Buttons

An input element with type=image is somewhat like a type=submit element, except instead of producing a button that the user presses in order to submit the form, it produces an inline image that the user clicks on to submit the form.

Also, whereas a type=submit button generates one form pair when pressed, name=value, from the element's name and value attributes, a type=image element generates two form pairs when pressed: name.x=across and name.y=down, reflecting the point in the image where the user's pointer was when he clicked on it. An example of typical type=image element syntax will illustrate this:

<input type=image name="woohah" src="do_it.gif">

And suppose that do_it.gif is an image 100 pixels wide by 40 high, and looks like the image in Figure 5-1.

Figure 5-1. A sample submit button

Figure 5-1. A sample submit button

If the user clicks the pointer over the absolute top-leftmost pixel of that image as drawn by the above <input type=image ...> element inside a larger form element, it will submit the form along with two form pairs: woohah.x=0 and woohah.y=0. If the user instead clicks the pointer over the four-corners design in the middle of the "O" in "DO IT!", this happens to be 38 pixels from the left edge of the image, and 19 pixels from the top edge of the image, the form is submitted with the two form pairs woohah.x=38 and woohah.y=19.

While this imagemap-like feature of input type=image elements would obviously be quite useful for, say, click-to-zoom maps, most uses of input type=image elements are actually merely cosmetic, and the inlined image is just a fancy-looking version of the submit button. As such, the programs that process most such forms will just ignore the values of the name.x and name.y form pairs.

Consider this simple form:

<form type=post action="searcher.cgi">
  <input type=hidden name="session" value="3.14159">
  <input type=text name="key" value="">
  <input type=image name="in-english" src="usa_flag.png">
  <input type=image name="in-spanish" src="mex_flag.png">
</form>

This will render an input box followed by a U.S. flag image, then a Mexican flag image. There are three possible ways this can be submitted. First, if the user selects the input box to plant the cursor there, types "chocolate", and presses Enter, this will submit the form (via a POST method) to the form searcher.cgi with just two form pairs: session=3.14159 and key=chocolate.

Secondly, if the user types "chocolate", then puts the pointer over the U.S. flag and clicks it, it will submit the form with four form pairs: session=3.14159, key=chocolate, in-english.x=12, and in-english.y=34, where 12 and 34 are the across and down coordinates of the point in the U.S. flag where the user clicked.

Or thirdly, if the user types "chocolate", then puts the pointer over the Mexican flag and clicks it, it will submit the form with four form pairs: session=3.14159, key=chocolate, in-spanish.x=12, and in-spanish.y=34, where 12 and 34 are the across and down coordinates of the point in the Mexican flag where the user clicked.

Incidentally, the HTML specifications do not say how browsers should behave when there is no name=whatever attribute present in an input type=image element, but common practice is to create form pairs with keys named x and y (i.e., x=38 and y=19).

5.4.8. Reset Buttons

A type=reset input element produces no form pair and does not submit the form. It merely creates a button that the user can press to reset the form's contents to their default values, back to the way they were when the form was first rendered. The value attribute is used only to put text on the button's face. For example:

<input type=reset value="Nevermind">

This creates a reset button with the text "Nevermind" on it. It has no other effect.

5.4.9. File Selection Elements

A type=file input element provides some set of controls with which the user can select a local file. Usually this appears as a "Browse..." button that brings up an "Open File..." window and a text box that lists the name of whatever file is selected. When a file is selected, it sets the value of the form pair as the content of the file. File parameters, however, work in quite a different way from regular forms, and we deal with them in the Section 5.7, "File Uploads" section later in this chapter.

5.4.10. Textarea Elements

A textarea element is like an <input type=text ...> element, except the user can enter many lines of text instead of just one. Moreover, the syntax is different. Whereas an <input type=text ...> element consists of just one tag, with the default content in the value attribute, like so:

<input type=text name="pairname" value="default content">

a textarea element consists of a start-tag, default content, and an end-tag:

<textarea name="pairname">Default content, first line.
Another line.
The last line.</textarea>

5.4.11. Select Elements and Option Elements

One final construct for expressing form controls is a select element containing some number of option elements. This is usually rendered as a drop-down/pop-up menu or occasionally as a scrollable list. In either case, the behavior is the same: the user selects an option from the list. The syntax is:

<select name="à la mode">
  <option value="nope">Nope</option>
  <option value="w/lemon">with lemon sorbet</option>
  <option value="w/vanilla">with vanilla ice cream</option>
  <option value="w/chocolate">with chocolate ice cream</option>
</select>

That is, one select element with a name=string attribute contains some option elements, each of which has a value=string attribute. The select element generates one form pair, using the select element's name=string attribute and the value=string attribute from the chosen option element. So in the example above, if the user chooses the option that showed on the screen as "with lemon sorbet", this sends the form pair à la mode=w/lemon, or, once it's URL encoded, %E0+la+mode=w%2Flemon.

Any option elements that have no value=string attribute get their values from the content of the element. So these option elements:

<option>This &amp; That</option>
<option>And the other

mean the same thing as:

<option value="This &amp; That">This &amp; That</option>
<option value="And the other">And the other</option>

When the form is first rendered, the first element is typically selected by default, and selecting any other deselects it. By providing a selected attribute in an option element, you can force it to be the selected one when the form first renders, just as the checked attribute does for checkbox input elements. Also, the </option> end-tag is optional.

Putting all that together, this code:

<select name="pie_filling">
  <option>Apple crunch
  <option selected>Pumpkin
  <option value="Mince-meat">Mince
  <option>Blueberry
  <option>Quince
</select>

means the same thing as this code:

<select name="pie_filling">
  <option value="Apple crunch">Apple crunch</option>
  <option value="Pumpkin">Pumpkin</option>
  <option value="Mince-meat">Mince</option>
  <option value="Blueberry" selected>Blueberry</option>
  <option value="Quince">Quince</option>
</select>

with the single exception that when the first one is rendered on the screen, it starts out with "Pumpkin" selected by default, whereas in the second one, "Blueberry" is selected by default.

There are two other kinds of differences in the code: the latter has </option> tags, but the former does not, and the former leaves out some value="..." attributes where the latter always has them. However, neither of these two kinds of differences are significant; the browser sees both blocks of code as meaning the same thing.

If the select element has a multiple attribute, as here:

<select name="à la mode" multiple>
  <option value="nope">Nope</option>
  <option value="w/lemon">with lemon sorbet</option>
  <option value="w/vanilla">with vanilla ice cream</option>
  <option value="w/chocolate">with chocolate ice cream</option>
</select>

the user is allowed to select more than one option at a time. (And incidentally, this typically forces the options to appear as a scrollable list instead of as a drop-down/pop-up menu.) This multiple feature is rarely used in practice.