Forms

Revised, Fall 2013, by Scott.

These notes cover how to create forms and use them to email data to a specified email address. They also describe using jQuery and plugins to operate on the form, including validation.

Forms

So far in our web pages, we've just been giving the user information. Now, we want to get some from the user. We'll do this by having them fill out a form, just like the ones you did on the first day of cs110 lecture (and whenever you buy something online). Here are some examples; look at the source code to see how they are done.

You can figure out a lot just by looking at the code and making reasonable guesses, but we'll walk through the details in lecture to be sure.

The FORM Tag

The main tag is the FORM tag. Like TABLE, UL and a few others, the FORM tag is just a container; it doesn't do much by itself.

... inputs go here ...

Don't worry about the method attribute and (empty) action attribute; we'll get to that soon enough, when we talk about CGI scripts.

The body of the form can contain one or more inputs, (in addition to any other HTML, JavaScript code, text, and images). Many of these use the INPUT tag, but there are tags called SELECT and TEXTAREA that also provide input.

We will also name all of our inputs. This is useful when the form data is processed on a server, because only named data is submitted. For example, we will later see how to the form data can be emailed somewhere, but only named fields will be in the email.

The INPUT Tag

The INPUT tags have several different types, which you specify using the TYPE attribute. Here are some of the types:

Examples:

You can see more examples by looking at the source for the example form. If you submit this form, the data is "echoed" back to you.

The SELECT input

To specify a menu, from which the user can choose only one option, you use the SELECT tag inside the form. You specify the NAME of the input in the SELECT tag, and each menu item is specified using the OPTION tag. Here's an example:

Drink:

(The closing </option> tag is optional, like a closing </p> tag or </li> tag.) Any option can have a separate "value" attribute; if none is specified, the value is the option itself.

Specifying a non-option as the first item in the list helps to tell whether someone has actually made a choice or just overlooked this menu. Making the non-option have a value of the empty string helps with validation.

The email message will display whichever option the person chose.

The TEXTAREA input

If you want to allow your user to type in a long response, you should define a textarea inside your form. This tag has attributes called ROWS and COLS that let you specify the size of the area.

<textarea name="thoughts" rows="3" cols="40">
A chicken is an egg's way of making another egg
</textarea>

The default value is the region between the beginning and ending tag. Typically, you want the default value to be empty, so put the tags right next to each other, as in this example here:


Don't let even a single space creep in, or the initial value will be a string of one space, and not the empty string. That will affect any code that cares about the default or original value, such as certain kinds of validation

SUBMIT, RESET and BUTTON elements

Here are some more INPUT tag types. The user doesn't use them to enter any data, but they otherwise share the common syntax for the INPUT tag. You need not name these elements, since you typically don't need to send the value to the CGI script.

Expandable/Collapsible Forms using JavaScript

In our lecture on Events and Rollovers, we introduced the idea of manipulating elements of the document using JavaScript. Here, we will introduce a form that is mostly hidden, but can be revealed when desired.

First, try the example-form-toggled.html to see the desired behavior.

Here are the details of the code:

If we wanted to do this to multiple parts of a long, complex form (think FAFSA or IRS form 1040), we could certainly do so with some copy/paste/edit of the code, but that doesn't scale up well. Look in the additional material, below, for the code to do this.

Processing Form Data using JavaScript

jQuery makes retrieving form data pretty easy. We need to learn a new method, the val method. As you'd expect, it's used like this:

    $(selector).val();
  

The main thing is that if the selector specifies a form input, the jQuery val method gives us the value of that input. Here is an form with several different kinds of inputs:


Grade:

Your comments:

Here's the actual form, so you can change the values of inputs:


Grade:

Your comments:

Now, let's look at how to get the values of an input. The text inputs, the select menu and the textarea are all easy because there's just one element and one value to worry about. The jQuery selector can either be the ID of the element or a syntax using the TYPE and NAME of the input.

For example, the following expression evaluates to the pet's name:

$("#petname").val()

Here is an equivalent, using the name of the element:

$("[name=petname]").val()

Here are some live examples:


Form Processing Examples

