Learn HTML in 10 DaysDay 7: Advanced Forms

Day 7: Advanced Forms

What You'll Learn Today

  • HTML5 validation features
  • New input types
  • Autocomplete with datalist
  • Progress and meter elements

HTML5 Validation

HTML has built-in validation that checks form input without JavaScript.

flowchart LR
    Input["User Input"] --> Validate{"HTML5<br>Validation"}
    Validate -->|"✅ Valid"| Submit["Submit"]
    Validate -->|"❌ Invalid"| Error["Error Message"]
    Error --> Input
    style Validate fill:#f59e0b,color:#fff
    style Submit fill:#22c55e,color:#fff
    style Error fill:#ef4444,color:#fff

Validation Attributes

Attribute Description Example
required Required field required
minlength Minimum characters minlength="3"
maxlength Maximum characters maxlength="100"
min Minimum value min="0"
max Maximum value max="100"
step Step increment step="0.01"
pattern Regex pattern pattern="[0-9]{3}"

Examples

<form>
    <label for="name">Name (required):</label>
    <input type="text" id="name" name="name" required>

    <label for="username">Username (3–20 chars):</label>
    <input type="text" id="username" name="username"
           minlength="3" maxlength="20" required>

    <label for="age">Age (1–120):</label>
    <input type="number" id="age" name="age"
           min="1" max="120" required>

    <label for="zipcode">ZIP Code (e.g., 12345):</label>
    <input type="text" id="zipcode" name="zipcode"
           pattern="[0-9]{5}"
           title="Enter a 5-digit ZIP code"
           required>

    <button type="submit">Submit</button>
</form>

Pattern Attribute Examples

Pattern Description Matches
[0-9]{5} 5 digits 12345
[A-Za-z]+ 1+ letters hello
[0-9]{5}(-[0-9]{4})? US ZIP 12345 or 12345-6789
.{8,} 8+ characters password1

New Input Types

Color Picker

<label for="color">Theme color:</label>
<input type="color" id="color" name="color" value="#3b82f6">

File Upload

<label for="avatar">Profile picture:</label>
<input type="file" id="avatar" name="avatar"
       accept="image/png, image/jpeg">

<input type="file" name="documents" multiple
       accept=".pdf,.doc,.docx">

Hidden Input

<input type="hidden" name="form_id" value="contact-v2">

Datalist Autocomplete

<label for="browser">Browser:</label>
<input type="text" id="browser" name="browser" list="browsers">
<datalist id="browsers">
    <option value="Chrome">
    <option value="Firefox">
    <option value="Safari">
    <option value="Edge">
    <option value="Opera">
</datalist>

Note: Unlike <select>, <datalist> suggests options but also allows free text input.

flowchart LR
    subgraph Comparison["datalist vs select"]
        DL["&lt;datalist&gt;<br>Suggestions + Free input"]
        SL["&lt;select&gt;<br>Fixed choices only"]
    end
    style DL fill:#22c55e,color:#fff
    style SL fill:#3b82f6,color:#fff

Output Element

<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
    <input type="number" id="a" name="a" value="0"> +
    <input type="number" id="b" name="b" value="0"> =
    <output name="result" for="a b">0</output>
</form>

Progress and Meter

Progress Bar

<label for="download">Download progress:</label>
<progress id="download" value="70" max="100">70%</progress>

Meter

<label for="disk">Disk usage:</label>
<meter id="disk" value="65" min="0" max="100"
       low="30" high="80" optimum="20">65%</meter>
Element Purpose Key Attributes
<progress> Task progress value, max
<meter> Measured value value, min, max, low, high, optimum

Form Grouping

<form>
    <fieldset>
        <legend>Personal Information</legend>
        <p>
            <label for="fname">Name:</label>
            <input type="text" id="fname" name="fname" required>
        </p>
        <p>
            <label for="femail">Email:</label>
            <input type="email" id="femail" name="femail" required>
        </p>
    </fieldset>

    <fieldset>
        <legend>Shipping Information</legend>
        <p>
            <label for="address">Address:</label>
            <input type="text" id="address" name="address" required>
        </p>
        <p>
            <label for="delivery-date">Delivery date:</label>
            <input type="date" id="delivery-date" name="delivery-date"
                   min="2026-01-30">
        </p>
    </fieldset>

    <button type="submit">Place Order</button>
</form>

Practice: Registration Form

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sign Up</title>
</head>
<body>
    <h1>Create Account</h1>

    <form action="/register" method="post">
        <fieldset>
            <legend>Account</legend>
            <p>
                <label for="reg-username">Username (3–20 chars):</label><br>
                <input type="text" id="reg-username" name="username"
                       minlength="3" maxlength="20" required
                       pattern="[a-zA-Z0-9_]+"
                       title="Letters, numbers, and underscores only">
            </p>
            <p>
                <label for="reg-email">Email:</label><br>
                <input type="email" id="reg-email" name="email" required>
            </p>
            <p>
                <label for="reg-password">Password (8+ chars):</label><br>
                <input type="password" id="reg-password" name="password"
                       minlength="8" required>
            </p>
        </fieldset>

        <fieldset>
            <legend>Profile</legend>
            <p>
                <label for="reg-birthday">Birthday:</label><br>
                <input type="date" id="reg-birthday" name="birthday">
            </p>
            <p>
                <label for="reg-country">Country:</label><br>
                <input type="text" id="reg-country" name="country" list="countries">
                <datalist id="countries">
                    <option value="United States">
                    <option value="United Kingdom">
                    <option value="Japan">
                    <option value="Canada">
                    <option value="Australia">
                </datalist>
            </p>
            <p>
                <label for="reg-bio">Bio:</label><br>
                <textarea id="reg-bio" name="bio" rows="4" cols="50"
                          maxlength="500"
                          placeholder="Tell us about yourself (500 chars max)"></textarea>
            </p>
        </fieldset>

        <fieldset>
            <legend>Notifications</legend>
            <label>
                <input type="checkbox" name="notify_email" checked>
                Receive email notifications
            </label><br>
            <label>
                <input type="checkbox" name="notify_news">
                Subscribe to newsletter
            </label>
        </fieldset>

        <p>
            <label>
                <input type="checkbox" name="agree" required>
                I agree to the <a href="/terms">Terms of Service</a>
            </label>
        </p>

        <button type="submit">Sign Up</button>
    </form>
</body>
</html>

Summary

Concept Description
HTML5 Validation required, pattern, min/max, etc.
pattern Regex-based input checking
<datalist> Autocomplete suggestions
<output> Calculation result output
<progress> Progress bar
<meter> Measurement gauge

Key Takeaways

  1. HTML5 validation checks input before server submission
  2. Use pattern and title together
  3. <datalist> allows flexible suggestions with free input
  4. HTML5 validation does not replace server-side validation

Exercises

Exercise 1: Basic

Create a form with ZIP code and phone number validation using pattern.

Exercise 2: Intermediate

Create a <datalist>-powered form for selecting programming languages (10+ options).

Challenge

Build a complete event registration form with attendee info, event selection (radio), dietary restrictions (checkboxes), date (future dates only), and notes (textarea)—all with proper validation.


References


Next up: In Day 8, you'll learn "Semantic HTML"—giving your pages meaning with <header>, <main>, <footer>, and more.