4

HTML FormsThe Foundation of an Interactive Web

by Brian Deng



This chapter serves as a review of HTML forms. I will assume you have a working knowledge of HTML tags. The HTML tags discussed in this review are limited to those that pertain to creating forms. Later in this chapter, I will discuss some more advanced HTML tags to give your forms a better look and feel. This chapter introduces the CGI modules available for use with Perl5 and how they can be used to simplify the generation of HTML forms.

The CGI modules consist of several packages, or classes, written by various Perl contributors. These modules contain some very useful abstractions for HTML generation and CGI processing. Instead of learning how to parse the received data within your script, you can leverage the work already done by these Perl experts. The methods provided by these classes can take care of the dirty work and give you more flexibility to be creative with your Web content. As you will see, the CGI::Form package gives you an easy-to-use programming interface to create HTML forms.



NOTE:

You can obtain the CGI::Form module as well as other modules from the CPAN included on the CD provided with this book.


As you must already know, HTML forms are an essential reason for the Web's popularity. Forms bring a powerful interactive aspect to the Web. Another thing the HTML form provides is a cross-platform user interface. This capability is much more subtle than the first, but if deciding on a client platform is a difficult decision for you, HTML forms may be the answer. If you want to write simple applications such as the ones in subsequent chapters (or even more complex ones), you can focus on one piece of code to run on your server and provide a platform-independent user interface to your application through the Web. Forms still have some drawbacks, and these are mentioned in this chapter but discussed in greater detail in subsequent chapters.

HTML forms essentially consist of three things: a form declaration or header, one or more input fields, such as text fields or list boxes, and the button that submits the form data. This section discusses the different field types that can make up a form. Along with each field type is an example of how the HTML code might look, as well as how you can construct the field using the CGI::Form package.

The first thing you will need to do is construct a new CGI::Form object. This can be done by using the new() method. For example:

use CGI::Form;

$q = new CGI::Form;

The $q variable will then contain an instance of a CGI::Form object that can then be used to emit the HTML for your form using the methods listed in the following.

Text Fields

One of the most commonly used fields is the text field. This is an input field that allows the user to type in a single line of text. For multiple lines of text see "Text Areas" in the following section. Text fields can be used for things such as names, phone numbers, and other user input. Using raw HTML, you can create a text field using the INPUT tag with TYPE text as shown here:

<INPUT TYPE=text NAME="Name"" SIZE=32 MAXLENGTH=32 VALUE="Your name">

Using CGI::Form, this is a call to the method textfield, as shown here:

$q->textfield(-name=>'Name', -default=>'Your name', -size=>32, -maxlength=>32);

-name specifies the name of the field. This value is used later for querying the value of the field during the POST request. -default specifies the default value of the field. -size specifies the size, in characters, of the displayed text field. -maxlength specifies the maximum number of characters allowed for the field.

Text Areas

Text areas are very similar to text fields. The difference is that text area values can span multiple lines. Text areas might be used for such things as addresses or comments. Using raw HTML, you can create a text area using the <TEXTAREA> tag as shown here:

<TEXTAREA NAME="Address" ROWS=6 COLS=32>Your address</TEXTAREA>

Using CGI::Form, this is a call to the method textarea, as shown here:

$q->textarea( -name=>'Address', -default=>'Your address', -rows=>6, -cols=>32);

-rows specifies the number of rows to display to the user. -cols specifies the number of columns to display to the user. The user is not constrained to the values of -rows and -cols for his/her entry. If the user needs extra space to enter more text, he/she can use the scrollbars provided with this form field.

Password Fields

Password fields are also very similar to text fields. The difference is that the characters that are typed into the field are not displayed. This is useful for entering passwords (thus the name password field). Using raw HTML, you can create password fields using the INPUT tag with TYPE password like this:

<INPUT TYPE=password NAME=password VALUE="" SIZE=8 MAXLENGTH=8>

Using CGI::Form, this is a call to the method password_field, as shown here:

$q->password_field( -name=>'Password', -default=>'', -size=>8, -maxlength=>8 );

Radio Buttons

