Skip to main content

Session 2

HTML Forms

HTML Forms are a fundamental building block of interactive web development, designed to collect user input dynamically at runtime. In this session, you will gain a foundational understanding of how to create, structure, and implement HTML forms to gather information from users. The data entered through these forms is typically transmitted to a web server for processing, validation, and storage.

Forms are widely used to collect essential information such as usernames, passwords, contact details (e-mail IDs, mobile numbers), and other user preferences. This session introduces the core <form> container element and explores the various input controls it can hold, including:

  • Text fields & text areas
  • Radio buttons & checkboxes
  • Submit & clickable buttons
  • Labels for accessibility and clarity
  • HTML5-specific input types (e.g., email, search, url, date, month, time)

Objective

After Completing this session, one should be able to:

  • Understand the HTML form element
  • use the form element in HTML
  • use HTML to acquire user input and process it
  • Create forms with basic elements like textboxes, checkboxes, radio buttons and submit buttons.
  • Create forms using HTML5 elements like E-Mail address field and form validation

Question 1

Problem Statement

Create an HTML webpage, as shown in the figure [2.1]. The user can specify any expression as input. Use form element to collect the user data.

Figure 2.1 (Demo)
  • Reference by question
  • Working demo for preview

Expression

Result

Code

form.html
		<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Vanilla Expression Calculator</title>
        <style>
            .demo-1 {
                color: black;
            }
            /* Replicates: grid grid-cols-2 border p-1 w-1/3 mt-3 gap-1 */
            .grid-container {
                display: grid;
                grid-template-columns: 1fr 1fr;
                border: 1px solid #333;
                color: black;
                padding: 0.25rem;
                width: 33.333%;
                margin-top: 0.75rem;
                gap: 0.25rem;
                box-sizing: border-box;
                font-family:
                    system-ui,
                    -apple-system,
                    sans-serif;
            }
 
            /* Replicates: border p-1 px-2 font-bold */
            .grid-item,
            .grid-input {
                border: 1px solid #333;
                padding: 0.25rem 0.5rem;
                font-weight: bold;
                box-sizing: border-box;
                margin: 0;
                color: black;
            }
 
            .grid-input {
                outline: none;
                background: #fff;
            }
 
            .grid-input:focus {
                border-color: #2563eb;
                box-shadow: 0 0 0 1px #2563eb;
            }
 
            .grid-header {
                background-color: #f3f4f6;
            }
        </style>
    </head>
    <body class="demo-1">
        <div class="grid-container">
            <p class="grid-item grid-header">Expression</p>
            <p class="grid-item grid-header">Result</p>
 
            <input type="text" class="grid-input" id="expression-1" />
            <input type="text" class="grid-input" id="result-1" readonly />
 
            <input type="text" class="grid-input" id="expression-2" />
            <input type="text" class="grid-input" id="result-2" readonly />
        </div>
 
        <script>
            // 1. Mirror the $state object
            const inputvalue = {
                1: "1+1",
                2: "1+1*2",
                result1: "2",
                result2: "3",
            };
 
            // 2. Cache DOM elements for performance
            const els = {
                expr1: document.getElementById("expression-1"),
                res1: document.getElementById("result-1"),
                expr2: document.getElementById("expression-2"),
                res2: document.getElementById("result-2"),
            };
 
            // 3. Initialize inputs with default state
            els.expr1.value = inputvalue[1];
            els.res1.value = inputvalue.result1;
            els.expr2.value = inputvalue[2];
            els.res2.value = inputvalue.result2;
 
            // 4. Core calculation function
            function onInputChange(index) {
                const exprEl = index === 1 ? els.expr1 : els.expr2;
                const resEl = index === 1 ? els.res1 : els.res2;
 
                // Sync DOM -> State
                inputvalue[index] = exprEl.value;
 
                try {
                    // Note: eval() is used as requested. In production, consider a math parser
                    // like math.js or new Function() for better security & performance.
                    const result = eval(inputvalue[index]);
 
                    // Sync State -> DOM
                    inputvalue[`result${index}`] = result;
                    resEl.value = result;
                } catch (error) {
                    inputvalue[`result${index}`] = "Error";
                    resEl.value = "Error";
                }
            }
 
            // 5. Attach event listeners
            // Using 'input' fires on every keystroke (better UX for calculators).
            // Change to 'change' if you only want it to fire on blur/enter.
            els.expr1.addEventListener("input", () => onInputChange(1));
            els.expr2.addEventListener("input", () => onInputChange(2));
        </script>
    </body>
