Forms
This reading introduces forms. Forms are an important part of any website in which the user interacts, such as supplying information or making choices (e.g. menu options).
We will not be covering all aspects of HTML forms. We'll focus on just a handful that are useful in this course. If you want to learn more, there's a list of additional topics at the end of the reading, and you're welcome to ask. The most important kinds of inputs we'll learn are:
- text inputs (a single line of text, such as someone's name or favorite color)
- textareas (longer blocks of text, such as a restaurant review or a blog entry)
- menus (one of a set of choices, pre-defined by the form's author, such as "small/medium/large")
- buttons, which don't so much give input as trigger behavior.
The FORM tag¶
HTML has a dedicated tag, form
, that is used as a
container for all the form-related inputs. The data from those inputs
might be sent as a collection to a web server. In this course, we
won't always be submitting the form to a web server. We will
definitely use the form
tag in CoffeeRun.
The attribute method
of the element allows the form to
either request data from the server (method="GET"
), or
send data to the server (method="POST"
). However, in
order for either of these operations to happen, the server needs to
have some dedicated programs (also known as scripts) that can deal
with the form data. At this point, we will not talk about how this
happens (we'll postpone this discussion for later in the semester),
and only concentrate on the HTML elements that are contained inside
the form.
Let's see an example form, and then we'll look at the code that creates it. You can try it if you'd like; it just echoes the data back to you.
Here's the code that creates that form:
<form class="example"
id="pizza-form"
method="GET"
action="https://cs.wellesley.edu/~cs304flask/cgi-bin/dump.cgi">
<p><label>Customer name: <input name="customer"></label></p>
<p><label>Telephone: <input type=tel name="phone"></label></p>
<p><label>E-mail address: <input type=email name="addr"></label></p>
<p><label>Size:
<select name="size">
<option value="">choose size</option>
<option value="small">small (10-inch)</option>
<option value="medium">medium (12-inch)</option>
<option value="large">large (14-inch)</option>
</select>
</label></p>
<p><label>Preferred delivery time:
<input name="due" type=time min="11:00" max="21:00" step="900">
</label></p>
<p><label>Delivery instructions:
<textarea rows="3" cols="30" name="instructions"></textarea>
</label></p>
<p><button type="submit">Submit order</button></p>
</form>
As you can see, there's an outer FORM
element that wraps
up the form inputs. There are input elements that correspond to
different places where the user can enter information. Most of the
inputs use the INPUT
tag, but some use tags like
SELECT
(for a drop-down menu) and TEXTAREA
(for larger blocks of text).
The umbrella term for inputs, select
, textarea
and such is
control. (Personally, I don't think that's a very intuitive
word, so I will usually call them inputs and hope you understand
that select
and textarea
are also inputs. See native form
controls.)
Finally, there's a submit
button at the end. Clicking
this button sends the form data to the web server where it is
processed by the script mentioned in the action
attribute of the
form
tag. In this case, the script is dump.cgi
, which is a script
I wrote, running on the CS server, that just reflects the data back to
us, showing that it was successfully received. (So it's useful for
debugging but little else.)
Name and Value¶
When the form gets submitted, the form data gets sent to the server. It gets sent as a set of name/value pairs, which we can think of as like a little table. Here's some data as if from our pizza form:
input name | input value |
---|---|
customer | Hermione |
phone | 555-8888 |
addr | hgranger@hogwarts.ac.uk |
size | large |
due | 18:00 |
instructions | please deliver by owl |
So this tells us that one of the things you will do as the author of
the form is to decide what the names are for the data it
collects. In other words, you are responsible for the left column
(customer
, etc) and the user is responsible for the right
column ("Hermione", etc).
Form Fields¶
Let's look at the different input elements (again, also known as
controls). The following table shows the HTML syntax for
different form elements. As you will notice, the most common element
is <input>
, which, based on the value for its
attribute type
will display a different kind of
input. Play with the rendered version of a tag in every row in the
table.
Syntax note: as a general rule in HTML, if the value of an attribute is "solid" (letters and numbers without spaces or other confusing characters), the quotation marks are not necessary. So the following are equivalent:
<input type=text name=office>
<input type="text" name="office">
But it never hurts to put the quotation marks in.
Here are some inputs:
Control HTML | Rendered Control | More Info |
---|---|---|
text: <input type="text"> |
info | |
number: <input type="number" min="1" max="120"> |
info | |
range: <input type="range" min="100" max="200"> |
info | |
date: <input type="date"> |
info | |
time: <input type="time"> |
info | |
<button type="button">Click me</button> |
info | |
long text: <textarea rows="2" cols="10"> </textarea> |
info | |
menu: <select><option>Black <option>White </select> |
info |
Buttons are a little odd in this context, since they don't accept data input, but instead they trigger action. We'll discuss more in the section on buttons.
For more information on the form
elements and all its
fields, consult the W3Schools page on
forms.
Let's look at some of the more important controls, and then other aspects of forms.
The INPUT Tag¶
The input
tag is fairly straightforward, but you can
specify the type of input you are looking for by using the
TYPE
attribute. It has many more types, which we are not
listing here; consult W3Schools page for
input to see the complete list. Here are a few of the most common
ones:
text
: allows the user to type in a word or phrasepassword
: allows the user to type in a word or phrase, but its value isn't echoed, so no one can look over their shoulder and see it.email
: like a text type, but should look like an email address. New with HTML5.date
: for entering dates. New with HTML5.time
: for entering times. New with HTML5.
Some of these types (such as time, date, number, range, etc.) were
introduced in HTML5, which means that old browsers might not support
them. But HTML5 has been around for a while, so you're pretty safe.
For maximum portability, you should stick to
type=text
. However, sliders like we get with
type=range
are fun, and we'll use them sometimes.
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:
<form action="">
<label>Drink
<select name="beverage">
<option value="">choose one</option>
<option value="Coke">Coca-Cola</option>
<option value="Pepsi">Pepsi-Cola</option>
<option>Beer</option>
<option>Wine</option>
</select>
</label>
</form>
(The closing </option>
tag is not required, like a closing </p>
tag or </li>
tag, but it's best to use it.) Any option can have a
separate "value" attribute; if none is specified, the value is the
option itself. So, the option for "Wine" is "Wine". Text between the
begin/end option tags is what the user sees. The "value" is what is
sent to the server. So the user sees "Coca-Cola" but (if that option
is chosen), the server will get the value "Coke".
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 validating the form, which we'll talk about later.
The TEXTAREA input¶
If you want to allow your user to type in a long response, say for a
blog post, restaurant review, comment or whatever, 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:
<textarea name="thoughts" rows="3" cols="40"></textarea>
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.
Note that a default value is different from a placeholder. A placeholder is example text that appears in the box but will not be sent to the server when the form is submitted. Placeholders don't count as values. Default text is an initial value and will be sent to the server if the form is submitted.
Labels¶
A form consisting of a bunch of bare boxes would be useless, so how is
the user to know what input box means what? It could be done just by
putting text in the form, with paragraph tags and such, but that
doesn't work so well for screen readers and other user agents. It is
more accessible to associate a bit of text with an input by using
the label
tag.
There are two ways the label can be used. One option is to wrap both the input and the text in the label. I call this the structural way. Here are two examples:
<label>
Given Name
<input type="text" name="givenname">
</label>
<label>
Family Name
<input type="text" name="familyname">
</label>
The other way is to give the input an ID and reference that ID in a
for
attribute of the label. The <label>
tag still wraps
the textual label, but it no longer wraps the control/input. I call
this the id way. Here are two examples:
<label for="givenname">Given Name</label>
<input type="text" name="givenname" id="givenname">
<label for="familyname">Family Name</label>
<input type="text" name="familyname" id="familyname">
In the id
examples above, I made the name
be the same as the id
;
that's not necessary. It was just to save me the mental burden of
coming up with a good synonym. You're welcome to do the same. But note
that an id
is not the same thing as a name
. The name/value pairs
are sent to the server when the form is submitted. The ID is used to
identify this particular element, just like we always have. In this
case, both attributes are necessary.
The structural version is simpler, easier and works in almost every situation. I suggest you use the structural approach unless you are using a page layout where the structural approach doesn't work.
(The id version is necessary in rare cases where the structure of the HTML doesn't allow the input to be a child of the label, as with a table. We haven't learned about tables yet, but imagine the label being in one column and the input in another; it's hard to wrap the label around the input in that case.)
Placeholders¶
Another useful attribute for input
controls is
placeholder
, which can be used to provide a hint or
example of the kind of value that should go in a field. For example,
this HTML
<label>full name <input type="text" placeholder="Hermione Granger"></label>
will be rendered like this:
But, remember that the placeholder text is not a value, and won't be sent to the server.
Radio Buttons¶
Radio buttons are used for a set of mutually exclusive options, like the buttons on a car radio, to choose the station. The HTML is more complicated than our earlier inputs, but radio buttons are useful.
Here's an example of some radio buttons:
Try choosing different buttons and see how the selection changes.
Here's the HTML for it:
<form>
<label><input type="radio" name="station" value="wbur">WBUR 90.9 FM </label>
<label><input type="radio" name="station" value="wgbh">WGBH 89.7 FM </label>
<label><input type="radio" name="station" value="wzly">WZLY 91.5 FM </label>
</form>
Notice that all the inputs have the same name
attribute value,
namely station
. The fact that they have the same name tells the
browser that they form a set of mutually exclusive options. Here's
another example, now with two groups, both with yes/no answers:
Again, click the buttons to see how there are two mutually exclusive groups here. The HTML is as follows:
<form>
<p>do you like cats?
<label><input type="radio" name="cats" value="yes"> yes</label>
<label><input type="radio" name="cats" value="no"> no</label>
</p>
<p>do you like dogs?
<label><input type="radio" name="dogs" value="yes"> yes</label>
<label><input type="radio" name="dogs" value="no"> no</label>
</p>
</form>
A few more things to note:
- In the first example, we see that the text that the user sees, such as "WZLY 91.5 FM" is not the same as the value ("wzly"); it's the value that is sent to the server.
- Notice that we can click on the label text to select the button; we
don't have to click exactly on the little circle widget. That's a
feature of the
label
, something that helps everyone, not just those using screen readers.
Buttons¶
Radio buttons allow the user to choose among different values. Let's turn to some other kinds of buttons.
There's a button that is used to submit the form when the user wants to. Traditionally, that was done by the following kind of button:
<input type="submit" value="submit form">
The value
is just the text on the button. It can be any text you
want, such as "order this item" or "enroll in this course".
There are also buttons that are used solely to trigger some JavaScript, so without the JavaScript, they do nothing at all. Those are done like this:
<input type="button" value="do something">
We could then add a click
handler to the button to trigger some
JavaScript. We've seen that several times this semester.
An alternatvie is the <button>
tag, which wraps around something,
rather than being an atomic element like the buttons above. In that
way, it works more like the clickable <a>
tag. So we can do:
<button><img src="rock.jpg" alt="rock"></button>
The <button>
tag was added to the HTML language so that we could add
clickability to any element by wrapping it in a button. One nice
feature of using <button>
rather than <a>
is that with <button>
there's no default behavior that we have to prevent, so no need for
event.preventDefault
.
Testing Accessibility¶
Accessibility is a big complex subject, and professional websites have trained developers, automated tools, and human testers to ensure accessibility. All that is outside the scope of this course, but I will introduce three important tools and require you to use them.
All HTML must be valid, which means it satisfies the structural rules set out by the WWW consortium (W3C). Valid HTML is important because screen readers and such can do a better job understanding the structure of the page if it follows the rules. Most browsers are much more forgiving, so don't assume that if it looks good in a browser that it's good.
You can validate your HTML using this website from the W3C: https://validator.nu/. We've done this before in this course.
All CSS (see below) must be valid, for similar reasons as the HTML.
The W3C also provides a CSS validator that works the same way as the HTML validator: https://jigsaw.w3.org/css-validator. Again, we've used this before.
Check the page for common accessibility issues with the WAVE, the Web Accessibility Evaluation tool, https://wave.webaim.org/. It's important to note that getting no errors from the WAVE tool doesn't mean your site is accessible — only a person can decide that — but it's a useful tool nevertheless. Not passing the WAVE test is certainly undesirable.
Like the earlier validators, WAVE can retrieve a publicly hosted page given its URL and evaluate it. It doesn't have a mode where you can copy/paste your code, but there are two browser plugins that will evaluate the page in your browser. In less than 1 minute, I installed the Firefox plug-in, visited a page, and evaluated it.
Forms and JS¶
The next topic is how to process the form data in the browser, using JavaScript. I've broken that out into a separate reading about forms and js.
Topics we didn't cover¶
- fieldset and legend
- checkboxes
- size of inputs
- validation
- others??