Chapter 14

Forms, Tables, and Frames


CONTENTS


In Chapter 13, I covered the specifications of the latest level of HTML. In this chapter, you'll look at three important advanced HTML features-forms, tables, and frames-in more detail. This chapter describes how to create a form and the basics of connecting it to a back end-a gateway program used to accomplish some work. More gateway programming examples with the FORM element are covered in Part IV, "Gateway Programming," and case studies are presented in Part V. I also cover the basics of tables and frames, showing the syntax and examples of each.

Forms

Forms are used to elicit responses from users through a graphical user interface consisting of fill-in blanks, buttons, check boxes, and other features. After the user fills in form values, the entries can be used by a script or executable program (a gateway program). This gateway program then can access databases, other software, or any other program or data that the implementer designates. Based on the results, an HTML document can be displayed in the user's browser showing the results of the gateway program execution. Figure 14.1 summarizes these general relationships among forms, an executable gateway program, and other data.

Figure 14.1 : Form relationships and functionality.

Languages used for gateway programs might be programming languages such as C (see Chapter 29, "C-Based Gateway Scripting"), REXX (see Chapter 30, "Writing CGI Scripts in REXX"), or others (see Chapter 26, "Gateway Programming Language Options and a Server Modification Case Study"). Gateway programs can be written using script languages such as Perl or UNIX Shell command languages (see Part IV). This chapter uses Perl as part of its tutorial material. Perl is a very useful language for text and string processing and is popularly used with gateway programs. For on-line information about Perl, see http://www.yahoo.com/Computers/Languages/Perl/.

Many new users find the visual portion of forms easy enough to learn. A form is comprised of HTML elements not unlike those from levels 3, 2, 1 and 0 HTML. The conceptual difficulty often lies in the connection to and composition of the gateway program. No single gateway programming language needs to be used with forms, and the gateway program is completely different from the HTML that you have been learning. Moreover, users of the Web who are used to being able to view the HTML source of any web page can't observe the source code of gateway programs. For the user, gateway programs therefore can seem very mysterious; gateway programs can be "anything," but the casual user might not ever be able to see one. This section attempts to unravel the mystery behind the forms by showing how the graphical interface and gateway programs are constructed and work together.

The FORM Element Syntax

A FORM element is used in an HTML document just like any other element. It has a start tag, <FORM>, and an end tag, </FORM>. A FORM tag is structured like this:

<FORM Action="URL" Method="POST">FORM contents</FORM>

Here, URL is the query program or server to which the contents of the fill-in fields of the form are sent. Method identifies the way in which the contents of the form are sent to the query program. The form itself is defined by the elements in FORM contents.

The FORM element contains the elements INPUT, SELECT, OPTION, and TEXTAREA. These elements set up areas to accept input from the user. The input from the user is tied to variable names you supply by a set of paired variable name fields and value fields. The variable name is supplied in the form. The user filling out the form supplies or selects the variable values (except for variables with hidden values), and default values can be coded into the form.

Each form has a method and action associated with it. The method specifies how the data from the form is to be handled in processing. The action identifies the executable program or script that will process the data from the form. Here is a list of the elements and attributes you will be working with when creating a form:

FORM  Delimits the start and end of a data input form. Forms can't be nested, although there might be several in each document. Forms can include other elements, such as lists or <PRE>.


FORM Attributes

Action  Specifies the URL of the program or script that accepts the contents of the form for processing. If this attribute is absent, the base URL (the URL where the form is located on the server) of the form is used.