</html>
	

Question 2

Problem Statement

Create a scrolling list that shows five items from the following list of PC processors: Intel i7, Motorola 68000, AMD Athlon , Intel 8088, AMD Ryzon, Intel Pentium MMX, Intel i3, Intel Pentium II, Intel Pentium III, Intel i5, Intel Celeron, PowerPC G3, PowerPC G4.

Preview

PC Processors
  • 1 Intel i7
  • 2 Motorola 68000
  • 3 AMD Athlon
  • 4 Intel 8088
  • 5 AMD Ryzen
  • 6 Intel Pentium MMX
  • 7 Intel i3
  • 8 Intel Pentium II
  • 9 Intel Pentium III
  • 10 Intel i5
  • 11 Intel Celeron
  • 12 PowerPC G3
  • 13 PowerPC G4

Code

list-scroller.html
		<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>PC Processors Scroll List</title>
        <style>
            * {
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }
 
            body {
                font-family:
                    system-ui,
                    -apple-system,
                    sans-serif;
                background: #0f172a;
                display: flex;
                justify-content: center;
                align-items: center;
                height: 100svh;
                padding: 12px;
            }
 
            .scroll-container {
                width: 100%;
                max-width: 420px;
                height: 50svh;
                background: #ffffff;
                border-radius: 16px;
                box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
                overflow-y: auto;
                scroll-behavior: smooth;
                position: relative;
            }
 
            .list-header {
                position: sticky;
                top: 0;
                background: #1e293b;
                color: #f8fafc;
                padding: 18px;
                text-align: center;
                font-size: 1.15rem;
                font-weight: 600;
                z-index: 10;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                letter-spacing: 0.5px;
            }
 
            .processor-list {
                list-style: none;
            }
 
            .processor-item {
                padding: 16px 20px;
                border-bottom: 1px solid #e2e8f0;
                display: flex;
                align-items: center;
                gap: 12px;
                transition: background 0.2s ease;
            }
 
            .processor-item:last-child {
                border-bottom: none;
            }
 
            .processor-item:hover {
                background: #f1f5f9;
            }
 
            .item-number {
                width: 32px;
                height: 32px;
                background: linear-gradient(135deg, #3b82f6, #8b5cf6);
                border-radius: 8px;
                display: flex;
                align-items: center;
                justify-content: center;
                color: white;
                font-size: 0.75rem;
                font-weight: 700;
                flex-shrink: 0;
            }
 
            .item-name {
                font-size: 1rem;
                color: #0f172a;
                font-weight: 500;
            }
 
            /* Custom Scrollbar */
            .scroll-container::-webkit-scrollbar {
                width: 8px;
            }
            .scroll-container::-webkit-scrollbar-track {
                background: #f8fafc;
            }
            .scroll-container::-webkit-scrollbar-thumb {
                background: #cbd5e1;
                border-radius: 4px;
                border: 2px solid #f8fafc;
            }
            .scroll-container::-webkit-scrollbar-thumb:hover {
                background: #94a3b8;
            }
        </style>
    </head>
    <body>
        <div class="scroll-container">
            <div class="list-header">PC Processors</div>
            <ul class="processor-list" id="processorList"></ul>
        </div>
 
        <script>
            const processors = [
                "Intel i7",
                "Motorola 68000",
                "AMD Athlon",
                "Intel 8088",
                "AMD Ryzen",
                "Intel Pentium MMX",
                "Intel i3",
                "Intel Pentium II",
                "Intel Pentium III",
                "Intel i5",
                "Intel Celeron",
                "PowerPC G3",
                "PowerPC G4",
            ];
 
            const listEl = document.getElementById("processorList");
 
            // Generate list items dynamically
            processors.forEach((proc, index) => {
                const li = document.createElement("li");
                li.className = "processor-item";
                li.innerHTML = `
                <div class="item-number">${index + 1}</div>
                <div class="item-name">${proc}</div>
            `;
                listEl.appendChild(li);
            });
        </script>
    </body>
</html>
	

Question 3

Problem Statement

Design a webpage for a software company to accept on-line job applications. The webpage must be designed to use form with elements:

  • Position applied for (autofocus), name, nationality, date of birth (selected from an auto picker), address (in a text area), telephone number and email (required).
  • Educational history and qualifications.
  • Work experience/employment/training in terms of employer history and number of years of experience selected from a slider. Set maximum years of experience to 10 years.
  • Personal statement.
  • Two referees including names, occupation, relationship, address, telephone.

Preview

Ethercorps

Online Job Application Portal

Personal & Contact Information
Education & Qualifications
Work Experience & Training
0 yrs
Personal Statement
Referees

Referee 1

Referee 2

Code

job-portal.html
		<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Apply Now - TechNova Solutions</title>
        <style>
            :root {
                --primary: #2563eb;
                --primary-hover: #1d4ed8;
                --bg: #f8fafc;
                --surface: #ffffff;
                --text: #0f172a;
                --text-muted: #475569;
                --border: #cbd5e1;
                --focus-ring: rgba(37, 99, 235, 0.3);
                --error: #ef4444;
                --success: #10b981;
                --radius: 10px;
                --shadow:
                    0 4px 6px -1px rgb(0 0 0 / 0.1),
                    0 2px 4px -2px rgb(0 0 0 / 0.1);
            }
 
            * {
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }
 
            body {
                font-family:
                    system-ui,
                    -apple-system,
                    "Segoe UI",
                    Roboto,
                    sans-serif;
                background: var(--bg);
                color: var(--text);
                line-height: 1.5;
                padding: 2rem 1rem;
                min-height: 100vh;
            }
 
            .container {
                max-width: 900px;
                margin: 0 auto;
                background: var(--surface);
                padding: 2.5rem;
                border-radius: var(--radius);
                box-shadow: var(--shadow);
            }
 
            header {
                text-align: center;
                margin-bottom: 2rem;
                padding-bottom: 1.5rem;
                border-bottom: 1px solid var(--border);
            }
 
            header h1 {
                font-size: 1.75rem;
                font-weight: 700;
                color: var(--text);
            }
 
            header p {
                color: var(--text-muted);
                margin-top: 0.25rem;
            }
 
            form {
                display: flex;
                flex-direction: column;
                gap: 1.75rem;
            }
 
            fieldset {
                border: 1px solid var(--border);
                border-radius: var(--radius);
                padding: 1.5rem;
                background: #fdfdfd;
            }
 
            legend {
                font-weight: 600;
                padding: 0 0.5rem;
                color: var(--primary);
                font-size: 1.1rem;
            }
 
            .form-grid {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
                gap: 1.25rem;
            }
 
            .form-group {
                display: flex;
                flex-direction: column;
                gap: 0.4rem;
            }
 
            .form-group.full-width {
                grid-column: 1 / -1;
            }
 
            label {
                font-size: 0.9rem;
                font-weight: 500;
                color: var(--text);
            }
 
            label .req {
                color: var(--error);
                margin-left: 2px;
            }
 
            input,
            textarea,
            select {
                padding: 0.75rem;
                border: 1px solid var(--border);
                border-radius: 8px;
                font-size: 0.95rem;
                font-family: inherit;
                transition:
                    border-color 0.2s,
                    box-shadow 0.2s;
                background: #fff;
            }
 
            input:focus,
            textarea:focus {
                outline: none;
                border-color: var(--primary);
                box-shadow: 0 0 0 3px var(--focus-ring);
            }
 
            input:invalid:not(:placeholder-shown) {
                border-color: var(--error);
            }
 
            textarea {
                resize: vertical;
                min-height: 100px;
            }
 
            /* Slider Styling */
            .slider-wrapper {
                display: flex;
                align-items: center;
                gap: 1rem;
                margin-top: 0.5rem;
            }
 
            input[type="range"] {
                flex: 1;
                cursor: pointer;
                accent-color: var(--primary);
            }
 
            .slider-value {
                min-width: 3ch;
                text-align: center;
                font-weight: 600;
                background: var(--bg);
                padding: 0.3rem 0.6rem;
                border-radius: 6px;
                border: 1px solid var(--border);
            }
 
            /* Referees Grid */
            .referees-grid {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 1.5rem;
            }
 
            .referee-card {
                background: #fff;
                border: 1px solid var(--border);
                border-radius: 8px;
                padding: 1.25rem;
            }
 
            .referee-card h3 {
                margin-bottom: 1rem;
                font-size: 1rem;
                color: var(--text-muted);
                border-bottom: 1px dashed var(--border);
                padding-bottom: 0.5rem;
            }
 
            /* Submit Button */
            button[type="submit"] {
                background: var(--primary);
                color: white;
                border: none;
                padding: 1rem 2rem;
                font-size: 1rem;
                font-weight: 600;
                border-radius: 8px;
                cursor: pointer;
                transition:
                    background 0.2s,
                    transform 0.1s;
                margin-top: 1rem;
                align-self: flex-start;
            }
 
            button[type="submit"]:hover {
                background: var(--primary-hover);
            }
            button[type="submit"]:active {
                transform: scale(0.98);
            }
            button[type="submit"]:disabled {
                background: var(--text-muted);
                cursor: not-allowed;
                opacity: 0.7;
            }
 
            /* Message Toast */
            .message {
                padding: 1rem;
                border-radius: 8px;
                margin-top: 1rem;
                display: none;
                font-weight: 500;
                text-align: center;
            }
 
            .message.success {
                background: #dcfce7;
                color: #166534;
                border: 1px solid #bbf7d0;
                display: block;
            }
 
            .message.error {
                background: #fee2e2;
                color: #991b1b;
                border: 1px solid #fecaca;
                display: block;
            }
 
            @media (max-width: 768px) {
                .container {
                    padding: 1.5rem;
                }
                .referees-grid {
                    grid-template-columns: 1fr;
                }
                button[type="submit"] {
                    width: 100%;
                    align-self: center;
                }
            }
        </style>
    </head>
    <body>
        <div class="container">
            <header>
                <h1>Ethercorps Solutions</h1>
                <p>Online Job Application Portal</p>
            </header>
 
            <form id="applicationForm" novalidate>
                <!-- Personal & Contact -->
                <fieldset>
                    <legend>Personal & Contact Information</legend>
                    <div class="form-grid">
                        <div class="form-group full-width">
                            <label for="position"
                                >Position Applied For
                                <span class="req">*</span></label
                            >
                            <input
                                type="text"
                                id="position"
                                name="position"
                                placeholder="e.g. Senior Frontend Developer"
                                required
                                autofocus
                            />
                        </div>
                        <div class="form-group">
                            <label for="fullName"
                                >Full Name <span class="req">*</span></label
                            >
                            <input
                                type="text"
                                id="fullName"
                                name="fullName"
                                required
                            />
                        </div>
                        <div class="form-group">
                            <label for="nationality"
                                >Nationality <span class="req">*</span></label
                            >
                            <input
                                type="text"
                                id="nationality"
                                name="nationality"
                                required
                            />
                        </div>
                        <div class="form-group">
                            <label for="dob"
                                >Date of Birth <span class="req">*</span></label
                            >
                            <input type="date" id="dob" name="dob" required />
                        </div>
                        <div class="form-group">
                            <label for="email"
                                >Email Address <span class="req">*</span></label
                            >
                            <input
                                type="email"
                                id="email"
                                name="email"
                                placeholder="[email protected]"
                                required
                            />
                        </div>
                        <div class="form-group full-width">
                            <label for="address">Address</label>
                            <textarea
                                id="address"
                                name="address"
                                rows="2"
                                required
                            ></textarea>
                        </div>
                        <div class="form-group">
                            <label for="phone"
                                >Telephone Number
                                <span class="req">*</span></label
                            >
                            <input
                                type="tel"
                                id="phone"
                                name="phone"
                                placeholder="+1 (555) 000-0000"
                                required
                            />
                        </div>
                    </div>
                </fieldset>
 
                <!-- Education -->
                <fieldset>
                    <legend>Education & Qualifications</legend>
                    <div class="form-group">
                        <label for="education"
                            >Educational History & Qualifications</label
                        >
                        <textarea
                            id="education"
                            name="education"
                            placeholder="Degrees, certifications, institutions, graduation dates..."
                        ></textarea>
                    </div>
                </fieldset>
 
                <!-- Work Experience -->
                <fieldset>
                    <legend>Work Experience & Training</legend>
                    <div class="form-group">
                        <label for="employmentHistory"
                            >Employer History & Training</label
                        >
                        <textarea
                            id="employmentHistory"
                            name="employmentHistory"
                            rows="4"
                            placeholder="Previous companies, roles, key responsibilities, training programs..."
                        ></textarea>
                    </div>
                    <div class="form-group">
                        <label for="yearsExp"
                            >Years of Experience (Max 10)</label
                        >
                        <div class="slider-wrapper">
                            <input
                                type="range"
                                id="yearsExp"
                                name="yearsExp"
                                min="0"
                                max="10"
                                step="1"
                                value="0"
                            />
                            <output id="yearsExpOutput" class="slider-value"
                                >0</output
                            >
                        </div>
                    </div>
                </fieldset>
 
                <!-- Personal Statement -->
                <fieldset>
                    <legend>Personal Statement</legend>
                    <div class="form-group">
                        <label for="personalStatement"
                            >Why are you a strong candidate?
                            <span class="req">*</span></label
                        >
                        <textarea
                            id="personalStatement"
                            name="personalStatement"
                            rows="4"
                            placeholder="Highlight your skills, motivation, and career objectives..."
                            required
                        ></textarea>
                    </div>
                </fieldset>
 
                <!-- Referees -->
                <fieldset>
                    <legend>Referees</legend>
                    <div class="referees-grid">
                        <div class="referee-card">
                            <h3>Referee 1</h3>
                            <div class="form-group">
                                <label for="ref1Name">Full Name</label>
                                <input
                                    type="text"
                                    id="ref1Name"
                                    name="ref1Name"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref1Occupation">Occupation</label>
                                <input
                                    type="text"
                                    id="ref1Occupation"
                                    name="ref1Occupation"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref1Relationship"
                                    >Relationship</label
                                >
                                <input
                                    type="text"
                                    id="ref1Relationship"
                                    name="ref1Relationship"
                                    placeholder="e.g. Former Manager"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref1Address">Address</label>
                                <textarea
                                    id="ref1Address"
                                    name="ref1Address"
                                    rows="2"
                                    required
                                ></textarea>
                            </div>
                            <div class="form-group">
                                <label for="ref1Phone">Telephone</label>
                                <input
                                    type="tel"
                                    id="ref1Phone"
                                    name="ref1Phone"
                                    required
                                />
                            </div>
                        </div>
 
                        <div class="referee-card">
                            <h3>Referee 2</h3>
                            <div class="form-group">
                                <label for="ref2Name">Full Name</label>
                                <input
                                    type="text"
                                    id="ref2Name"
                                    name="ref2Name"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref2Occupation">Occupation</label>
                                <input
                                    type="text"
                                    id="ref2Occupation"
                                    name="ref2Occupation"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref2Relationship"
                                    >Relationship</label
                                >
                                <input
                                    type="text"
                                    id="ref2Relationship"
                                    name="ref2Relationship"
                                    required
                                />
                            </div>
                            <div class="form-group">
                                <label for="ref2Address">Address</label>
                                <textarea
                                    id="ref2Address"
                                    name="ref2Address"
                                    rows="2"
                                    required
                                ></textarea>
                            </div>
                            <div class="form-group">
                                <label for="ref2Phone">Telephone</label>
                                <input
                                    type="tel"
                                    id="ref2Phone"
                                    name="ref2Phone"
                                    required
                                />
                            </div>
                        </div>
                    </div>
                </fieldset>
 
                <button type="submit" id="submitBtn">Submit Application</button>
                <div id="formMessage" class="message" aria-live="polite"></div>
            </form>
        </div>
 
        <script>
            document.addEventListener("DOMContentLoaded", () => {
                const form = document.getElementById("applicationForm");
                const slider = document.getElementById("yearsExp");
                const sliderOutput = document.getElementById("yearsExpOutput");
                const submitBtn = document.getElementById("submitBtn");
                const messageDiv = document.getElementById("formMessage");
 
                // Update slider output dynamically
                slider.addEventListener("input", () => {
                    sliderOutput.textContent = slider.value;
                });
 
                // Handle form submission
                form.addEventListener("submit", (e) => {
                    e.preventDefault();
                    messageDiv.className = "message"; // Reset classes
                    messageDiv.style.display = "none";
 
                    // Trigger native HTML5 validation
                    if (!form.checkValidity()) {
                        form.reportValidity();
                        return;
                    }
 
                    // Simulate async submission
                    submitBtn.disabled = true;
                    submitBtn.textContent = "Submitting...";
 
                    // Collect form data (for demonstration)
                    const formData = new FormData(form);
                    const data = Object.fromEntries(formData.entries());
                    console.log("Application Data:", data);
 
                    // Mock API delay
                    setTimeout(() => {
                        messageDiv.textContent =
                            "✅ Application submitted successfully! We will review your details and contact you shortly.";
                        messageDiv.classList.add("success");
                        messageDiv.style.display = "block";
 
                        // Reset form
                        form.reset();
                        sliderOutput.textContent = "0";
                        submitBtn.disabled = false;
                        submitBtn.textContent = "Submit Application";
 
                        // Scroll to message
                        messageDiv.scrollIntoView({
                            behavior: "smooth",
                            block: "nearest",
                        });
                    }, 1500);
                });
            });
        </script>
    </body>
</html>