Forms allow us to gather information from users via a web page. The structure for a form is entirely part of the HTML specifications. That means that for the construction of the form, no other language or tool is necessary.
That, however, is true only of construction the form. Once a 'submit' button is pushed, then we need to be able to handle the information that the user has put into the form.
We will look at the use of forms in three sections:
I. Constructing an HTML form
II. Capturing form data - what do we do with it?
III. 'Validation' of form element content - check for desirable user input before sending the form contents to the server
[ Top of Page ]
A Slight Diversion
As you well know by now, HTML follows certain rules of an ISO standard SGML. It also breaks some of those rules, or rather makes following some of the rules optional in some cases.
With the advent of XML and its widespread use on the web, it is especially good practice now to follow normal SGML rules and not cut corners. Specifically, always use paired tags. Any tag that has content also can and should have a closing tag. (Some tags are not paired, such as <BR>.)
As an example of what I mean:
In tables, you open a cell with <TD>.
A second cell can be opened with another <TD>.
According to HTML specs, technically this is permissable:
<TD>SOME CELL CONTENT
<TD>NEW CELL CONTENT
BECAUSE the appearance of a new <TD> implies the presence of </TD> to close the previous cell.
In the past, it was considered acceptable practice to use implied tags in this way.
This is no longer good practice even though technically it is still valid HTML.
Why?
1) As I said, the appearance of XML on the scene raises the bar in terms of acceptable practice. Keep your HTML future-oriented by adopting 'best' practices now rather than just 'permissable' practices. This means that what you write will be accessible to programs and devices that are able to parse SGML documents on the fly and don't have the full HTML specifications built in.
2) You will make your HTML easier to read, easier to spot problems, easier to edit. You will also avoid sneaky cross-browser problems.
This applies to forms particularly in the SELECT drop down menu:
<option>data</option>
[ Top of Page ]
<form></form>
Use these tags to create a form. All form elements come between this Element Pair.
<select name="NAME"></select>
Creates a pulldown or scrollable menu, depending on attributes and properties you supply. Within this Element Pair will appear <option></option> pairs.
<option></option>
Sets off each menu item within a <SELECT></SELECT> element.
<input ....>
type, name, etc
<input type="checkbox" name="NAME">
Creates a checkbox. Descriptive text outside of tag needed to identify to user.
<input type="radio" name="NAME" value="x">
Creates a radio button. Descriptive text outside of tag needed to identify to user.
<input type="text" name="foo" size="20" maxlength="60">
Creates a one-line text area. Size sets length, in characters.
<input type="hidden" name="foo" value="something">
Allows you to pass information without user seeing it.
<input type="submit" value="NAME">
Creates a Submit button
<input type="image" border="0" name="NAME" src="name.gif">
Creates a Submit button using an image
<textarea name="NAME" cols="40" rows="8"></textarea>
Creates a text box area. Columns set the width; rows set the height.
<input type="reset" value="Clear the Form">
Creates a Reset button which clears the form of all input.
[ Top of Page ]
<form>...</form>
This creates an HTML form.
All of the elements of the form come between this pair.
There can be more than one form on an HTML page but they cannot overlap. You must start one form and end it before starting another.
The 'forms' collection is part of the Document Object Model.
The DOM is a branching structure with WINDOW at the top.
Here is a brief listing of some of the parts of the DOM. (The DOM is a huge model with many diverting branches.)
WINDOW (whatever is inside the browser window)
Here are the immediate "children" of the WINDOW node:
- location
- frames
- history
- navigator
- event
- screen
- document
We're dealing with the DOCUMENT node.
Here is the DOCUMENT node with its children nodes:
DOCUMENT
- links
- anchors
- images
- filters
- forms
- applets
- embeds
- plug-ins
- frames
- scripts
- selection
- stylesheets
- body
- paragraph
- table
- ... and any other HTML element
If there is more than one form on a page, they can be referenced like this:
(Note: counting starts at zero!)
document.form[0] - this is the first form
document.form[1] - this is the second form
and so on.
But if we use name="foo" in the <form> tag, like this:
<form name="mealplans"> .... </form>
<form name="interests"> .... </form>
then we can use
document.mealplans
document.interests
This is helpful because we don't have to count the elements in the document to figure out how to refer to the element we are interested in.
also we can use ID for the newer DOM
<form ID="mealplans"> .... </form>
<form ID="interests"> .... </form>
The elements of the form are the children nodes of the form, and they must be named for us to be able to refer to their value.
<form name="interests">
<P>What is your favorite sport?</P>
<select name="sports">
<option>Hockey</option>
<option>Football</option>
<option>Soccer</option>
</select>
</form>
Now we can refer to the selection that someone makes like this:
document.interests.sports.value
It is not important to know this simply to build an HTML form.
It will become important if you need to make sure that a user doesn't leave a field blank. You have to know how to check that and require that an entry is made. The DOM nomenclature is our handle to do just that, with a little Javascript. We'll come back to that later.
Here are links to pages that demonstrate most of the form children nodes - form elements. [Please use your browser BACK button TWICE to return to this page after submitting example.]
[ Top of Page ]
<form name="myForm" method="get" action="formtest.asp">
The default method of http and thus of a form is "get," so that
<form name="myForm" action="formtest.asp">
is equivalent to the explicit declaration in the previous example.
This simply means that any form data collected is passed along as part of a querystring which is attached to the url.
In plain language, the form data is attached to the address of the web page indicated in the in the action.
So that if a form has two elements, for example:
<form method="get" action="formtest.asp">
<select name="sports">
<option>hockey</option>
<option>football</option>
</select>
<input type="text" name="UserID">
<input type="submit" value="submit">
</form>
and the user selects "hockey" and puts in "Jim" as an id,
the data from this form is appended to the URL like this:
http://www.fredonia.edu/formtest.asp?sports=hockey&UserID=Jim
You've seen this before. To be a bit more complete, the URL itself with the querystring attached is being sent in the header of a HTTP request. There may be a limit as to how many characters can be strung onto a URL in this fashion; one source says it is not defined, another says 2,000 characters. A third reliable source says 4KB (4096 bytes) is the maximum form-wide total data that can be sent via the "get" method.
The web server then responds to this information by passing the data along to particular functions on an active web page. A plain HTML page will not have any way of even knowing that the data is there.
In ASP page, data sent in this manner is accessed via the request.querystring collection.
One of the downsides of using the "get" method and the querystring to pass form information along is that many times it displays information that you do not wish to be displayed to the user. For example, you may find it necessary to hand a password off from one page to another - first via an <input type="password" ...> field, and later as a <input type="hidden"> field. This isn't necessarily something you wish to display.
It's also rather unattractive and can be a bit confusing when it gets long.
And the 4 KB limit is also a consideration.
[ Top of Page ]
<form name="myForm" method="post" action="formtest.asp">
"Post" is the other way of handing off the information.
If you use method="post" the data is picked up on an ASP page with the request.form collection.
It is necessary to use method="post" if you are going to use action="MailTo:someone@somewhere.com"
Here the information is passed without being attached to the URL as is the querystring. There is theoretically no limit to the amount of data that can be passed via "post."
There may, however, be a limit on how much data an individual form element can reliably handle. The textarea, for example, has a limit of roughly 30,000 characters.
It is true that in most cases, the forms we will build will not push the envelope in terms of the size issue.
[ Top of Page ]
<form name="myForm" method="get" action="formtest.asp">
"Action" is the answer to "What's supposed to happen when the submit button gets pushed?"
If a web page is indicated, then, upon submitting the form contents, the user is also linking to that page. Whether by "get" or "post" the form data is transmitted as part of the HTTP request.
* Now the web server must do something with that data if it is to be useful. And the web page must have access to more than straight HTML to be able to use the data. More on that later.
Another action is "mailto."
For example:
<form name="myForm" method="post" action="mailto:gerholdt@fredonia.edu">
As noted earlier, this requires the "post" method. This will open the users default mail program and insert information into the body, and emails it off.
This is a quick and dirty way to get information, and is not without problems.
First, the cross-browser support is not identical. This is the ubiquitous problem when trying to do things on the client side. What browser do they use? What does the browser support? How can I work through my HTML or my Javascript to make it look or work the same - as much as possible - in the various browsers?
Some browsers have in the past supported the ability to supply a subject with the email submitted by the form. This is not true of newer browsers, and will actually make "mailto" not work in some cases. I suggest that if you've seen code for this, that you don't use it. If you use a WYSIWYG program to create HTML and it offers you this option, decline.
Second, here's an example of how the contents of the form come through in email:
selectONE=happens&selectFOUR=US&textONE=Enter+Text+Here&textTWO=You+Can%27t+Edit+This%21&textTHREE=&checkTWO=green&radio=none&hiddenONE=You+can%27t+see+me&hiddenTWO=Can%27t+see+me+either&textareaTWO=Can%27t+input+or+edit+text+here+-+just+read+and+weep.+This+textarea+content+WILL+be+submitted.%0D%0A&textareaTHREE=User+can+edit+this+text.+Helpful+for+you+to+put+instructions+which+the+user+will+then+overwrite.%0D%0A&textareaFOUR=
Needless to say, this is not a human-friendly way to gather information. Now you must either painstakingly edit this gibberish manually or get a script to fix it up for you.
NOTE: I have a NoteTab clip which will do just that. Or I used to. But I haven't needed it in a long time. I NEVER use action="mailto:xyz@xyz.edu." I suggest that you also find alternatives.
[ Top of Page ]
So what is a form good for? How can it be used if all we know is HTML and don't have any knowledge of ASP or perl/cgi?
Good question!
HTML pages can create and send forms, but they can't receive the contents of forms and use the information at all. Nor can they store the information for you or notify you that information has been stored. The browser stores them in its history, and you can use the back button to travel through the window.history node to see the contents of the form. But that only benefits the end user, not the person who put the form up on the web. And anyway, as soon as the browser is closed, the content of the form is lost.
What does it take on the Server Side to do something useful with the contents of a submitted form?
The web server needs to have the ability to recognize incoming form data and make it available to the web page. And the web page needs to have some scripting built into it that can accept and manipulate that data.
Here are some things that a server can do with the data:
- display it on a new web page
- display some of it on a new web page - for example, grab a person's name that was submitted via a form, and then embed that into some pre-existing text to personalize the web page.
- use form data to compare against other data, such as to find sports events in a database that happen on, before or after a particular date, or between two dates
- send "nicely formatted email" to a recepient
- insert the information into a database
- insert information into a "cookie"
Some of the server side technologies that are capable of this are:
- a cgi and perl combination
- php scripting
- cold fusion
- jsp (Java Server Pages)
- asp (Active Server Pages)
as well as others.
The technology that resides on our web server is ASP. ASP is a way of enhancing web pages to make them powerful and interactive. This is done by embedding script on an HTML page and changing the extension to .asp. When a request is made to the web server for a document that ends in .asp, the server looks through the file before returning it to the requesting computer. It runs any script it finds, and then fulfills the client request.
I will show you how to use ASP to send nicely formatted email using form contents in the body. You will be able to take a script I wrote home with you and put it to use.
I will demonstrate for you how an ASP page can insert form contents into a database. I'll also demonstrate how another web page can come along and read that data right back out. I will not provide a take-home script for this, however. While it isn't quite rocket science, it certainly isn't plug and play. There are lots of pieces to the puzzle. I will show you an example of one such application which is currently in use on our campus. Perhaps you have used it yourself.
I will also demonstrate how you can pull some of the contents of a submitted form onto the next web page to personalize the page for the user.
[ Top of Page ]
<%
strBody = ""
FOR EACH item in request.form
strBody = strBody & item & vbcrlf & request(item) & vbcrlf & vbcrlf
NEXT
Set objMail = Server.CreateObject("CDONTS.NewMail")
objMail.From="JJDOE@fredonia.edu"
objMail.To="gerholdt@fredonia.edu"
objMail.Subject="Form to Mail Server Side"
objMail.Body=strBody
objMail.importance=1
objMail.Send
Set objMail = nothing
response.write "<h3 class=""CELLHEAD"">Message Sent!</h3>"
%>
[ Top of Page ]
You don't really need to remember that CDONTS stands for "Collaboration Data Objects for NT Server." Nor do you need to know this capability is part of the SMTP service of NT Service Pack 4.
So we can ignore that.
I won't try to teach you ASP but this script is short enough that I can explain it line by line.
Here goes!
I.
<% - in a document that ends in .asp, this indicates the beginning of a block of asp code. The server will consider anything not inside of <% .......%> to be HTML/text and just display it.
II.
strBody = ""
This just creates a variable. A variable is like a bag. We just created an empty bag. Generally bags are most useful when you put something into them. We're going to do that, too.
III.
FOR EACH ...
This creates what we call a "For Loop." A For Loop starts with FOR and ends with NEXT. It keeps going until there's no more to do.
IV.
FOR EACH item in request.form
This is pretty easy. The previous web page had a form on it; the user clicked "submit"; the action was "post" - and so the request comes to the web server. The web server makes the contents of the form available to the current web page via the 'form' collection. A plain jane HTML page wouldn't know what to do with the form collection. But we're creating an ASP page!
How many items are in that collection? We don't have to know for this script; we don't even have to know the names of the items. This script will give us the name and value of each item in the form collection until there aren't any more left.
That's why this is a script you can take and use with any form which is sent by means of the "post" method.
(HINT: You can convert this to "get" method by changing "request.form" to "request.querystring.")
V.
strBody = strBody & item & vbcrlf & request(item) & vbcrlf & vbcrlf
This looks more confusing than it is. Let's look at the loop as a whole:
FOR EACH item in request.form
strBody = strBody & item & vbcrlf & request(item) & vbcrlf & vbcrlf
NEXT
We start with an empty bag called strBody. We're going to go through all the items the form sent to the web server and which the web server in turn made available to the web page. For each one, we're going to put something into the bag. See the equal sign? Everything to the right of that equal sign is going to get put into the empty bag.
(Well, the metaphor breaks down a little. What we're really doing is changing the VALUE of strBody. It never was an empty bag, really. It was the emptiness inside the bag, and there never was a bag. [If you find this concept troubling, you may be happy to know that Christine Davis Mantai has been studying Zen.] Now we are going to give strBody content; but it isn't going to HOLD the content as much as actually BE the content.)
Let's place ourselves at the first time through the FOR loop. strBody has no content or value.
Now we give it some.
strBody equals strBody well, that doesn't change it. It still has no content. Just ask Aristotle.
& - the ampersand - this is how we put different things together in vbScript.
[Oh, sorry - yeah, this is Visual Basic Script. ASP isn't a scripting language. It's an environment. We could be doing this in Javascript or JScript or perlscript - and still be using ASP. But I use VBScript.]
item - aha! No longer is strBody empty! It now has the name of one of the form elements in it!
vbcrlf - this is just a visual-basic-carriage-return/line-feed
Now strBody has the name of a form element and a line feed. It's growing.
& request(item) - this means the VALUE which the user selected for the item. For example, if we're talking about the select form named sports, and the user chose hockey, strBody now looks like this if we print it out:
Sports
Hockey
item, linefeed, item value
And now you can see for yourself that we just tack on two more line feeds and go through the loop again. Each time through the loop, the content of strBody changes - it equals what it already equaled plus the next item/linefeed/itemvalue/linefeed/linefeed
And when we've iterated through all the items in the form, the FOR LOOP when it gets to 'NEXT' says "There ain't no next" and the script moves down to the next line.
[ Top of Page ]
And after the FOR LOOP, the next line tells the server to create an object called CDONTS.NewMail.
The server knows about a file called cdonts.dll and knows it has to look there to perform this task.
Once again, we start with a variable - an empty bag. No, the emptiness inside the non-existent bag. And we set it to equal the object the server creates - a New Mail object.
You don't have to understand much about this - just that this is what's happening. It's one of the kinds of things that HTML isn't capable of that makes server side operations so important.
This New Mail object has some properties which are not set. The rest of the script sets them. I don't think much explanation is necessary.
However, I will give you a word of caution: This isn't like HTML where you can make an error and still get halfway acceptable results. You will want to edit this code to include a different email address - but everything must be "Just So." One little error and nothing works at all.
Especially please notice that the From, To and Subject fields have quotations around them. This is because they are "strings" - in other words, straight text. They aren't variables - they are to be taken literally. Compare this to the Body where our old friend strBody sits. This is a variable, and we know what it includes. Lots of information is packed into that variable. If we put quotations around strBody, the body of any email would include those seven letters - s,t,r,B,o,d,y. Of course, we aren't interested in strBody as a string - we're interested in the value it holds as a variable.
From, To, Subject, Body, Importance - these are "properties" of the CDONTS.NewMail object.
Send is a "method." It's an action instead of a noun/adjective. This is what sends the mail.
Finally, we "throw" the variable objMail away - we set it equal to nothing. This is just to explicitly release server resources (in the form of RAM the computer used to hold this value and this variable together).
Set objMail = Server.CreateObject("CDONTS.NewMail")
objMail.From="JJDOE@fredonia.edu"
objMail.To="gerholdt@fredonia.edu"
objMail.Subject="Form to Mail Server Side"
objMail.Body=strBody
objMail.importance=1
objMail.Send
Set objMail = nothing
NOW - I'd like to give you something else to consider. What if one of the input fields in the form contained the user's email address? What if you wanted to use that as the return address instead of this fake one? How could you do that?
Well, you know what the name of the element was in the form. You can get the value of that input by using the request.form collection and specifying that element. Let's create an empty variable called "strEmail" and put the value of the user input into it. For example, on our form we asked the user to put her email address in a text input element that we called "textTHREE." (In real life we might call it "email" - something more meaningful.) So:
strEmail = request.form("textTHREE")
objMail.From=strEmail
Compare this From with the one above. What's the difference? Quotation marks, right. Why aren't we using them here? Because this email isn't from "strEmail" = it's from the user's email address. We don't want strEmail to be considered a string literal, but rather a content holder. So no quotations.
In order to be able to do this kind of thing, you have to know the name of the field. In our earlier FOR LOOP which is a 'one size fits all' script, you don't have to know any element names. You just get them all. But you then give up control of how the elements are ordered - you take them as they come. Clearly you can do things more powerfully and with more control. But that takes more time and knowledge.
[ Top of Page ]
Take a normal web page that you have already written.
Put the CDONTS script I've given you on it so the web page will now send email.
Make sure to change the page from "page.htm" to "page.asp" so the server will know it has work to do before sending the web page out.
Now you can grab some of the fields the user has input and use their values on your page to personalize it. Remember "textONE?" That was the user's name. You can include this in other HTML text by using this ASP code:
<%
response.write request.form("textONE")
%>
Example:
Here's some HTML and ASP code mixed together:
<P> We have a special prize for:</P>
<h3>
<%
response.write request.form("textONE")
%>
"response.write" is just the command you give the server to tell it to write text as part of its response to the request. (What request? The request from the client computer for this particular web page; the request that included the form input. ASP has (among others) two important collections: request and response.)
Here's a nice little shorthand way of writing the request.write that is perfect for small insertions:
<%=request.form("textONE")%>
Nice, huh?
<P><%=request.form("textONE")%>, we think you will really like it at our school.</P>
This will "response.write" the user's name from the request.form "textONE" field.
Since you are going to build the forms, you will know the names of the elements, and so you will find it very easy to use some of the user input on your web page in this way. Simple, powerful and personal!
[ Top of Page ]
Sometimes it is important to make sure that a user enters something in a form element. We can do this on the server side with Active Server Page technology easily. However, that's not the best way. Why send a defective submission to the web server, only to have the web server reject it and send a request back to the user that the form be completed properly - when this can be done on the client side with no network traffic at all?
On the client side, what we'll use is Javascript and the Document Object Model (DOM). As you know already, the DOM is just a schematic model of a web page. We can apply that schema to our own web page - the one with the form on it - to identify a form element. Then we can pass that element to a javascript function. I'm going to show you a very simple function that tests only for the existence of an entry. It isn't a very complex function - it won't make sure that the entry is the correct kind of entry. It will be satisfied with the existence of a single character.
We're going to test for the entry of the email field in the element that we can locate through the Document Object Model as:
window.document.formExamples.textTHREE
We don't need to use "window" - I just put it there to be complete. Window is at the top of everything, and so is always assumed.
document.formExamples.textTHREE
We do need to start with "document." It is one step below Window, but so are some other objects which are peer objects to document. Here are some of them:
- location
- frames
- history
- navigator
- event
- screen
- document
So if we just tried to start with "formExamples" the function wouldn't know where to look - under the location object, or history, or document.
"formExamples", you will remember, is the name of the form we've been practicing with. And "textTHREE" is the third example of <input type="text">.
We don't absolutely have to use the names of these objects. We could refer to it as
document.form[0].element[6] (if I counted right: the first form, the seventh element). But it's much easier to use names.
Along with the DOM which identifies the element we want to test, we also hook into an "event." There are a number of events that can take place on a web page. onMouseOver is one you have seen in use - when you move your mouse pointer over an image and it changes to let you know it is an active link. That is the result of a javascript function that says "exchange image a for image b" and it is triggered by an onMouseOver event. Another event is onLoad - you can call a javascript function by calling it as the body of the document loads. onClick, onBlur, onFocus and onSubmit are other events.
We can use any of these events to trigger a call to a Javascript function, and there are many, many things that a javascript function can do. This is how you build DHTML or Dynamic HTML pages.
In our example, we will use the onSubmit event, and it goes in the <form ...> tag. Here's what our form tag will look like:
<form action="formtest.asp" method="post" name="formExamples" onSubmit="chekField()";>
We're building into our form a new dimension. When it is submitted, it will call a javascript function which is called "chekField." the function is probably written up in the head of the document, though it may also be in an external file which is 'included' in our web page.
[ Top of Page ]
Here's the javascript function that checks to make sure that textTHREE has at least something in it:
function chekField()
{
with ( formExamples)
{
if (textTHREE.value.length < 1)
{ alert('Please enter your email address!');
event.returnValue=false;
document.formExamples.textTHREE.focus();
return false; }
}
}
We are using "form level" validation. That means that this function is called when the form is submitted. We could have used onBlur or onFocus to call a function when the user moves from one element to the next, and checked each element individually. That can get a bit complex; it is simpler to do things at the form level.
I'm not going to try to explain every bit of this javascript function to you as I did the VBScript for CDONTS. I'll just point out that the function is CONDITIONAL. It starts out with "IF." This means it is testing for a condition. Here it is:
if (textTHREE.value.length < 1)
If the length of the user input for textTHREE is less than 1 character, then the rest of the function will be completed. If there is a character in textTHREE, the condition is not fulfilled and the function ends.
{ alert('Please enter your email address!');
This tells the function to make a pop-up message box to the user.
event.returnValue=false;
Don't continue to do what the EVENT that triggered this function was about to do.
document.formExamples.textTHREE.focus();
Put the focus here. In other words, the element textTHREE will be active and the cursor will be in it ready for text input.
return false; }
don't go on to other parts of the function if there are any; just stop here.
This is good because instead of getting a number of message boxes all one after the other, the user gets one at a time, if you are performing validation on more than one element.
[ Top of Page ]
HTML forms are a useful tool for gathering information from users. There are many ways we can manipulate and use the information from a form; we've barely skimmed the surface.
HTML can create a form, but it is helpless to check user input or to put any of that input to good use. For this we need to use client-side technology such as Javascript and the Document Object Model or server-side technology such as Active Server Pages.
Therefore we must go beyond HTML itself and plunge into the realm of programming if we are to get any benefit from HTML forms.
[ Top of Page ]