Enctype  This identifies the media type. See RFC1590 (ftp://ftp.merit.edu/documents/rfc/rfc1590.txt). This media type is used for encoding the name/value pairs of the form's data. This is needed when the protocol identified in Method does not have its own format. The default encoding for all forms is application/x-www-form-urlencoded, and name/value pairs have the following characteristics:

Method  Indicates the method type in the forms-handling protocol that will be used in processing the Action program or script. The possible values are get and post.

Query forms that make no lasting changes in the state of hypertext or other data (for example, a database query) should use the Method get. A form using the get method is processed using the Action URL of the form with a ? appended to it followed by the form data appended in the application/x-www-form-urlencoded (as described for the Enctype default format).

Forms that do make a change in a database or hypertext or some other value should use the Method post. The format of the message is application/x-www-form-urlencoded (as described for the Enctype default format).


INPUT  Collects information from the user.


INPUT Attributes

Align  Used only with the image Type (see the list that follows). Possible values are top, middle, and bottom, and they define the relationship of the image to the text following it.

Checked  Causes the initial state of a check box or radio button to be selected. Without this attribute, the initial state is unselected.

Maxlength  Sets a maximum number of characters that a user can enter in a text field. The default value of this is unlimited.

Name  Specifies a symbolic name used in transferring and identifying the output from this element of the form.

Size  Specifies the field width as displayed to the user. If Size is less than Maxlength, the text field is scrollable.

Src  Defines the source file for the image when the attribute Type is set to image.

Text  A single-line, text-entry area (the TEXTAREA element is used for multiline text input). If the only element in the form has attribute Text, the user can submit the form by pressing Enter (or Return) on the keyboard.

Type  Defines what kind of input field is presented to the user. Possible values follow:

Value  Sets the initial displayed value of the field or the value of the field when it is selected (the radio button type must have this attribute set).


OPTION  Occurs only within the SELECT element (described previously) and is used to represent each choice of the SELECT.


OPTION Attributes

Selected  Indicates that this option initially is selected.

Value  If present, this is the value returned by SELECT if this option is chosen; otherwise, the value returned is that set by the OPTION element.


SELECT  Allows a user to choose one of a set of alternatives. The OPTION element is used to define each alternative.


SELECT Attributes

Multiple  By default, the user can make only one selection from the group in the SELECT element. By using the Multiple attribute, the user can select one or more of the OPTIONs.

Name  The logical name that will be submitted and associated with the data as a result of the user choosing SELECT.

Size  Specifies the number of visible items. If this is more than one, the visual display will be a list. If the size is unspecified, the display will be a pull-down list.


TEXTAREA  Collects multiple lines of text from the user. The user is presented with a scrollable pane in which text can be written.


TEXTAREA Attributes

Cols  The number of columns that will be displayed (the user can use the scrollbar to move through more columns if necessary).

Name  The logical name associated with the returned text.

Rows  The number of rows that will be displayed (note that the user can use more rows and scroll down to them).


A Sample Form

To put together the preceding list, the HTML document in Listing 14.1 shows a sample form that contains all the major form elements.

This form example illustrates the use of the hidden value of the Type attribute:

<INPUT Type="hidden" Name="address" Value="nobody@rpi.edu">

This is for use with the gateway program identified in the Action attribute of the form. The example sets the destination address and subject line of the e-mail message sent as a result of this form's use.

This example includes radio, check box, text, password, image, submit, and reset types of INPUT elements.

The SELECT element is used with the OPTION element in this example. The "What is your favorite Web browser?" question uses the OPTION Selected attribute to set the default for that selection to Netscape.

The Value attribute is used with the "Which of these ice cream flavors have you tried?" question to illustrate how these can differ from the text displayed to the user.

The TEXTAREA element is used with a default value ("All is well that ends well."). The user can change this value if desired.

The image INPUT element type illustrates how the form can be submitted using an imagemap. The gateway program used with this form reports the x and y values of the location of the user's mouse click on the image. Listing 14.1 shows the HTML source for this form. Figure 14.2 shows this form as rendered in the Netscape browser.

Figure 14.2 : A sample HTML form.


Listing 14.1. An HTML form example.
<!-- HTML Form Example -->
<!-- Author: john@december.com -->
<!-- Created:  17 Mar 1995 -->
<!-- Update:   3 Dec 1995: had to send to Sunsite echo; RPI down -->
<!-- Update:   4 May 1996: moved to HTML station -->
<FORM Method="POST" Action="http://hostcgi-bin/mailer">
   <P>
   <INPUT Type="hidden" Name="address" Value="nobody@rpi.edu">
   <INPUT Type="hidden" Name="subject" Value="Level 2 HTML Form +">
   <INPUT Type="hidden" Name="username" Value="Unknown User">
   <INPUT Type="hidden" Name="usermail" Value="Unknown Email">

   Your age: <INPUT Type="text" Name="user-age" Size="2"><BR>

   Your gender:
      <INPUT Type="radio" Name="user-gender" Value="M">Male
      <INPUT Type="radio" Name="user-gender" Value="F">Female<BR>

   Check all names of the people listed whom you have heard about:<BR>
      <INPUT Type="checkbox" Name="knows-marc">Marc Andreessen
      <INPUT Type="checkbox" Name="knows-lisa">Lisa Schmeiser
      <INPUT Type="checkbox" Name="knows-al">Al Gore
      <INPUT Type="checkbox" Name="knows-bbg">Boutros Boutros-Ghali<BR>

   What is your favorite Web browser?
   <SELECT Name="favorite-web-browser">
      <OPTION>Arena
      <OPTION>Cello
      <OPTION>Chimera
      <OPTION>Lynx
      <OPTION>MacWeb
      <OPTION>Mosaic
      <OPTION Selected>Netscape
      <OPTION>SlipKnot
      <OPTION>Viola
      <OPTION>Web Explorer
      <OPTION>None of the above
   </SELECT><BR>

   Which of these ice cream flavors have you tried?
   <SELECT Name="tried-ice-cream" Multiple Size="3">
      <OPTION Value="conservative">Vanilla
      <OPTION Value="conservative">Chocolate
      <OPTION Value="daring">Cherry Garcia
      <OPTION Value="strange">Pizza Pancake
   </SELECT><BR>

   Guess the secret password:
   <INPUT Type="password" Name="password-guess"><BR>

   Do you have an informal nickname?
      <INPUT Type="radio" Name="nickname" Value="No" Checked>No
      <INPUT Type="radio" Name="nickname" Value="Yes">Yes, it is:
      <INPUT Type="text" Name="user-nickname" Size="12" Maxlength="12"><BR>

   Enter your personal motto:<BR>
   <TEXTAREA Name="user-motto" Rows="2" Cols="40">
All is well that ends well.
   </TEXTAREA><BR>

   When you are done with the above responses, please submit this information
   by clicking on your current geographic location on this map:<BR>

   <INPUT Type="image" Src="http://www.december.com/html/images/world.gif"
          Name="user-image-location" Align="bottom"><BR>

   <INPUT Type="submit" Value="Send this survey">

   <INPUT Type="reset"  Value="Cancel this survey">
<BR>
</FORM>

Elements in a Form

As you can see from the syntax summary of the FORM element, several kinds of elements can be used within a form to provide interfaces for user response. The following description is a narrative through the most popularly used elements.

The INPUT element is the basic way to get input from the user in a variety of situations. The key is that an INPUT element can define many types of graphical user interface features: pull-down menus, radio buttons, text input boxes, text fields, and check boxes. These are all variations on the INPUT element with a different Type attribute set for each.

In many situations, eliciting user response can be done using INPUT. Asking for a user's name (when an exhaustive list of possibilities is not desirable), for example, is possible using INPUT as well as when asking for a response based on a strict enumeration of choices (for example, a user's gender).

Here's a sample INPUT tag that queries the user for a name (using "text" as the value of the attribute Type):

<INPUT Type="text" Size=40 Name="user-name">

The "text" value of the attribute Type identifies this as a single-line, text-input field that will be displayed at 40 characters. Because there is no Maxlength attribute set, the user can enter an arbitrary number of characters as input to this element, and the text will scroll as the user types it, although only 40 characters at a time are displayed.

The Name attribute of the INPUT element designates the variable name that will be used in the data structure sent to the query program. This name is used to identify the value of the user's response from this INPUT element.

The INPUT element is very versatile and can be used to create many different kinds of user interface features. This is an INPUT check box example used to ask the user to fill in any number of responses.

You can use this code to check the names of the people listed whom you have heard about or know personally, for example:

<INPUT Type="checkbox" Name="knows-marc">Marc Andreessen
<INPUT Type="checkbox" Name="knows-lisa">Lisa Schmeiser
<INPUT Type="checkbox" Name="knows-al">Al Gore

This is an INPUT radio button example used to ask the user to fill in one, and only one, selection from a series of responses:

Your gender:

<INPUT Type="radio" Name="user-gender" Value="M">Male
<INPUT Type="radio" Name="user-gender" Value="F">Female

Like the INPUT element, the SELECT element is used for querying the user. The SELECT element is specialized for creating drop-down or scrollable lists of menus only, however. SELECT has a partner element, OPTION, to delimit the choices the user has for selection. The basic structure of a SELECT element follows:

<SELECT Name="select-menu">
<OPTION> View the product.
<OPTION> Call for help.
<OPTION> Request a catalog.
<OPTION> Exit this form.
</SELECT>

This SELECT offers the user one, and only one, choice of the possible responses, and only one choice is visible. It is rendered as in example 1 of Figure 14.3.

Figure 14.3 : Sample SELECT elements.

The Name attribute is used to create a label for the SELECT data structure ("select-menu"). Notice that in the preceding arrangement, only one of the options is visible at a time, and all are accessed through a drop-down menu. Functionally, this is equivalent to the radio button possibility with the INPUT element of Type="radio", where one, and only one, of a set of options can be made. To make more than one choice visible at a time, the Size attribute can be added:

<SELECT Name="select-menu" Size="3">
<OPTION> View the product.
<OPTION> Call for help.
<OPTION> Request a catalog.
<OPTION> Exit this form.
</SELECT>

This kind of a SELECT statement is rendered as example 2 in Figure 14.3.

In both of the previous examples of SELECT statements, the user can make one, and only one, choice. By adding the attribute Multiple, the user can choose among several options:

<SELECT Name="select-menu" Size="3" Multiple>
<OPTION> View the product.
<OPTION> Call for help.
<OPTION> Request a catalog.
<OPTION> Exit this form.
</SELECT>

This SELECT statement is rendered as in example 3 of Figure 14.3.

The user can select more than one of the options. Functionally, this is equivalent to the check box possibility used with an INPUT element of Type="checkbox", where any number of selections can be made. Thus, the SELECT element does repeat the functionality available with the INPUT element, but it offers a different appearance for the users.

The TEXTAREA element is used to ask the user to enter several lines of text (as opposed to the single line with an INPUT element of Type="text").

A sample TEXTAREA tag follows:

<TEXTAREA NAME="comments" ROWS=4 COLS=30></TEXTAREA>

This allows the user to enter any amount of text, with only four rows and 30 columns visible. The user can type more text than the amount visible, however, with the browser allowing an arbitrary amount of text to be entered.

Having a Form Do Something

After the form's front end or graphical user interface is created, the next step is to create an executable script to be referred to in the Action attribute of the FORM element. For some Web servers, having a script execute through a form requires permission to a directory designated for gateway programs (usually, the cgi-bin directory or other directory designated in the Web server setup). Users without permission to this designated directory will not be able to execute a program through a form.

Echo Input Using a Test Gateway Program

Listing 14.2 shows a sample form to echo input based on a test gateway program provided by NCSA.


Listing 14.2. A sample order form.
<HTML>
<HEAD>
   <TITLE>Example Order Form</TITLE>
</HEAD>

<BODY>

<H1>Order Form</H1>

<P>
Please fill out the following form.

<FORM Method="post" Action="http://hoohoo.ncsa.uiuc.edu/cgi-bin/post-query">
    <P>
    Your Name:
    <INPUT Type="text"  Size=32 Name="user-name"><BR>

    Customer Number:
    <INPUT Type="number" size=10 name="customer-number"><BR>

    Shirt Size?
    <INPUT Type="radio" Value="S" Name="shirt-size">S
    <INPUT Type="radio" Value="M"  Name="shirt-size">M
    <INPUT Type="radio" Value="L" Name="shirt-size">L
    <INPUT Type="radio" Value="XL" Name="shirt-size">XL

    <P>
    What would you like?<BR>
    <SELECT Name="would-like" Size=2 Multiple>
    <OPTION>View the product.
    <OPTION>Call for help.
    <OPTION>Request a catalog.
    </SELECT>

    <P>
    Your comments? <BR>
    <TEXTAREA Name="comments" Rows="4" Cols="30"></TEXTAREA>

    <P>
    <INPUT Type=submit Value="Order Product">
    <INPUT Type=reset  Value="Cancel Order">
    </FORM>

</BODY>
</HTML>