Here are some examples of processing form data.

Form Validation

Soon, we'll talk about submitting the form data to a server for more elaborate processing, but before we do that, we should discuss validation. What is form validation? Essentially, it means checking to see that the form has been filled out correctly (as far as we can tell).

Form validation could be used to ensure that someone hasn't overlooked a text input, menu or radio button group, and can check that, for example, the zip code is 5 digits (or 9) and that a telephone number is 10 digits, and that an email address looks like an email address.

Form validation can actually cancel the submission of the form, so that the data never leaves browser. The reason we validate forms is twofold: to give the user immediate feedback that they've missed something, instead of waiting for the server to respond, and to protect the server from having to handle all those invalid forms. Of course, a determined nefarious person can simply disable our form validation JavaScript and hammer our server with invalid forms, but that's rare. The vast majority of invalid forms are just human error.

Obviously, the browser can't tell whether you entered your correct phone number, but it can check that you typed the right number of digits (and only digits). Similarly, it can't check that your spelled your name correctly (and whether your name really is Mickey Mouse), but it can check that you didn't leave that input blank.

With HTML5 and modern web browsers, form validation has gotten a lot easier. In the past, web developers would write JavaScript code that would look at the values in the form to check for bogus values. They wrote libraries and jQuery plug-ins to make the job easier for others. Indeed, there is a jQuery plug-in by Jörn Zaefferer called validation that does a good job and is well described in our book, JavaScript & jQuery: The Missing Manual, pages 278-300. Please read that, and the on-line documentation linked above, for full details.

However, the vast majority of form validation can be done with a few simple things:

Here's a demonstration. (Note that I didn't re-use the input names from the earlier example because the JavaScript code above referred to the inputs by name, and so we need to make those unique. I could also have used a nested selector and given each form its own ID.)

Username:

Email address:

Birthday:

Here's the actual form, so you can change the values of inputs:

Username:

Email address:

Birthday:

Try to submit an incomplete form!

CGI

What happens when the form is submitted is determined by the CGI (Common Gateway Interface) protocol, which sets the rules by which form data is sent to servers and processed by programs, usually called CGI scripts. A CGI script can do anything it wants: it can send email, interact with a database, create a document, contact other users, or whatever. The electronic commerce web sites that you know, like amazon.com, all work via CGI scripts.

A form can specify what script is to process the form data (via the ACTION attribute), and how it should get the data (via the METHOD attribute). The example that we will use in this class is a CGI script that emails the data to some recipient. When you want the data to be sent to someone with the help of Puma (acting as a mail server ) you can write:

<form name = "my_data"
      method="post"
      action="/cgi-bin/eform.cgi">
</form>

