HTML-Based Web Development
Senior 4 · ICT
HTML-Based Web Development
Lesson 5 of 5
25 min
Every page so far has only shown information. A form lets the visitor send information back: a search box, a log-in page, an application for a service on Irembo, a school's online admission form. The visitor fills in the form, the browser packs the answers up and sends them to a program on a web server, and that program replies with a new page: the search results, the account, a receipt.
HTML builds the form and the browser checks and sends it. Receiving and storing the data needs a program on the server, written in a language such as PHP or Python, and usually a database (Unit 7). This lesson covers the HTML side.
Definition
Form (<form>): a part of a page that collects data from the user and submits it to a URL.
Form control: an element the user fills in or chooses with: a text box, a checkbox, a drop-down list, a button.
Name/value pair: what each control submits, its name attribute and the user's answer, for example club=ict. A control with no name sends nothing.
Label (<label>): the visible caption of a control, linked to it.
Client-side validation: checks the browser makes before sending, such as "this field is required" or "this is not an email address".

Two attributes of <form> decide where the data goes and how it travels:
action: the URL of the server program that will receive the data, such as action="/register".method: get or post.| GET | POST | |
|---|---|---|
| Where the data goes | In the URL, after ? | In the body of the request |
| Seen in the address bar, history and server logs? | Yes | No |
| Can the result be bookmarked or shared? | Yes | No |
| Size | Limited by the URL length | Large data and file uploads |
| Use it for | Searches and filters that only read data | Passwords, personal data, anything that changes data |
POST keeps data out of the URL, but it does not encrypt it: only HTTPS does that. A form that asks for a password must be on an https:// page.
Most controls are an <input>, a void element whose type attribute decides what it is. On a phone, the type also chooses the keyboard: email shows an @ key and tel and number show a number pad.
| Control | Use |
|---|---|
<input type="text"> | One line of text |
type="email", "url", "tel" | An email address, a web address, a phone number (email and url are checked) |
type="password" | Text hidden as dots |
type="number", "range" | A number, typed or chosen with a slider; min, max, step set the limits |
type="date" | A date picker |
type="radio" | Choose ONE from a group; all buttons in the group share the same name |
type="checkbox" | Tick any number, including none |
type="file" | Upload a file (the form needs method="post" and enctype="multipart/form-data") |
<select> with <option> | A drop-down list |
<textarea rows cols> | Several lines of text |
<button type="submit">, type="reset" | Send the form; clear it back to its starting values |
<fieldset> with <legend> | A box that groups related controls under a caption |
Useful attributes on controls: name (the key that is sent), id (links the label), value (what a radio button, checkbox or option sends), checked and selected (chosen at the start), placeholder (a grey hint inside an empty box), required, maxlength, min, max, disabled.
Labels. Write <label for="email"> and give the control id="email". The label is then read out by screen readers, and clicking it puts the cursor in the box or ticks the checkbox, a larger target for a finger on a phone.
Run it. Click "Send" with the boxes empty: the browser stops you and points to the first required field. Type an email without @, or an age of 40, and the browser complains again. That is client-side validation, done before anything is sent. Fill everything in correctly and press Send: the line under the form shows the name/value pairs the browser would submit, such as fullname=Aline+Uwase&email=aline%40example.org&age=16&class=s4&club=ict&days=wed&why=I+like+coding. Notice that the unticked checkbox sends nothing, and that the <script> at the bottom is JavaScript added only because the playground has no server.
Worked example 1: from a paper form to HTML controls
A school's paper form for the science fair asks for: the pupil's name; date of birth; class (S4, S5 or S6); which days they can help (Friday, Saturday, or both); whether they will present or only visit; and a short description of the project. Choose a control for each.
| Field | Control | Why |
|---|---|---|
| Name | <input type="text" name="name" required> | Free text, and the form is useless without it |
| Date of birth | <input type="date" name="dob"> | A date picker avoids "12-03" versus "03-12" confusion |
| Class | <select name="class"> with three options | A fixed list of choices |
| Days | Two checkboxes, name="days" | Any number of days may be ticked |
| Present or visit | Two radio buttons with the same name="role" | Exactly one of the two |
| Project description | <textarea name="project" rows="4"> | Several lines of text |
Worked example 2: three bugs in one form
<form action="/vote" method="post"> <label>Your name</label> <input type="text" id="voter"> <input type="radio" name="choice1" value="yes"> Yes <input type="radio" name="choice2" value="no"> No <button type="submit">Vote</button> </form>
for, so clicking it does nothing and a screen reader cannot tell what the box is for. Fix: <label for="voter">.id but no name, so the server receives no name at all. Fix: add name="voter".name. Fix: give both name="choice"; the server then receives choice=yes or choice=no. Each button also needs its own id and linked label.Worked example 3: GET or POST?
| Form | Method | Reasoning |
|---|---|---|
| The search box of a library catalogue | GET | It only reads data, and a URL like search?q=chemistry can be bookmarked and shared. |
| A log-in form | POST | A password in the URL would be saved in the browser history and in server logs. |
| Registering for the science fair | POST | It changes data on the server (adds a pupil) and contains personal data. |
| Filtering a list of books by subject and class | GET | It reads data; the filtered list can be shared as a link. |
The browser's checks (required, type="email", min, max, maxlength, pattern) save the visitor from mistakes, but they are a convenience, not protection: anyone can switch them off or send data without using your form. The program on the server must check every value again.
Forms often collect personal data. In Senior 2 you met Rwanda's law relating to the protection of personal data and privacy of 2021. A good form asks only for what it really needs, says why it needs it, and is sent over HTTPS.
Web Dev Simplified: Learn HTML Forms In 25 Minutes. Watch labels linked with for and id, the main input types, radio groups that share a name, select lists and textareas, and what the browser sends when the form is submitted.
Warning
<label>.Tip
No name, no data. When a value is missing at the server, look first for a control without a name. And remember the pairs: for matches id; radio buttons in one group match on name.
Practice
action and method attributes of a form decide?contact.level for Beginner, Intermediate and Advanced, with Beginner chosen at the start.province listing the City of Kigali and the four provinces.action="/search" and a text box named q. A user types html tables. Write the URL path the browser requests.required on a field does not guarantee the server never receives an empty value.action: the URL of the program that receives the data. method: how it is sent, GET (in the URL) or POST (in the request body).<label for="contact">Email</label> <input type="email" id="contact" name="contact" required><input type="radio" id="beg" name="level" value="beginner" checked><label for="beg">Beginner</label>, then the same for inter and adv with the same name="level" and no checked.<select name="province"><option>City of Kigali</option><option>Northern Province</option><option>Southern Province</option><option>Eastern Province</option><option>Western Province</option></select>, with a linked label./search?q=html+tables (the space is encoded as +).Key points
<form action method>: action is where the data goes; GET puts it in the URL (searches), POST in the request body (passwords, personal data, changes).name=value pairs; without a name, nothing is sent. Link every <label for> to a control's id.input types (text, email, password, number, date, radio, checkbox, file), select, textarea, button, fieldset and legend.Further reading
Sources and credits
This lesson adapts CC BY-SA material and is shared under CC BY-SA 4.0.
<h2>Join a club</h2>
<form action="/register" method="post">
<fieldset>
<legend>About you</legend>
<p>
<label for="fullname">Full name</label><br>
<input type="text" id="fullname" name="fullname" required maxlength="60">
</p>
<p>
<label for="email">Email</label><br>
<input type="email" id="email" name="email" placeholder="name@example.org" required>
</p>
<p>
<label for="age">Age</label><br>
<input type="number" id="age" name="age" min="12" max="25">
</p>
<p>
<label for="cls">Class</label><br>
<select id="cls" name="class">
<option value="s4">Senior 4</option>
<option value="s5">Senior 5</option>
<option value="s6">Senior 6</option>
</select>
</p>
</fieldset>
<fieldset>
<legend>Which club?</legend>
<input type="radio" id="ict" name="club" value="ict" checked>
<label for="ict">ICT</label>
<input type="radio" id="debate" name="club" value="debate">
<label for="debate">Debate</label>
</fieldset>
<fieldset>
<legend>Days you can attend</legend>
<input type="checkbox" id="wed" name="days" value="wed">
<label for="wed">Wednesday</label>
<input type="checkbox" id="sat" name="days" value="sat">
<label for="sat">Saturday</label>
</fieldset>
<p>
<label for="why">Why do you want to join?</label><br>
<textarea id="why" name="why" rows="3" cols="40"></textarea>
</p>
<button type="submit">Send</button>
<button type="reset">Clear</button>
</form>
<p id="sent"></p>
<script>
// Only for this playground, which has no server:
// show the name=value pairs the browser would send.
document.querySelector("form").addEventListener("submit", function (e) {
e.preventDefault();
var pairs = new URLSearchParams(new FormData(this)).toString();
document.getElementById("sent").textContent = "Would send: " + pairs;
});
</script>Quick check
Which method should a log-in form use, and why?