After the form is filled in by the users and they click the Submit button ("Order Product"), the results are sent to the demonstration query program (at http://hoohoo.ncsa.uiuc.edu/cgi-bin/post-query). This test server is provided by NCSA developers to echo the data structure submitted by a post query. Implementers could develop their own program that would have used the form values in some other way.

Figure 14.4 shows an example of how this form might be filled in, and Figure 14.5 shows the results of the user submitting the query.

Figure 14.4 : A filled-in sample echo form.

Figure 14.5 : The sample echo form results.

The next section shows how to create such an echo program using a Perl script.

Echo Input Using a Perl Script

The key for developers to manipulate the variable name/variable value pairs provided by a form is to create a program or script to deal with them. This section shows an example using a Perl script. Developers can find out how Perl is installed on their UNIX system by entering the command which perl at the UNIX prompt.

This example assumes that the developer creates the same form as shown in Figure 14.4, but with the Action URL changed to a local program, simpleform.cgi, located in the cgi-bin directory of the host:

<FORM Method="get" Action="http://host.domain/cgi-bin/simpleform.cgi">

By locating this file in this gateway program directory, the developer's server executes the program instead of displaying its contents to the user. Listing 14.3 shows the Perl code in the file simpleform.cgi, which echoes the input variables.


Listing 14.3. A simple script to echo input.
#!/usr/local/bin/perl
#------------------------------------------------------------------------
# Simple Perl script to echo a FORM's input
#------------------------------------------------------------------------
print "Content-type: text/html\n\n";
if ($ENV{'REQUEST_METHOD'} eq "get") { $buffer = $ENV{'QUERY_STRING'};

else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }
print "<HTML><HEAD>\n";
print "<TITLE>Query Results</TITLE>\n";
print "</HEAD><BODY>\n";
print "Query Results\n";
print "<PRE>\n";
@nvpairs = split(/&/, $buffer);
foreach $pair (@nvpairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
print "$name = $value\n";
}
print "</PRE>\n";
print "</BODY></HTML>\n";

This Perl code extracts information about the user's response in the form based on environment variables using the application/x-www-form-urlencoded encoding scheme described in Chapter 13.

Based on the user input shown in Figure 14.4, the simpleform.cgi script produces this output:

Content-type: text/html
<HTML><HEAD>
<TITLE>Query Results</TITLE>
</HEAD><BODY>
Query Results
<PRE>
user-name = Jane Doe
customer-number = 12345
shirt-size = M
would-like = View the product.
Would-like = Call for help.
comments = Please giftwrap the package.
</PRE>
</BODY></HTML>

This output is sent to the user's browser, and the display is similar to the output shown in
Figure 14.5.

Send E-Mail Using a Form

The echo program described in the preceding section is just the start of a developer's use of gateway programs with forms. Another variation is to use the form to send an electronic mail message.

For e-mail, the address of the recipient must be designated. This can be done by adding the following line to the form shown in Figure 14.4 anywhere within the FORM element:

<INPUT Type="hidden" Name="receiver" Value="john@december.com">

Also, the sender's e-mail address needs to be identified by this line anywhere within the FORM element:

Your email address: <INPUT Type="text" Name="sender" Size="20">

Finally, the Action attribute is set to a new script called mailform.cgi:

<FORM Method="get" Action="http://host.domain/cgi-bin/mailform.cgi">

The mailform.cgi contains the Perl code necessary to take the FORM variables and create a mail session echoing them to the designated receiver, as shown in Listing 14.4.


Listing 14.4. A simple script to send mail.
#!/usr/local/bin/perl
#------------------------------------------------------------------------
# Perl program to send mail to a user.
#------------------------------------------------------------------------
$mailprog = '/usr/lib/sendmail';
print "Content-type: text/html\n\n";
if ($ENV{'REQUEST_METHOD'} eq "get") { $buffer = $ENV{'QUERY_STRING'};

else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }
@nvpairs = split(/&/, $buffer);
foreach $pair (@nvpairs)
{
 ($name, $value) = split(/=/, $pair);
 $value =~ tr/+/ /;
 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 $FORM{$name} = $value;
}
# REFERENCE POINT A
$recipient = $FORM{'receiver'};
#
# format the mail file
format MAIL =
~~<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<&l t;<<<<<<
$value
.
# Open the mail file and write to it
open(MAIL, "|$mailprog -t") || die "$mailprog not available.\n";
print MAIL "To: $recipient\n";
print MAIL "From: $FORM{'sender'}\n";
print MAIL "Subject: FORM test from $FORM{'sender'}\n\n";
print MAIL "Dear $FORM{receiver},\n\n";
print MAIL "\n";
print MAIL "The user chose:\n\n";
foreach $pair (@nvpairs)
 {
 ($name, $value) = split(/=/, $pair);
 $value =~ tr/+/ /;
 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 print MAIL "$name = $value\n";
 }
print MAIL "\n";
close (MAIL);
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Mail Sent</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "<P>Mail has been sent from $FORM{'sender'} to
FORM{'receiver'}.\n";
print "</BODY>\n";
print "</HTML>\n";

After the user clicks the Submit button for this form, the following results are generated:

Content-type: text/html
<HTML>
<HEAD>
<TITLE>Mail Sent</TITLE>
</HEAD>
<BODY>
<P>Mail has been sent from janedoe@host.domain to john@december.com.
</BODY>
</HTML>

This result is displayed on the user's browser, as shown in Figure 14.6.

Figure 14.6 : Form mail results.

Meanwhile, the designated receiver of the e-mail message receives an e-mail message like this:

Date: Mon, 05 Jul 1996 20:29:38 -0400
Message-Id:
From: janedoe@host.domain
Subject: FORM test from janedoe@host.domain
Apparently-To: john@december.com
Dear john@december.com,
The user chose
sender = janedoe@host.domain
receiver = john@december.com
user-name = Jane Doe
customer-number = 12345
shirt-size = M
would-like = View the product.
Would-like = Call for help.
comments = Please giftwrap the package.

Check Input in a Form

The preceding examples demonstrate how a simple Perl script can be used as a gateway programming language to manipulate the variable name/value pairs the users set in a form. Another variation on this is to use the programming language to check entries of the users. In the previous mail form, for example, the user might have neglected to enter his or her e-mail address (the "sender") field. The developer can accomplish this checking by adding the following Perl code at the point labeled # REFERENCE POINT A in Listing 14.4:

if ($FORM{"sender"} eq "") {
 print "<HTML>\n";
 print "<HEAD>\n";
 print "<TITLE>Entry Error: Email Field Blank</TITLE>\n";
 print "</HEAD>\n";
 print "<BODY>\n";
 print "<P>Your email address was left blank. Please enter it.\n";
 print "</BODY>\n";
 print "</HTML>\n";
 exit(0);
}

Users would be required to fill in some characters for their e-mail address. Of course, far more sophisticated checking would need to be done to verify that it is a valid e-mail address. Verifying that the e-mail address given actually belongs to the user submitting the request using the method demonstrated here is impossible. Some users have their e-mail address set up in an environment variable that can be made available to a gateway program; however, this environment variable could be forged to be any arbitrary e-mail address.

Forms Design and Implementation Issues

Forms can be used very flexibly both functionally and visually. The web developer can use the following tips when creating forms.

Functional Issues
INPUT elements of Type="checkbox" are functionally equivalent to SELECT elements with the Multiple attribute set. The check boxes are all visible to the user at the same time, however, so for a very large number of options, the SELECT element with a Size attribute set to a small number (for example, 3 or 4) might be the best way to go. This would simplify the visual interface by reducing the number of choices the user sees.
Note that when using the radio Type INPUT element, it's useful to use the optional Value attribute to set a value for each possible response. Otherwise, the value by default is set to "on." Paired with a variable name (for example, "gender"), the result could be "gender" has the value "on", which is ambiguous given the user's choice of "M" or "F".
Layout Issues
Text labels should be placed consistently to the left or right of the input boxes for the user. Figure 14.4 shows the consistent placement of text to the left (or top) of the input areas for the user. The text labels on the radio button INPUT element also are placed to the left with a colon (:) placed as a cue after each choice to indicate that the selection button follows.
Long forms might be best implemented in tables to provide better alignment and a more compact appearance.

Key On-Line Forms Resources
Forms Tutorial, by Alan Richmond: This on-line resource leads the user through some of the basics as well as advanced forms structures (http://WWW.Stars.com/Tutorial/HTML/Forms/).
Mosaic for X version 2.0 Fill-Out Form Support, by National Center for Supercomputing Applications (NCSA): This document describes forms as used with the NCSA servers (http://www.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/fill-out-forms/overview.html).
Digital Equipment's Form Test Suite: This page helps the developer check out how forms will behave under different browsers (http://www.research.digital.com/nsl/formtest/home.html).
Yahoo!'s Forms collection: This is the entry from the Yahoo! database showing many entries for forms information (http://www.yahoo.com/Computers/World_Wide_Web/Programming/FORMs/).

Tables

Tables are a very flexible way to do what many beginning HTML users want to do: line up items according to a grid pattern. A grid pattern can be a very effective way to provide visual cohesion on a web page. The clown-pants design problem in Chapter 7, for example, was resolved by using a table.

The element TABLE is used to define tables. Within the table element, you use the TR element for table rows, TH for table headers, TD for table data, and the CAPTION element for the table's caption. Here's a simple table example:

<!-- Simple Table Example -->
<!-- Author: john@december.com -->
<!-- Date created: 05 July 1996 -->
<TABLE>
   <CAPTION>The Stanley Cup Results.</CAPTION>
   <TR><TH>Game</TH><TH>Red Wings</TH><TH>Black Hawks</TH></TR>
   <TR><TD>1</TD><TD>3</TD><TD>2</TD></TR>
   <TR><TD>2</TD><TD>4</TD><TD>1</TD></TR>
   <TR><TD>3</TD><TD>0</TD><TD>8</TD></TR>
   <TR><TD>4</TD><TD>8</TD><TD>7</TD></TR>
   <TR><TD>5</TD><TD>2</TD><TD>1</TD></TR>
</TABLE>

This code is rendered in a browser, as shown in Figure 14.7.

Figure 14.7 : A simple table.


TABLE Attributes

Align  The horizontal alignment of the table on-screen (not the contents of the table). Possible values follow:

bleedleft  Aligned at the left window border

bleedright  Aligned at the right window border

center  Centered between text margins

justify  Table should fill space between text margins

left  At the left text margin

right  At the right text margin

Border  Causes browser to render a border around the table; if missing, the table has no grid around it or its data. You can set the thickness of the border by giving this attribute an integer value. For example: Border="3" gives the table a three-pixel border.

Cellpadding  You can set this to the number of pixels you want placed between cells of the table.

Cellspacing  You can set this to the number of pixels you want placed around the data in the cells.

Width  Specifies how wide the table will be; if given as NN%, the width is NN% of the width of the display; otherwise, the width is in pixels. It's not advisable to give the width in pixels, because you don't know how wide your users' browsers will be.


The CAPTION element is used to label a figure or table. Its attribute is Align, which is used to position the caption relative to the figure or table. Values include top, bottom, left, and right.

The TH element identifies a table header cell, and TD identifies a table data cell. Browsers usually treat these two elements differently in terms of how they are rendered. In general, a TH element's contents are placed in boldface and centered by default. A TD's elements usually are aligned to the left.


TD and TH Attributes

Align  Horizontal alignment of the paragraphs in a table row; values include left, center, right, justify, and decimal (text aligned on decimal points).

Colspan  Specifies the number of columns the cell spans.

No wrap  Prevents the browser from wrapping the contents of the cell.

Rowspan  Specifies the number of rows the cell spans.

Valign  Vertical alignment of material in a cell. Values include top, middle, and bottom.


The TR identifies a container for a row of table cells. Its attributes are the same as for TH and TD.

Working with tables is fairly easy and usually leads to pleasing results when you fine-tune your elements. Our Stanley Cup playoff scores weren't all that appealing in Figure 14.7, for example. We can center the data and add some cell spacing and padding as well as a border, as shown in Listing 14.5.


Listing 14.5. A simple table example with data centering.
<!-- Simple Table Example with data centering -->
<!-- Author: john@december.com -->
<!-- Date created: 05 July 1996 -->
<BODY>

<TABLE Border="2" Cellpadding="3" Cellspacing="3">
   <CAPTION>The Stanley Cup Results.</CAPTION>
   <TR><TH>Game</TH><TH>Red Wings</TH><TH>Black Hawks</TH></TR>
   <TR><TD Align="center">1</TD Align="center"><TD Align="center">3</TD Align="center"><TD Align="center">2</TD Align="center"></TR>
   <TR><TD Align="center">2</TD Align="center"><TD Align="center">4</TD Align="center"><TD Align="center">1</TD Align="center"></TR>
   <TR><TD Align="center">3</TD Align="center"><TD Align="center">0</TD Align="center"><TD Align="center">8</TD Align="center"></TR>
   <TR><TD Align="center">4</TD Align="center"><TD Align="center">8</TD Align="center"><TD Align="center">7</TD Align="center"></TR>
   <TR><TD Align="center">5</TD Align="center"><TD Align="center">2</TD Align="center"><TD Align="center">1</TD Align="center"></TR>
</TABLE>

You get the table shown in Figure 14.8.

Figure 14.8 : A simple table with some more flairs.

Here are some tips for working with tables:

The browser sets the number of columns in a table to be the greatest number of columns in all the rows. Blank cells are used to fill any extra columns in the rows.

A More Complex Sample Table

Now look at more of the table elements with a more complex example, as shown in Listing 14.6.


Listing 14.6. A level 3 table example.
<!-- Level 3 Table Example -->
<!-- Author: John December -->
<!-- Date created: 04 Jun 1995 -->
<!-- Last update: 21 Oct 1995 -->
<TABLE Border>
   <CAPTION Align="top">A more complex table-within-a table.</CAPTION>

   <TR><P>
   <TH>Outer Table</TH>
   <TD>
      <TABLE Border>
      <CAPTION Align="top">An inner table showing
               a variety of headings and data
       items.</CAPTION>
      <TR><P>
         <TH Colspan="5">Inner Table</TH>
      </TR>
      <TR><P>
         <TH Rowspan="2" Colspan="2">CORNER</TH>
         <TH Colspan="3">Head1</TH>
      </TR>
      <TR><P>
         <TH Rowspan="2">Head2</TH>
         <TH Colspan="2">Head3</TH>
      </TR>
      <TR>
         <TH>Head4</TH><TH>Head5</TH><TH>Head6</TH>
      </TR>
      <TR><P>
         <TD>A</TD>
         <TD Rowspan="2" Valign="middle">Two Tall</TD>
         <TD><UL><LI>Lists can be table data
                   <LI>Images can be table data</UL></TD>
         <TD Colspan="2" Align="center">Two Wide</TD>
      </TR>
      <TR Valign="middle">
         <TD><IMG Src="../images/icon.gif" ALT="HTML Station"></TD>
         <TD Align="center">
            A <A Href="form.html">Form</A> in a table:
            <FORM Method="POST"
               Action="http://hostcgi-bin/mailer">
               <INPUT Type="hidden" Name="address" Value="nobody@rpi.edu">
               <INPUT Type="hidden" Name="subject" Value="Table Example">
               Your age: <INPUT Type="text" Name="user-age" Size="2"><BR>
               What is your favorite ice cream?<BR>
               <SELECT Name="favorite-icecream">
                  <OPTION>Vanilla
                  <OPTION Selected>Chocolate
                  <OPTION>Cherry Garcia
                  <OPTION>Pizza Pancake
                  <OPTION>None of the above!
               </SELECT><BR>
               <INPUT Type="submit" Value="OK">
               <INPUT Type="reset" Value="Cancel">
            </FORM>
         </TD>
         <TD>
            <TABLE>
            <CAPTION>No border</CAPTION>
            <TR><P><TH>Little</TH></TR>
            <TR><P><TD>Table</TD></TR>
            </TABLE>
         </TD>
         <TD>Multiple<BR>line<BR>item</TD>
      </TR>
      </TABLE>
   </TD>
   </TR>
</TABLE>

This table is rendered as in Figure 14.9. Note how I've included a table within a table, and also an image and a form within the data elements of the table.

Figure 14.9 : A more complicated table example.

For a more practical example, see the Period Table of the Elements (WebElements) at http://www.cchem.berkeley.edu/Table/index.html.

Frames

Netscape Navigator's extensions include an extension called frames. With frames, you can divide a browser window into different panes of information that can be viewed and changed independently. Currently, frames are recognized only by Netscape and Microsoft Internet Explorer browsers.

Some problems also exist with frames; they violate many of the navigation practices that users have come to expect, they are fairly difficult to use well, and users easily can get confused using them. No longer is the current URL display on the browser valid, printing no longer is straightforward, and there's the possibility of the infinite fragmentation of the user's browser window (which I'll illustrate with an example later in this discussion). Because the style sheet extension of HTML is expected to enable you to do something similar to frames, I advise Web developers to use frames sparingly and only when they closely fit the users' needs.

The new elements to implement frames are FRAMESET, FRAME, and NOFRAMES. The attribute Target of the A (anchor) element also is added. The FRAMESET element is the container for a frame; instead of having a BODY element, a frame document uses FRAMESET. This element can be nested.


FRAMESET Attributes

Cols = "col_width_value_list"  A comma-separated list of values indicating the width of each of the columns. The values are the same syntax as for the Rows attribute.

Rows = "row_height_value_list"  a comma-separated list of values indicating the height of each of the rows.

The FRAME element identifies a single frame in a frameset.


FRAME Attributes

Marginheight = "value"  The number of pixels to add to the top and bottom of the contents of the frame.

Marginwidth = "value"  The number of pixels to add to the left and right of the contents of the frame.

Name = "text"  Assigns a name to the frame. This name then can be used in other documents in the Target attribute of the A (anchor) element.

Noresize  A flag that indicates that the frame is not resizable by the user. Normally, a user can manually alter the size of the frame by using the small boxes that appear on the display of the frame. The Noresize attribute makes this resizing impossible.

Src = "url"  The url refers to the resource to be displayed initially in this frame.

Scrolling = "yes | no | auto"  This allows you to control if and when the scrollbars appear in the frame. Normally, scrollbars are added only if there is not enough room to display all the contents in the frame. The yes value for this attribute adds scrollbars to the frame even if the frame contents can fit within the frame itself. A no value means that scrollbars never will be added, even if they are needed. The value of auto (the default) means that the scrollbars are added when necessary.


The NOFRAMES element brackets contents that will be rendered by non-frame-enabled browsers. Typically, this content is a BODY element and a page of HTML.

The frames scheme adds an attribute to the A (anchor) element: Target. This attribute defines in which frame the new content referenced in the anchor is displayed when selected.


Target Attributes

_blank  Displays the new document in a new, unnamed window

name  A frame named in a FRAME element's Name attribute

_parent  Displays the new document in the parent frame; if no parent, same as _self

_self  New document is displayed in the same frame as the anchor that loads it; this is the default

_top  Displays the new document in the entire window; if no frames, same as _self


The BASE element also gets a new attribute for frames, Target, which lets you set the default target for every hypertext link in the document. Its possible values are the same as for the Target attribute of the A element. A common use for this is to set Target="_blank" for every hyperlink in a long list of external documents. A new browser appears for every resource in the list the user selects. The benefit is that users of such a set of links never "lose" your original page; it always is on the parent browser. The downside is that users get a new browser spawned for every link they select.

A Sample Use of Frames

Let's put together the earlier syntax for frames in an example. First, you build an HTML document, which is called a layout document, that contains no BODY element. Instead, it contains a FRAMESET element that contains the FRAMES that will appear in the document. Listing 14.7 shows the FRAMESET file.


Listing 14.7. HTML frame extension from Netscape.
<HTML>
<!-- HTML FRAME extension from Netscape -->
<!-- Author: John@December.com -->
<!-- Created: 06 Dec 1995 -->
<!-- Update: 05 July 1996 -->
<!-- NOTE: No BODY or other TAG used -->
<!-- NOTE: This is called a LAYOUT document -->
<HEAD>
   <TITLE>Netscape FRAME Example</TITLE>
</HEAD>
<! -- Here is the FRAME information for browsers with frames -->
<FRAMESET Rows="*,*"><!-- Two rows, each equal height -->
   <FRAMESET Cols="*,*"><!-- Two columns, equal width -->
      <FRAME Src="findex.html"  Name="ul-frame">
      <FRAME Src="findex.html"  Name="ur-frame">
   </FRAMESET>
   <FRAMESET Cols="*,*"><!-- Two columns, equal width -->
      <FRAME Src="findex.html" Name="ll-frame">
      <FRAME Src="findex.html" Name="lr-frame">
   </FRAMESET>
</FRAMESET>
<! -- Here is the NOFRAME information displayed by browsers without frames -->
<NOFRAMES>
   <BODY>
      <P>
      This document requires a browser capable
      of rendering frames to view it.
   </BODY>
</NOFRAMES>
</HTML>

In the FRAMESET file, I have two rows and two columns. The first FRAMESET element is the outer container that holds the two rows. Its attribute and value (Rows="*,*") sets up the two equally-sized rows. Inside this element are two other FRAMESET elements, each of which sets up a row of two columns with the Cols="*,*" attribute. Within each of these rows are two FRAME elements. I give each element a name to indicate its position within the arrangement of frames: ul-frame, ur-frame, ll-frame, and lr-frame. Finally, I use the NOFRAMES element or give a message to people without a frames-capable browser.

I set each the frame's contents with the Scr attribute set to a file called findex.html. Listing 14.8 shows that file's contents.


Listing 14.8. HTML FRAME index.
<HTML>
<!-- HTML FRAME index -->
<!-- Author: john@december.com -->
<!-- Created: 06 Dec 1995 -->
<!-- Updated: 05 Jul 1996 -->
<HEAD>
   <TITLE>Frame Index</TITLE>
</HEAD>
<BODY>
<BASEFONT Size="6">
   <A Href="framea.html" Target="ur-frame">A</A> /
   <A Href="frameb.html" Target="ll-frame">B</A> /
   <A Href="framec.html" Target="lr-frame">C</A> /
   <A Href="framed.html" Target="_blank">D</A>
</BASEFONT>
</BODY>
</HTML>

The findex file just is a regular HTML file that acts as a switching index for four other files of sample frame content: framea.html, frameb.html, framec.html, and framed.html. In the A element corresponding to each of these files, I indicate the target frame the browser displays after the user selects the hotspot. Each of these files is of the form shown in Listing 14.9.


Listing 14.9. HTML FRAME example holder A.
<HTML>
<!-- HTML FRAME example holder -->
<!-- Author: john@december.com -->
<!-- Created: 05 Jul 1996 -->
<HEAD>
   <TITLE>Frame A</TITLE>
</HEAD>
<BODY>
<BASEFONT Size="7">
   <A Href="findex.html">Index</A>
<P>
Able
<P>
Able
<P>
Able
</BASEFONT>
</BODY>
</HTML>

The file framec.html is a little different, as Listing 14.10 shows.


Listing 14.10. HTML FRAME example holder C.
<HTML>
<!-- HTML FRAME example holder -->
<!-- Author: john@december.com -->
<!-- Created: 05 Jul 1996 -->
<HEAD>
   <TITLE>Frame C</TITLE>
</HEAD>
<BODY>
<BASEFONT Size="7">
<A Href="findex.html">Index</A>
      <P>
      Charlie <A Href="framea.html" Target="_self">A to _self</A>
      <P>
      Charlie <A Href="frameb.html" Target="_parent">B to _parent</A>
      <P>
      Charlie <A Href="framed.html" Target="_top">D to _top</A>
      <P>
      Charlie <A Href="http://www.december.com/html/" Target="_self">HTML
Station to self</A>
</BASEFONT>
</BODY>
</HTML>

The result is that I have a system of content that can be "switched" based on what the user wants. Figure 14.10 shows the initial appearance of the frameset.html file as soon as it is loaded in a Netscape browser.

Figure 14.10 : The initial appearance of the frameset example.

Figure 14.11 shows the result of selecting the A link from the upper right frame.

Figure 14.11 : The frameset example after the A selection.

Note that I could have produced the same output by selecting any of the A hotspots in any of the frames, because all the links are the same-mapping the framea.html file contents to the frame named ur-frame. I can click the B and C hotspots to get Figure 14.12.

Figure 14.12 : The frameset example after the B and C selection.

I set the Target for the D link to _blank so that when I click the D hotspot, I get Figure 14.13. Note that a new browser has popped up with the D file contents displayed in it.

Figure 14.13 : The frameset example after the D to_top selection.

I also show some other examples in the framec.html file, in the lower right-hand frame of Figure 14.13. By clicking A to _self in the C frame, the framea.html contents are replaced in the lower right-hand frame. If you click B to _parent, the four frames (the parent window for the lower right-hand frame) are replaced by the contents of the file frameb.html. This same thing happens if you click D to _top.

The final selection in the lower right-hand corner frame, HTML Station to _self, places the front page of the HTML Station (http://www.december.com/html/) in the lower right-hand frame (see Fig. 14.14).

This is where the use of frames can become confusing. I can click HTML Station to _self and see a display that was not designed to fit or work in a frame on a window. If I want to select more information in this frame, I must resize the other frames so that I can see it better or try to bring up the HTML Station resource itself in the entire window. The latter action could be a bit difficult, though, because the URL that would appear at the top of the browser window in Figure 14.14 would not appear for the HTML Station but for the example frameset file. The user no longer has a quick way to find out the URL of a displayed resource. This kind of fragmentation could continue indefinitely if the user gets caught in resources referred to in the frames. The bottom line is that your frame design, in general, should avoid pointing to outside resources; the user might not be able to navigate these resources well within the frames you've set up.

Figure 14.14 : The frameset file after the HTML Station to_self selection.

Frames can be fairly useful, however, Netscape's own example is Anatomy of an Eye (http://www.netscape.com/comprod/products/navigator/version_2.0/frames/eye/index.html), as shown in Figure 14.15.

Figure 14.15 : Netscape's Anatomy of an Eye frame example (courtesy of Netscape Communications).

This is actually a pretty good application of frames. Its static frame, on the left, shows the diagram of the eye. You can click on the labeled parts of the eye and see a description in the right frame. This is straightforward and simple, and it is clear where you are in the document. There are no links to outside resources that could potentially fragment the window.

The Frame Game
Start from the display shown in Figure 14.12, in which you have the Index, Able, Baker, and Charlie contents in the four frames. Then, by clicking on exactly five links, you should be able to obtain the display in Figure 14.16, in which there are two baker displays at the bottom. Remember, you don't want to get your users caught in similar puzzles. In general, use frame content replacement sparingly; avoid complicated deployment of your content across panes in the browser. For the answer to this frame game, see the book support Web (http://www.december.com/works/hcu.html).

Figure 14.16 : The final state of the Frame Game.

For more information and examples of frames, see the frame syntax from Netscape (http://www.netscape.com/assist/net_sites/frame_syntax.html).

Forms, Tables, and Frames Check