Radio buttons are used to select one out of several choices. This can be used for such things as designating a sex or marital status. Using raw HTML, you create radio buttons using the INPUT tag with TYPE radio. The CHECKED attribute can be used to specify which button to initially highlight. The following example shows how to highlight the button for selecting "male".

<INPUT TYPE=radio NAME='sex' VALUE='male' CHECKED>

<INPUT TYPE=radio NAME='sex' VALUE='female'>

Because radio buttons are generally created in groups, CGI::Form provides a single interface for creating a group of radio buttons. This method is called radio_group, as shown here:

$q->radio_group( -name=>'sex', values=>[`male', `female'], -default=>'female',

                 -linebreak=>'true' );

The -linebreak option causes the buttons to be laid out vertically aligned.

Checkboxes

Checkboxes are used for Boolean values. They can be used for things that require a yes or no response. Using raw HTML, you create checkboxes by using the INPUT tag with TYPE checkbox as shown in the following line:

<INPUT TYPE=checkbox NAME='want-notification' VALUE='yes' CHECKED>

Using CGI::Form, this is a call to the method checkbox:

$q->checkbox( -name=>'want-notification', -value=>'yes', -checked=>'true' );

Hidden Fields

Hidden fields are fields that do not appear on the form. At first you may wonder, "Why have hidden fields?" It turns out that hidden fields are an essential tool for solving the problem of maintaining state between transactions. In Chapter 16, "Advanced CGI/HTML," the concept of maintaining state will be discussed in great detail. Using raw HTML, you can create hidden fields using the INPUT tag with TYPE hidden:

<INPUT TYPE=hidden NAME='runningTotal' VALUE='36.25'>

Using CGI::Form, the following is a call to the method hidden:

$q->hidden( -name=>'runningTotal', -value=>'36.25' );



NOTE:

It turns out that one of the primary programming issues regarding HTTP and CGI is that of state. It is often essential for a programmer to keep track of certain values as the user is navigating through the user interface. This will become more obvious as you go through some of the examples.


Submit Buttons

Submit buttons initiate the action of sending the form data back to the server. A single form may have more than one Submit button to indicate what action is being performed. To create Submit buttons, use the INPUT tag with TYPE submit:

<INPUT TYPE=submit NAME='action' VALUE='Submit'>

Using CGI::Form, the following calls the method submit:

$q->submit( -name=>'action', -value=>'Submit' );

Reset Buttons

Reset buttons also appear as push buttons. The effect they have on the form, however, is to reset the contents of the form to its initial state of either blank fields or default values. Create Reset buttons by using the INPUT tag with TYPE reset, as shown here:

<INPUT TYPE=reset VALUE='Clear'>

Using CGI::Form, call the method reset, in the following manner:

$q->reset( -value=>'Clear' );

Image Buttons

Image buttons are the same as Submit buttons, except that an image is displayed instead of text. For example, you can place an image of a mailbox that could cause the action of mailing the form contents to a certain user. Using raw HTML, image buttons are created with the INPUT tag with TYPE image, as seen here:

<INPUT TYPE=image SRC="images/doit.gif" NAME='action' 

       VALUE='Doit' ALIGN=middle>

Using CGI::Form, this is a call to the method image_button, as shown in the following example:

$q->image_button( -src=>"images/doit.gif", -name=>'action', -value=>'Doit',

                  -align=>'middle' );

-src is used to specify the URL to the image which is to be displayed; -name specifies an arbitrary name associated with the image button; -value specifies an arbitrary value. The -name and -value parameters are important to distinguish the action between multiple image buttons on a form. -align is used to line up the image with the text that follows it. The possible values for -align are top, middle, and bottom.

Listboxes

Listboxes are fields that contain a scrollable list of text strings for single or multiple selection. You can use listboxes for such things as specifying a state (single selection) or product of interest (multiple selection). Use the SELECT and OPTION tags, as shown in the following lines, to create a listbox:

<SELECT NAME='State' SIZE=3>

<OPTION>CA

<OPTION>WA

<OPTION>OR

<OPTION>NV

<OPTION>AZ

</SELECT>

Using CGI::Form, this calls the scrolling_list method:

@states=( `CA', `WA', `OR', `NV', `AZ' );

$q->scrolling_list( -name=>'State', -values=>\@states, -default=>'CA',

                    -size=>3 );

The nice feature of using scrolling_list in CGI::Form is that the options can be stored within Perl arrays, which makes working with the data easier.

Popup Menus

With CGI::Form, popup menus, also referred to as drop-down lists, are single selection lists that expand when the user clicks the icon to the right of the text. Unlike listboxes, popup menus can only return a single selection. Popup menus use the <SELECT> tag with SIZE equal to 1:

<SELECT NAME='State' SIZE=1>

<OPTION>CA

<OPTION>WA

<OPTION>OR

<OPTION>NV

<OPTION>AZ

</SELECT>

Using CGI::Form, a call to the method popup_menu, is shown here:

@states=( `CA', `WA', `OR', `NV', `AZ' );

$q->popup_menu( -name=>'State', -values=>\@states, -default=>'CA' );

File-Upload Fields

File-upload fields enable the user to specify files for uploading to the server. Note that if you plan to use file-upload fields in your form, you must define your form as multipart/form-data. This is the new MIME type introduced by Netscape 2.0 for handling large amounts of data sent back to the server. This type also allows for binary data to be embedded within the form.

Using raw HTML, create file-upload fields with the INPUT tag and TYPE file:

<INPUT TYPE=file NAME=theFile>

Using CGI::Form, this is a call to the method filefield:

$q->filefield( -name=>'theFile' );

Image Maps

Image maps allow users to interact with the page by selecting a part of the image to navigate to another page or a location within the same page. Image maps are simply files that contain a list of area shapes on an image and their corresponding URLs. When a pixel on the image is clicked, the URL associated with the area containing that pixel is returned. The Perl package CGI::Imagemap is available for creating image maps within your Perl5 CGI script. The following are the possible pixel area groupings:

This image map is stored on your Web server and is referred to using a standard URL. Following is an example of a simple image map file:

circle food.html 10,10 15,15

rect entertainment.html 20,20 30,0

rect sports.html 50,20 60,0

You can use this image map together with the <A> and <IMG> HTML tags. In the following example, I will assume that the preceding map is stored in the file maps/menu.map and that it corresponds to an image called my_menu.gif.

<A HREF="maps/menu.map">

<IMG SRC=my_menu.gif ISMAP></A>

To use this image map along with an image in your form, use the CGI::Imagemap module. Using CGI::Form, create an image_button; for example,

print $q->image_button( -name=>'menu', -src=>'images/my_menu.gif',

                        -align=>'MIDDLE' );

Then, assume this image map is stored in the file maps/menu.map on your server. You can now associate the image map with the image using the following code:

use CGI::Imagemap;

use CGI::Form;



$q = new CGI::Form;

$x = $q->param( `menu.x' );

$y = $q->param( `menu.y' );

$map = $q->param( `maps/menu.map' );

$action = action_map( $x, $y, $map );

Other Form Elements

You can add other types of elements to your forms. The full list of available form fields is available in the HTML 3.2 evolving specification, which can currently be found at http://www.w3.org/pub/WWW/MarkUp/Wilbur/.

Generating HTML On-the-Fly with Perl5

There are two ways to define your form. The first is to create a static HTML file that contains all your form field definitions and reference the form to a particular CGI script. Another, perhaps easier, method is to dynamically display your form within your CGI script. The script can be called with a method get or a method post. When it is called with method get, you can respond with the form itself, and when it is called with method post, you can process the form request. Everything you print to stdout from your CGI script is returned back to the client (browser). This makes it very easy to generate HTML on-the-fly with Perl--especially when you use the CGI modules for form generation and processing. There is one drawback to this approach in that the Web server must execute a program to respond to the request rather than simply read a potentially cached file. If you don't mind the overhead of the extra process invocation, it will definitely make the job of maintaining your form and CGI program a lot easier.

Constructing Headers

The first part of an HTML form that you should generate is the header, which contains some important information about the text that is to follow. The most important piece of information is the MIME type. It is very important that you specify the correct MIME type for your HTML data. The first line of your output should always be Content-Type: text/html;. This line tells the browser what kind of data to expect. Fortunately, by using CGI::Form, you need not worry about this detail because it is the default type. Simply calling the method header returns the correct MIME type for you.

In addition to the document header, you will also need to correctly specify information about the types of any forms that are included in the document. This section will describe the two different types of forms as well.

print $q->header();

The HTML Header The next step is to construct the HTML header. The HTML header usually consists of just a title but may also include things that go into the <BODY> tag, such as background and foreground colors. Using the start_html method in CGI::Form provides a nice way to incorporate all of your HTML header information. In this example, I am starting an HTML document with a nice lavender background color (specified as a hexadecimal RGB triplet).

print $q->start_html(-title=>"Customer Survey Page",-author=>'bdeng@adobe.com',

                    -BGCOLOR=> "DDDDFF");

Not included in this function, however, is the new HTML 3.2 <!DOCTYPE> directive. This directive is what all HTML 3.2 conforming documents should begin with. This directive is actually part of SGML, but it is used to identify the HTML document as such. More information about HTML and SGML can be found at http://www.w3.org/pub/WWW/MarkUp. Hopefully, the start_html method will incorporate this standard at some point. Types of Forms Two different MIME types are currently defined for HTML forms. The first is application/ x-www-form-urlencoded. This is the original type defined for simple forms. The second is multipart/form-data. This type was introduced by Netscape 2.0 for the transfer of large chunks of data. It is important that you choose your form type appropriately. Generally speaking, if you need to support many different types of browsers, some of which may not handle multipart/ form-data, choose the original MIME type. However, if you want to use such fields as the file upload field, you must choose multipart/form-data. Eventually, all browsers should support multipart/form-data, at which point, it would be the obvious choice.

There are two methods within CGI::Form for starting your form--startform() and start_multipart_form(). You should use whichever one corresponds to the type of form you are creating. These methods take the optional parameters $method, $request, and $encoding. You shouldn't need to worry about the $encoding parameter because the method you choose will specify the appropriate encoding mechanism for your form. $method defaults to POST, and $action defaults to the current CGI script, which is generally what you want.

Constructing Elements

You have seen a few examples of how to define fields using CGI::Form. Now let's look at an example of a complete form. What you'll do is create a general questionnaire form for a restaurant. You'll ask the user these things: What did you order? (text field)

How was the service? (radio group)

How did the food taste? (radio group)

What is your age group? (popup menu)



Would you come back again? (checkbox)

The Perl code in Listing 4.1 generates these fields using a multipart/form-data type form.

Listing 4.1. Perl code for customer questionnaire.



use CGI::Form;

$q = new CGI::Form;



print "<H1>Customer Survey</H1>\n";

print $q->start_multipart_form();

print "What did you order? ";

print $q->textfield( -name=>'order', -value=>"", -maxlength=>30, -size=>30 );

print "<BR>"; # Line break

print "How was the service? (5-good,1-bad) ";

print $q->radio_group( -name=>'serviceRating', -values=>[`1','2','3','4','5'],

                       -default=>'3' );

print "<BR>";

print "How did the food taste? (5-good,1-bad) ";

print $q->radio_group( -name=>'tasteRating', -values=>[`1','2','3','4','5'],

                       -default=>'3' );

print "<BR>";

print "What age group are you in? ";

@ages=( `child', `teen', `20s', `30s', `40s', `50s', `senior' );

print $q->popup_menu( -name=>'ageGroup', -values=>\@ages );

print "<BR>";

print $q->checkbox( -name=>'comeAgain', -checked=>'checked', -value=>'yes',

                    -label=>"I would come back again " );

print "<BR><BR>";

print $q->submit( -name=>'Action', -value=>'Submit' );

print $q->reset();

print $q->endform();

This form appears in the browser, as shown in Figure 4.1.

You can include more than one form on a single HTML page. Each form can be associated with separate actions or the same action.

Figure 4.1. The questionnaire as it appears in the browser.

Included Files

One feature that is provided by some Web servers is server-side includes. You can configure your Web server in such a way that files of certain extensions (let's use the common one, .shtml) are parsed by the server before they are sent down to the client. There are two directives that tell the server to perform a specific operation with the file.

<!..#echo....> 

and

<!..#include...>

The server-side include feature is used to dynamically include nested HTML files. This feature enables some limited dynamically created content. The include directive is used to include other HTML files, much like a C program including header files. The echo directive allows you to dynamically display certain variables. The variables that can be displayed using the echo directive are as follows:

DATE_GMT

DATE_LOCAL

DOCUMENT_NAME

DOCUMENT_URI

LAST_MODIFIED

QUERY_STRING_UNESCAPED

For more information on SSIs, refer to HTML & CGI Unleashed (Sams, 1995).

As you saw previously, all of the HTML that you generate from your Perl script is dynamic. It would be very easy to incorporate this kind of information using simple print statements. For example, to print the local date, instead of using an echo directive you might write the following:

print "The current local time is: " . localtime() . "\n";

Or, to print Greenwich Mean Time, you could write:

print "The current time in Greenwich is: " . gmtime() . "\n";

The include directive of server-side includes can be easily implemented in Perl code, as in List-ing 4.2.

Listing 4.2. Perl subroutine for including another HTML file.



sub includeHTMLFile {

    local($theHTMLFile)=@_;

    local($thePathToHTMLFile)="$ENV{`DOCUMENT_ROOT'}/$theHTMLFile";

    open(IN,"< $thePathToHTMLFile") ||

        die "Cannot open file: $thePathToHTMLFile for read!\n";

    print(<IN>);

    close(IN);

}

In this example, the CGI environment variable DOCUMENT_ROOT determines the location of the included file. This is one of several well-defined environment variables for use in CGI programming.

You can extend the function in Listing 4.2 to process .shtml files and perform the proper action on the directives. Listing 4.3 shows a CGI program that uses the PATH_INFO environment variable to specify the .shtml file to parse. This CGI program can be specified as http://foo.bar.com/cgi-bin/parsessi.pl/included.shtml. PATH_INFO will contain /included.shtml, and that document will be returned with the proper SSI parsing having taken place.

Listing 4.3. parsessi.pl CGI program for including and parsing a .shtml file.



use CGI::Form;

$q = new CGI::Form;



print $q->header();

print $q->start_html(-title=>"Include Example",-author=>'bdeng@adobe.com',

                    -BGCOLOR=>"DDDDFF");

print "<H1>Include Example</H1>\n";

if ($ENV{`PATH_INFO'} ne "") {

   &includeHTMLFile($ENV{`PATH_INFO'});

} else {

   print "<P>No file was specified to parse";

}

print $q->end_html();



sub includeHTMLFile {

    local($theHTMLFile)=@_;

    local($thePathToHTMLFile)="$ENV{`DOCUMENT_ROOT'}${theHTMLFile}";

    open(IN,"< $thePathToHTMLFile") ||

        die "Cannot open file: $thePathToHTMLFile for read!\n";

    local(@lines)=<IN>;

    close(IN);

    foreach(@lines) {

        if (/\<!\.\.\#include(.*)\.\.\>/) {

            @parms=split(/ /,$1);

            foreach(@parms) {

               ($key,$val)=split(/=/,$_);

               $keys{$key}=$val;

            }

            &includeHTMLFile($keys{`file'});

        } elsif (/\<\!\.\.\#echo(.*)\.\.\>/) {

            @parms=split(/ /,$1);

            foreach(@parms) {

               ($key,$val)=split(/=/,$_);

               $keys{$key}=$val;

            }

            print $ENV{$keys{`var'}};

        } else {

            print;

        }

    }

}

Another method of incorporating raw HTML within your Perl script is to use what's known as here documents. Here documents are generally used to enclose large pieces of raw text and are constructed using ENDOFTEXT, where ENDOFTEXT is a label that you can arbitrarily choose. The rest of the Perl script will not be interpreted, but rather treated as plain text until the string ENDOFTEXT is found.



NOTE:

ENDOFTEXT must appear at the beginning of the line. All references to it after the first column are ignored.


An example of using a here document for embedding HTML text follows:

print <<ENDOFMYHTML;

<H3>Important Information</H3>

<P>This information is <B>very</B> important! Everything up until the

<BLINK>ENDOFTEXT</BLINK> line will appear in this page.

<HR>

ENDOFTEXT

Closing Up

To end your HTML document, you should call the end_html() method, which inserts the </BODY> and </HTML> tags for you.

print $q->end_html();

Heady StuffGenerating More Advanced (Possibly Dynamic) HTML

The concepts you have seen so far are fairly straightforward. Sometimes, you might want to do more than just display a few fields and process the Submit button. The next step is to take the initial building blocks and produce more complicated forms using other HTML tags. This section discusses some more advanced HTML generation using the Perl5 libraries.

Other Elements Within Elements

You also might want to incorporate form fields within other types of tags. This is easily done by combining the HTML for your special tags together with the output from these methods to produce formatted forms. This section discusses these approaches to work around some limitations. Using Tables for Better Field Layout One major drawback in HTML is the lack of ability to align fields. Suppose you wish to lay out your fields along a grid. If you desire this kind of effect, the trick is to use tables, which are available in HTML 3.2. Tables are defined using the <TABLE> and </TABLE> tags. Rows within a table are defined using the <TR> and </TR> tags. Columns within the row are defined using the <TD> and </TD> tags. Header columns within the row are defined using the <TH> and </TH> tags. Let's take the restaurant questionnaire form and make it look a bit nicer using a table. Although the <TABLE> tag provides a BORDER option, you probably won't want to use borders around your form fields. Borders are more suitable for displaying a table of data. The text prompts should go in the first column, and the others should go in the second column. You no longer need the line breaks because these are inferred by the table row definitions. The Perl code will now look something like Listing 4.4.

Listing 4.4. Perl code that emits a form formatted using the <TABLE> object.

use CGI::Form;

$q = new CGI::Form;



print "<H1>Customer Survey Using Tables</H1>\n";

print $q->start_multipart_form();

print "<TABLE>\n<TR>\n<TD>\n";

print "What did you order? ";

print "</TD>\n<TD>\n";

print $q->textfield( -name=>'order', -value=>"", -maxlength=>30, -size=>30 );

print "</TD>\n</TR>\n<TR>\n<TD>\n";

print "How was the service? (5-good,1-bad) ";

print "</TD>\n<TD>\n";

print $q->radio_group( -name=>'serviceRating', -values=>[`1','2','3','4','5'],

                      -default=>'3' );

print "</TD>\n</TR>\n<TR>\n<TD>\n";

print "How did the food taste? (5-good,1-bad) ";

print "</TD>\n<TD>\n";

print $q->radio_group( -name=>'tasteRating', -values=>[`1','2','3','4','5'],

                      -default=>'3' );

print "</TD>\n</TR>\n<TR>\n<TD>\n";

print "What age group are you in? ";

@ages=( `child', `teen', `20s', `30s', `40s', `50s', `senior' );

print "</TD>\n<TD>\n";

print $q->popup_menu( -name=>'ageGroup', -values=>\@ages );

print "</TD>\n</TR>\n<TR>\n<TD>\n";

print $q->checkbox( -name=>'comeAgain', -checked=>'checked', -value=>'yes',

                    -label=>"I would come back again " );

print "</TD>\n</TR>\n<TR>\n<TD>\n";

print $q->submit( -name=>'Action', -value=>'Submit' );

print $q->reset();

print "</TABLE>";

print $q->endform();

The form generated by this script will appear in the browser as shown in Figure 4.2.

Figure 4.2. The questionnaire, using a table, as it appears in the browser.

Using Netscape Frames You can also use Netscape frames to display multiple pages within a single browser window. Frames are defined using the <FRAME> tag, where each frame is associated with a single URL. You can have multiple CGI scripts running to produce a single Web page where each script runs within its own frame. An example HTML document that incorporates two frames running each of the above CGI programs follows:

<HTML>

<FRAMESET ROWS=50%,50%>

   <FRAME SRC="http://vaders/cgi-bin/wpp/testform.cgi">

   <FRAME SRC="http://vaders/cgi-bin/wpp/tablform.cgi">

</FRAMESET>

</HTML>



NOTE:

The <FRAME> tag is not an HTML 2.0 or 3.2 tag. It is a Netscape extension that is also supported in Microsoft's Internet Explorer 3.0. If you are concerned about compatibility with other browsers, you should avoid using frames or provide a non-frame alternative.


In this example, the page displays two horizontal frames of equal size. In the top frame, it will execute testform.pl, and in the bottom frame, it will execute tablform.pl. The frames are divided evenly across the page. The resulting page of this example is shown in Figure 4.3.

Figure 4.3. Both forms displayed in separate Netscape frames.

Other Objects: Applets, Images, Animation, and the <EMBED> Tag

Suppose you want to embed other types of objects within your Web page. You can do this in HTML using the <EMBED> tag. Many different companies have extended the definition of this tag to suit their object's needs. This section briefly describes what kinds of embeddable objects are out there and how you might go about incorporating them into your page, using available Perl library code.

Some types of embeddable objects are provided as Netscape plug-ins through the <EMBED> tag. For example, you can embed an Adobe Acrobat PDF file into your Web page if you have the PDF plug-in. You can also embed AVI files using the sample AVI plug-in provided from Netscape. The next example shows how to do both.

<embed src=movies/sample.avi width=300 height=100>

<br>

<embed src=pdfs/sample.pdf width=300 height=300>

The Adobe Acrobat Netscape plug-in is available at http://www.adobe.com. The Netscape plug-in development kit can be found at http://home.netscape.com. There are plenty of other Netscape plug-ins available. To see a complete list, visit the Netscape software page at http://home.netscape.com/comprod/upgrades/index.html. Additionally, you can embed audio and various other types of multimedia objects with the <EMBED> tag.

Java has become a huge buzzword in the industry of late. One of the things Java provides is the capability to download an executable applet from a Web server to a client browser and run that applet under a secure environment. Applets can be thought of as small application components that are useful for a specific task. These applets can provide a higher level of interaction that allows for some interesting Web page content. Some interesting Java applets can be found at http://www.gamelan.com. Java applets are included within an HTML document using the <APPLET> tag, as follows:

<APPLET CODE=JavaApplet.class WIDTH=200 HEIGHT=200>

</APPLET>

In this example, the Java applet is compiled into a file called JavaApplet.class, and when the browser loads the page containing this tag, JavaApplet.class will be downloaded and executed within the context of the browser.

What Forms Cannot Provide

You've just seen how forms can become a very valuable addition to your Web site. I have described the HTML form as a potential cross-platform, simple user interface. There are still some features that are missing that prevent it from replacing other traditional user interfaces. HTTP requests and responses are pretty much atomic in nature. This means that a persistent communication channel between the browser and the server is not directly supported. The protocol was intended as a means of requesting and serving small files over the Net to produce fairly rich graphical content. The lack of a persistent server-side state is obvious. This problem will be examined later on in Chapter 16, "Advanced CGI/HTML."

Another problem lies in the fact that the HTML form is a static entity once it reaches the browser. This means that it cannot handle certain user events that most user interface programmers probably take for granted. For example, suppose you want to enable or disable a field, depending on whether or not something is typed into a text field. This is common practice for most graphical user interfaces, yet it is not possible using HTML forms. There are alternatives for doing this kind of thing. For example, Java provides this type of client-side executable capability. Embedding a Java applet within your Web page can give you some more powerful capability. However, this extra capability does not come free. You would have to learn how to program with the Java AWT (applet window toolkit), and the transmission time for downloading the applet can be higher.

Summary

Now that you have learned all about HTML forms and how they can be generated with the CGI::Form module, you are ready to find out about the other, more powerful aspect of this module: its capability to simplify the processing of the form.