So far, everything you’ve learned about webpages and HTML has taught you how to build a one-way street. That is, you can post information to a webpage, but the website visitors have no way of interacting with you. That’s where web forms come in.
Web forms are the primary way users interact with websites. From contact forms to Google’s search box, forms drive engagement and make the web a more interactive place.
Forms allow users to submit information to your website. You then have the option to store the data or otherwise do something with it. Some examples of popular web forms:
Contact forms
Comments
Forums
Login boxes
Post boxes (on social media websites)
Search boxes
Checkout pages, Add To Cart buttons, and payment submissions for online stores
Chatbots
Popup opt-in boxes
You’ve no doubt seen lots of forms (FIGURES 9.1, 9.2, and 9.3).
There are several steps to building and processing a web form (FIGURE 9.4):
Build the form using HTML.
Validate the form to make sure all data is submitted properly.
Submit and process the form.
Processing can happen in several ways. You could simply email the contents of the form somewhere, you could store it in a database, you could use it to change your site in real time, and much more.
Display confirmation to the user.
Keep this in mind as you read this chapter, though: you’re learning how to build the form in HTML, and you’re using HTML elements to perform basic validation of the input data.
But with regard to submitting the data, you can’t do as much with just HTML. Submission often requires the use of another programming language, which goes beyond the scope of this book. That said, you will learn basic form processing to email the form contents. In Chapter 10, you’ll even learn a simple technique for storing the data.
Every form is wrapped in a <form>
element, which consists of the opening <form>
tag and the closing </form>
tag.
The bulk of the form itself is made up of fields that can accept data from users. Most of these elements are created with <input>
tags, though there are others you’ll also learn about.
<form>
ElementEvery form needs an opening <form>
tag and a closing </form>
tag, which together define a form
element. The form
element requires an action
attribute, and it should have method
and name
attributes as well:
<form name="search-form"
→ method="GET" action="process.php">
The name
attribute is a simple way to uniquely identify the form (each form should have a unique name). Webpages can contain more than one form, and the name
attribute allows you to easily reference the form in both CSS and JavaScript.
The method
attribute determines how the form data should be sent, and can take one of two values.
GET
is the default value. This method transmits data from one page to another in a URL as name-value pairs (FIGURE 9.5).
Attributes are a good example of name-value pairs. They have a name (like the role
attribute) and a value (like “main
”). In a URL, name-value pairs appear in this format: role=main
.
When a user fills out your form and clicks Submit, the browser takes all the data from the form and then inserts it into the URL. In the above example, the URL would look something like this: process.php?name_of_field=value_the_user_input
.
The other method
value is POST
. In this method, data is transmitted in the HTTP request and is not shown in the URL. The data is sent, in this instance, to process.php
via the server.
The action
attribute tells the browser where to send the form information. It’s what does the form processing, whether that’s emailing its contents or storing it in a database. If you do not include the action
attribute, modern browsers will assume the current page will also process the form.
There are several form fields that you can define in HTML, and each allows the user to interact with the form in a different way.
The most common tag you’ll find between the opening and closing <form>
tags is <input>
. This element creates a field into which users can insert data. It looks something like this:
<input type="text" name="search"
→ value="" />
Let’s take each attribute one by one.
The type
attribute determines the kind of data a user can input. While text
is the most common (and the default when the type
attribute is not defined), there are lots of values the type
attribute can have. You’ll see most of them throughout this chapter.
The name
attribute assigns a name to the input field. Remember those name-value pairs from earlier? The name is derived from the name
attribute. It should be unique to prevent overriding data.
The value part of the name-value pairs is derived from the value
attribute. Notice that the value
attribute in the above example is blank. You can add one, but whatever the user inputs will overwrite it (FIGURE 9.6).
With some form fields—namely, those that take on the appearance of a textbox (a single-line white field with gray border, which accepts a limited amount of text)—there is another attribute. Instead of setting the value
attribute, you can use the placeholder
attribute. This adds grayed-out text to the field, to suggest the type text that can go in the field.
If the user does not fill out the field, it will have no value (FIGURE 9.7).
Each form should also have a submit
field, which has its own input type. When the browser sees this input type, it will generate a button for the user to click, in order to send the form’s data using the method
and action
you defined in the opening <form>
tag.
Although you can set the value of a submit input type, it is immutable outside of markup, so the user cannot change it.
Putting it all together, you get this:
<form name="search-form" method="GET" → action="process.php"> <input type="text" →name="search-term" /> <input type="submit" name="submit" →value="Search" /> </form>
… which looks like FIGURE 9.8 in the browser.
If a user were to enter Atlantis into the search form, the URL would look like this:
yoursite.com/process.php?search-term=
→ Atlantis
Text and submit are not the only types of input available. You can submit data using a variety of formats (FIGURE 9.9, CODE 9.1):
text
: A single line of text.
password
: A field designed for users to add passwords or other sensitive text. This field obfuscates input, using dots to hide its contents.
radio
: A button (typically circular) usually created in groups. Only one of the buttons in a group can be selected at a time, which makes radio buttons the ideal way to offer your user a range of options from which they must choose one.
Use the checked
attribute to select a default value.
checkbox
: A set of square boxes that present the user with several options. One or more can be selected.
Use the checked
attribute to select a default value.
email
: This input type tells the browser to make sure the user has entered a properly formatted email address.
file
: A text field with a Choose File button. Clicking the button opens a file navigation dialog box the user can use to find and select a file on their computer for upload to a server.
submit
: A button that, when clicked, sends the form for processing.
image
: Works just like the submit button, but you can use an image you provide instead of the standard browser-rendered submit button.
Due to advancements in CSS, you see this used a lot less than it once was.
hidden
: Creates a form field that cannot be seen or edited by users. This is often used to capture dynamically generated content, like a timestamp or ID. For example, on a blog post, a comment form would have a hidden field with the ID of the post so that the blog publisher knows which post the comment belongs to.
There are also a few fields that act like text fields but require specific kinds of text. They are email
, date
, search
, tel
, and url
. You will learn more about them in the “Validating Forms” section of this chapter.
Aside from the <input>
tag, there are two other field elements worth mentioning.
A <textarea>
field allows users to enter a block or paragraph of text; it also uses a closing </textarea>
tag. The default text of this field goes in between the opening and closing tags. See Code 9.1 for an example.
The <select>
element creates a dropdown menu, or list of options. By default, only one option in the list can be selected. You can allow the reader to select more than one option by including the multiselect
attribute.
To populate a <select>
field, you’ll need to include the <option>
element between the opening and closing <select>
tags. In this instance, <select>
should include the name
attribute, but each <option>
tag should have its own value
attribute.
See Code 9.1 for an example. You’ll create your own select box in an upcoming task!
Although the placeholder
attribute does a reasonable job of communicating the kind of information the user should enter into many form fields, there’s a better, more semantic way: use a <label>
element with your <input>
elements.
<div> <label for="first_name">First → Name:</label> <input type="text" → name="first_name" → id="first_name" placeholder= → "Milo" /> </div>
In the browser, this code is rendered as a text box labeled with the kind of data the user is expected to enter (FIGURE 9.10).
You’ll notice that the label has a for
attribute. That attribute matches the id
attribute on the input element. This tells the browser, “This label belongs to the <input>
element whose ID matches the for
attribute.”
Aside from improving user experience, labeling your input fields provides accessibility benefits:
If a visitor to your site is using a screen reader, it can read the text of the label out loud when the input element has user focus (for example, when the user taps it or clicks it with a mouse).
Because clicking the label activates the form field, the overall “hit area” for the form element is increased. This can make it easier for users with decreased mobility to activate the input fields.
Before moving on and creating examples of form inputs, you’ll write a simple form skeleton, to which you can add the example inputs you create in the rest of the tasks.
To create a form skeleton:
Type <form name="example-form"
.
Type method="GET">
.
Leave a blank line between the previous line and the next line.
On the next line, type <input type="submit" name="submit" value="Submit" />
.
On the next line, type </form>
.
You should now have this:
<form name="example-form" → method="GET"> <input type="submit" name="submit" →value="Submit" /> </form>
Select boxes are an intuitive way to allow your users to pick from a list of items. There are two ways a select box can work: as a simple dropdown menu, which allows only one option to be selected, or as a multiselect box, where several items can be selected. The following tasks will show you how to build both. Using the form skeleton you created in the previous task, insert the code you will build in the following task right after the opening <form>
tag.
To create a select box:
First, create the label for the select box. Be sure to include the for
attribute with the ID for the label. For this example, type <label for="next-movie">What movie do you want to see next?</label>
.
Type the opening tag for the select box: <select
.
Give the box a name and assign its ID by typing name="next-movie" id="next-movie">
.
Next, define the <option>
elements that will be listed on the menu. This example uses movie titles.
Type <option value="Toy Story 4"> Toy Story 4</option>
.
Type <option value="Onward">Onward </option>
.
Type <option value="Fast 9">Fast 9 </option>
.
Type </select>
.
This creates a box that lists three options, from which the user can pick one (FIGURE 9.11).
To create a multiselect box:
Type <label for="seen-movies">What movies have you seen?</label>
.
Type <select name="seen-movies" id="seen-movies"
.
Type multiple>
and press Return/Enter.
Each of the following option
elements belongs on its own line.
Type <option value="Atlantis"> Atlantis</option>
.
Type <option value="Snow White">Snow White</option>
.
Type <option value="Aladdin"> Aladdin</option>
.
Type </select>
.
This creates a box that lists three options. The user can hold the Shift key while clicking to select more than one contiguous option, or they can hold Command (macOS)/Ctrl (Windows) to select multiple noncontiguous options (FIGURE 9.12).
Radio buttons are another way to present a user with options and have them pick one (the select box is the first way). Once a radio button is selected, it cannot be deselected without selecting another radio button.
Using the form skeleton you created in a previous task, place the following code from the task right after the opening <form>
tag.
To create radio buttons:
If you want to provide a title or other introductory text for your buttons, include it in a paragraph element. For this example, type <p>What is your favorite movie?</p>
.
Type <input type="radio" name= "favorite-movie" id="atlantis" value="Atlantis" /> <label for="atlantis">Atlantis</label>
.
Type <input type="radio" name= "favorite-movie" id="snow-white" value="Snow White" /> <label for="snow-white">Snow White </label>
.
Type <input type="radio" name= "favorite-movie" id="aladdin" value="Aladdin" checked /> <label for="aladdin">Aladdin</label>
(FIGURE 9.13).
Note the checked
attribute on this input.
Notice the value of the name
attribute of all three buttons is the same. That’s to tell the browser, “These buttons belong together.”
Checkboxes are a great way to present the user with multiple options and allow them to accept more than one. Unlike radio buttons, where the user can only choose one, there is generally no limit on the number of checkboxes a user can select.
Using the form skeleton you created in a previous task, place the following code from the task right after the opening <form>
tag.
To create checkboxes:
Type the introductory text, if any; in this case, use <p>What movies do you want to see?</p>
.
Type <input type="checkbox" name="want-to-see-1" id="atlantis" value="Atlantis" checked/> <label for="atlantis">Atlantis</label>
.
Note the checked attribute.
Type <input type="checkbox" name= "want-to-see-2" id="snow-white" value="Snow White" /> <label for="snow-white">Snow White </label>
.
Type <input type="checkbox" name="want-to-see-3" id="aladdin" value="Aladdin" /> <label for="aladdin">Aladdin</label>
(FIGURE 9.14).
Notice that the names of these checkboxes have a number appended. If they were named the same, they would all effectively represent one option because as we learned earlier, the name
attribute of each form field on a page must be unique. This rule does not apply to radio buttons, of course.
Email forms are super common online, as are inputs to capture email in general. That’s why the email
input type exists. It will self-validate to make sure the user is entering an email address that’s in the proper format (but it won’t know whether the email address actually exists).
To create a simple email opt-in form:
Type the opening tag for the form
element, making sure to include the name
or id
, method
, and action
attributes. For this example, use <form name="optin" method="GET" action="process.php">
.
Our example form includes two <input>
elements, each with a label
: a text
input for the user’s first name, and the email
input.
Create the label for the user’s name: <label for="first-name">First Name:</label>
.
Type <input type="text" name="first_name" id="first-name" placeholder="First Name" />
.
Type <label for="email-address"> Email Address:</label>
.
Type <input type="email" name="email_address" id="email-address" placeholder="Email Address" />
.
Type <input type="submit" name="submit" value="Join the List!" />
.
Type </form>
(FIGURE 9.15).
There is a set of input types that add special controls and selectors. They offer a better way for users to insert properly formatted data. This reduces the need to take separate measures to validate and makes the input more reliable.
The date
input type (FIGURE 9.16) brings up a calendar for users to pick a date from (FIGURE 9.17). The browser display (what you see in the box) depends on the user’s locale (where they are located, based on what the browser knows). The date is always sent in the format YYYY-MM-DD
.
<input type="date"
→ name="release-date" />
You can constrain a user’s selection to a specific range of dates by using the min
and max
attributes:
<input type="date" name="release"
→ min="1937-12-21" max="1992-11-11" />
Note that the min
and max
attributes affect the date picker, but a user will be able to manually set any date, even if it’s outside the range. This is a good use case for validation with JavaScript.
Finally, there are a few other date- and time- related inputs:
datetime-local
: This allows the user to select a date and time without including the time zone. That means that even if you’re in New York and your user is in London, you’ll both see the same date and time inputs.
time
: Allows the user to select a time with no time zone included.
month
: Allows the user to select a month and year.
week
: Allow the user to select a week number and year.
When capturing times in a form, since time zones are not supported, you’ll need to capture them a different way. You can use a hidden field for this if you don’t want the user to change the time zone (this works best for local events or appointments). If you want them to select their own time zone, you can use a select box.
The color
input type allows users to select a color through use of a color picker (FIGURE 9.18):
<input type="color" name="carpet-color"
→ value="#FF0000" />
The value is a seven-character code in hexadecimal format (which you’ll learn all about in Chapter 14). The default value of color
is black unless you specify a different value.
The range
input type creates a slide controller that allows users to adjust the value of a parameter by sliding the controller along a scale. You can set min
and max
attributes to limit the possible range of values (FIGURE 9.19). The default values for min
and max
are 0 and 100, respectively.
<input type="range" name="rating"
→ min="0" max="10" />
You can also use the step
attribute, which allows you to set a specific increment by which values can change. The default value is 1. The step
attribute happens to be supported for date
inputs as well, but it is best for imprecise values, as in a volume controller.
<meter>
elements: one with, and one without, min and max values defined.<label for="fuel">Fuel level:</label>
<meter id="fuel" value="0.2">
At 20%
</meter>
<label for="donations">Donations:</label>
<meter id="donations" min="0" max="100000"
→ value="60000">
at $60,000
</meter>
<meter>
ElementOne pretty nifty element is <meter>
, which graphically represents a value over a range. It accepts several attributes, but the ones to know about are value
, min
, and max
. The attributes min
and max
are optional. If they are not specified, they default to 0 and 1, respectively, and value
is a fraction. If min
and max
are defined, they determine the scale for value
. You can see <meter>
in action in FIGURE 9.21, which is generated by CODE 9.2.
Validation is an incredibly important part of any form. There are three primary ways to validate forms:
The built-in HTML5 validation for specific fields like email, URL, phone number, and more, as well as the validation attributes required
and, if needed, pattern
.
You can use JavaScript to validate data when it is input by the user, especially if that data isn’t automatically validated by one of the input types. One example in the US is the zip code; they should follow a specific format, but there is no input type defined for them.
A server-side script written in a language like PHP. Validating at this stage makes sure all data is in the right format, and that there are no malicious attempts at hacking before you process it. While you don’t need to know server-side validation for the examples in this book, once you start learning how to write server-side code, you will need to keep this in mind as you process forms.
For the purposes of this book, using the built-in HTML validation works well. As you begin to do more advanced form processing, knowing how to validate with both JavaScript and a server-side language is important.
Javascript and PHP are outside the scope of this book, but there are a couple of helpful files in the Github repo for this book.
Instead, here’s how to apply some great form validation with HTML5 only.
The most basic validation you can add is to ensure that required fields are filled out. That is as simple as adding the required
attribute:
<div> <label for=first_name">First Name*: → </label> <input type="text" name="first_name" → id="first_name" placeholder="First → Name" required/> </div>
It’s also a good practice to provide a visual indicator that a field is required. Common methods include adding an asterisk (*) or the word required in parentheses next to the label.
Testing webpages is just as important as building them, and in this video, you’ll see how to build a small form using the validation methods, and then you’ll test it to make sure it works properly.
If the required field is not filled out, modern browsers will display an error message (FIGURE 9.22).
Similarly, there is a set of input types that have automatic validation:
email
: Looks for a valid email address (FIGURE 9.23).
url
: Looks for a valid URL format.
number
: Looks for a valid numerical value. Using the min
and max
attributes will validate on a specific range:
<input type="number" name="age"
→ mix="13" max="150" />
tel
: Looks for a telephone number.
This requires the pattern
attribute.
The final piece of validation that can be applied in HTML is the pattern
attribute. This requires knowledge of regular expressions (regex), but it allows you to supply the description of a pattern, which all input can be validated against. Here’s an example of a US telephone format:
<input type="tel" name="phone_number" → id="phone_number" → pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"/>
Regular expressions are a way of performing complex searching of text by describing what they should look like. For example, the regex [0-9]{3} means “any three digits between 0 and 9, inclusive of 0 and 9.” A great resource for learning regex is regexone.com/.
There’s a lot to know about forms, but thanks to HTML5 and advances in browser technology, you can do a lot more with plain HTML today than you could even just a few years ago.
I encourage you to experiment with all the different inputs and data types to learn exactly how they work. You’ll find that you can build some pretty impressive, and interactive, webpages.