The value of the ACTION attribute is a CGI script that will package up all the form information and email it someplace. There are two methods, GET and POST. The GET method collects all the form inputs in the URL. (You've probably seen this sort of link from sites like Google Maps .) On the other hand, the POST method collects all the form inputs into something called “standard input.” Which method you use is determined by the author of the script. We will always use the POST method in this class.

Echoing the Data

The first CGI script we'll consider is not particularly useful by itself, but is very helpful for debugging forms, as we saw with the examples at the beginning of the notes. It just echoes the data back to the browser, in a nicely formatted way. It also tells you a few other things it knows, such as the IP address you're browsing from and the time you submitted the form. The script is called dump.cgi and it lives in /cgi-bin/dump.cgi .

Exercise 1

Emailing the form data from Puma

Since CGI scripts can do such different things, each one can have its own behavior and rules. The one we will use in this course is called eform.cgi and it is designed to email the information on the form to someone. It can do this in one of two ways:

You already know how do to the first case. There are two steps:

  1. Make the FORM tag look like this:
    <form name="mailform"
          method="post"
          action="/cgi-bin/eform.cgi">
    </form>
    
  2. make sure there is a recipient for the email message. This is usually done via a hidden input:
    <input type="hidden" 
           name="_recipient" 
           value="me@wellesley.edu">
    

    (The required input _recipient begins with an underscore so it is unlikely to conflict with a name you would like to use for something else in your page; the script will complain if that input is missing.) That's all. The downside of this simple approach is that the resulting email message isn't pretty. It is unformatted, a long string of form contents.

To have a formatted email message is an optional advanced technique for the interested reader. Follow the link to find out how.

Wrong Server

To avoid abuse by spammers, eform.cgi requires that the form be on the server. If your form is not on the server, you will get an error message saying

Wrong Server

This error commonly occurs when you are testing your form on your local desktop machine, so that the URL for the form is file:///.... Sorry, but that won't work.

Exercise 2

Other CGI Scripts

Note that the eform.cgi script lives on the CS server. If you decide to use it in your projects (which you're welcome to do), you will eventually have to face the problem of what to do when your site is delivered to your client. You are welcome to copy our eform.cgi code to the web hosting service, but they may not support scripts (just passive web pages). If that's the case, you'll have to find some kind of equivalent that they do support (they typically provide a script equivalent to eform.cgi). You can search their support pages or ask their tech support for more info.

You can still use eform.cgi in your project without necessarily having solved this problem of an equivalent on the client's web hosting service. You might be able to solve it later, or omit that functionality if the web hosting service isn't up to the task.

Solutions to Exercises

Summary

In this lecture, we learned

Optional reading: Meyers Ch. 14-15, Thau Chapter 7.

Additional Material

The following sections are not required, but are included for the interested student.

Radio Buttons and Checkboxes

Each radio button input is part of a group of mutually exclusive buttons: if you click on one button, it is selected and whatever used to be selected is de-selected. This is more intuitive to try than it is to describe:

favorite fruitfavorite tech company
apple Apple
banana Google
orange Microsoft

The crucial question is, how does the browser know that when you click on the first “apple,” it should deselect “banana” and “orange,” but not “Apple,” “Google,” or “Microsoft”? The browser is not able to get any clues from the layout of your buttons: you might just as easily have arranged the table horizontally instead of vertically. (Look at the source to see how ugly that might be.)

The rule is that the browser deselects all other inputs that have the same name as the input you selected. Thus, the name of a radio button is crucial: it defines the group of mutually exclusive options.

Although checkboxes are not mutually exclusive the way that radio buttons are, they also form groups based on the name of the input. This is reflected in the email that you are sent: checked boxes are grouped together as one set of responses.

Structuring Forms

For clarity and accessibility, it's a good idea to structure a form: grouping related inputs and labeling each input. At the top of these notes, we saw an example-using-fieldset.html.

We'll need to learn the following HTML tags:

It's also useful to know about the accesskey attribute, which provides a shortcut to put a particular input in focus (to type a value) or to choose a value (as with a radio button or checkbox). This is very convenient for touch-typists and those who have trouble with a mouse.

Using a modern Firefox, Chrome or Safari on a Mac, hold down the control and option keys and type the access key to use the feature. Try it on our example-using-fieldset.html, where the accesskey for each input is given in parens in the label.

Toggling Multiple Areas of a Form

To be written. See the somewhat more complex code in example-using-fieldset-and-jq.html, which you're welcome to explore on your own (or ask us during office hours).

Getting Values From Radio Buttons and Checkboxes

As we mentioned, radio buttons and checkboxes are trickier. Let's start with radio buttons, like our grades radio button set above. Here, we can't use an ID, because there are six buttons, and each would have to have its own ID. We can use just the name, since they all share a name. We can't use val just by itself, though, because all six of them have a different value. However, jQuery provides us a pseudo-class called :checked that will narrow the selection to just the checked button.

Thus, the following expression will evaluate to the checked grade:

$("input[name=grade]:checked").val()

Try it:


Checkboxes are even trickier, because more than one of them might be checked, so there's more than one value. If you just want the first checked value, jQuery makes that easy, because the val method returns the value of the first selected element.

alert($("input[name=spells]:checked").val());

Thus, the following expression will evaluate to the first checked spell:

$("input[name=spells]:checked").val()

However, if you want all the checked values, the val method needs to return a set of values. It does that with arrays, which we've read a tiny amount about, and which we'll learn more about at later time.

Here's an example form, using checkboxes: