Stage 2: Frontend Fundamentals

HTML · Lesson 05

Forms

Inputs, selects, textareas and labels for collecting user input correctly.

HTML5 min readFree lesson

Learn how to build forms (input forms) that collect data from users.


1. What Is a Form?

An HTML form is the interface through which users enter data and send it to a server.
It is used in almost every web service, including sign-ups, logins, search, and surveys.


2. The form Tag

<form action="URL to handle the data" method="get or post">
  <!-- input elements -->
</form>

Main Attributes

Attribute Description Value
action Server URL the form data is sent to A URL
method How the data is sent get or post
<!-- GET: data is exposed in the URL. Used for search, etc. -->
<form action="/search" method="get">
  <input type="text" name="query">
  <button type="submit">Search</button>
</form>
<!-- URL after submitting: /search?query=entered-value -->

<!-- POST: data is not exposed in the URL. Used for sign-ups, logins, etc. -->
<form action="/login" method="post">
  <input type="email" name="email">
  <input type="password" name="password">
  <button type="submit">Log in</button>
</form>

3. The input Tag — Various Types

<input> is a void element, so it has no closing tag.

text — Text Input

<input type="text" name="username" placeholder="Enter your name" maxlength="20">

email — Email Input

<input type="email" name="email" placeholder="[email protected]">
<!-- An error is shown automatically if the value is not an email format (contains @) -->

password — Password Input

<input type="password" name="password" minlength="8">
<!-- What you type is masked with ••• -->

number — Number Input

<input type="number" name="age" min="0" max="150" step="1" value="20">
<!-- min: minimum value, max: maximum value, step: increment size -->

checkbox — Checkboxes

<!-- Multiple selections allowed -->
<input type="checkbox" name="hobby" value="reading" id="hobby-reading">
<label for="hobby-reading">Reading</label>

<input type="checkbox" name="hobby" value="coding" id="hobby-coding" checked>
<label for="hobby-coding">Coding</label>
<!-- checked: checked by default -->

radio — Radio Buttons

<!-- Only one can be selected within the same name group -->
<input type="radio" name="gender" value="male" id="male">
<label for="male">Male</label>

<input type="radio" name="gender" value="female" id="female">
<label for="female">Female</label>

<input type="radio" name="gender" value="prefer-not-to-say" id="prefer">
<label for="prefer">Prefer not to say</label>

file — File Upload

<!-- Allow image files only -->
<input type="file" name="profile-img" accept="image/*">

<!-- Allow selecting multiple files -->
<input type="file" name="documents" accept=".pdf,.doc,.docx" multiple>

date — Date Picker

<input type="date" name="birthday" min="1900-01-01" max="2026-12-31">

range — Slider

<input type="range" name="satisfaction" min="1" max="10" value="5">

hidden — Hidden Value

<!-- Data the user cannot see but that is sent along with the form -->
<input type="hidden" name="user_id" value="12345">

Other input Types

<input type="tel" placeholder="555-000-0000">          <!-- Phone number -->
<input type="url" placeholder="https://example.com">    <!-- URL -->
<input type="color">                                     <!-- Color picker -->
<input type="search" placeholder="Enter a search term">  <!-- Search -->

4. The label Tag

<label> connects an input element with its descriptive text.

<!-- Method 1: connect with the for attribute and id (recommended) -->
<label for="username">Name:</label>
<input type="text" id="username" name="username">

<!-- Method 2: the label wraps the input -->
<label>
  Name:
  <input type="text" name="username">
</label>

Why labels matter: Clicking a label focuses the connected input element.
Screen readers read labels too, so they are essential for accessibility.


5. select — Dropdown Selection

<label for="city">City of residence:</label>
<select name="city" id="city">
  <option value="">-- Select a city --</option>   <!-- Indicates that nothing is selected by default -->
  <option value="new-york" selected>New York</option>   <!-- selected: the default selection -->
  <option value="los-angeles">Los Angeles</option>
  <option value="chicago">Chicago</option>
  <option value="houston">Houston</option>
</select>

<!-- Grouping with optgroup -->
<select name="job">
  <optgroup label="IT">
    <option value="dev">Developer</option>
    <option value="design">Designer</option>
  </optgroup>
  <optgroup label="General">
    <option value="sales">Sales</option>
    <option value="marketing">Marketing</option>
  </optgroup>
</select>

<!-- multiple: allows several selections (together with the Ctrl/Cmd key) -->
<select name="skills" multiple size="4">
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="js">JavaScript</option>
  <option value="python">Python</option>
</select>

6. textarea — Multi-line Text Input

<label for="message">Message:</label>
<textarea
  id="message"
  name="message"
  rows="5"
  cols="40"
  placeholder="Type your message here..."
  maxlength="500"
></textarea>
<!-- rows: number of rows to display, cols: number of columns to display -->

7. The button Tag

<!-- type="submit": submits the form (default) -->
<button type="submit">Submit</button>

<!-- type="reset": resets the form -->
<button type="reset">Start over</button>

<!-- type="button": a plain button (used together with JavaScript) -->
<button type="button" onclick="alert('Clicked!')">Click</button>

8. fieldset and legend — Grouping a Form

Groups related input elements together.

<form>
  <fieldset>
    <legend>Personal Information</legend>   <!-- the title of the fieldset -->
    <label for="name">Name:</label>
    <input type="text" id="name" name="name"><br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email">
  </fieldset>

  <fieldset>
    <legend>Account Information</legend>
    <label for="pw">Password:</label>
    <input type="password" id="pw" name="password"><br>
    <label for="pw2">Confirm password:</label>
    <input type="password" id="pw2" name="password_confirm">
  </fieldset>

  <button type="submit">Sign up</button>
</form>

9. Validation Attributes

<!-- required: a required field (the form cannot be submitted while it is empty) -->
<input type="text" name="name" required>

<!-- placeholder: hint text shown in gray before the user types -->
<input type="text" name="name" placeholder="John Doe">

<!-- disabled: disabled (cannot be edited or submitted) -->
<input type="text" name="name" disabled>

<!-- readonly: read-only (cannot be edited, but is still submitted) -->
<input type="text" name="name" value="John Doe" readonly>

<!-- minlength, maxlength: minimum/maximum text length -->
<input type="text" name="username" minlength="2" maxlength="20">

<!-- min, max: minimum/maximum numeric value -->
<input type="number" name="age" min="1" max="150">

<!-- pattern: validates the input format with a regular expression -->
<input type="text" name="phone" pattern="[0-9]{3}-[0-9]{4}-[0-9]{4}" placeholder="555-1234-5678">

Summary

Tag/Attribute Description
<form> Form container
action URL the data is sent to
method How the data is sent (get/post)
<input type="text"> Text input
<input type="email"> Email input (format validation)
<input type="password"> Password (masked)
<input type="number"> Number input
<input type="checkbox"> Multiple selection
<input type="radio"> Single selection
<input type="file"> File upload
<input type="date"> Date picker
<select> Dropdown selection
<textarea> Multi-line text
<button> Button
<label> Input label
<fieldset> Form group
<legend> fieldset title
required Required input
placeholder Hint text
disabled Disabled

Next Steps

  • View the example file - Sign-up form example
  • Check the assignment - Build a survey page
  • Next lesson: Semantic HTML

Example files

Complete, runnable files used in this lesson. Copy them into your project and experiment.

signup.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sign Up - Web Development Learning Community</title>
</head>
<body>

  <h1>Web Development Learning Community</h1>
  <h2>Sign Up</h2>

  <p>Complete your sign-up by filling out the form below. (A <span>*</span> marks a required field)</p>

  <!-- form: the container that holds the user's input data -->
  <!-- action: the server URL the form data is sent to (currently an example) -->
  <!-- method="post": sensitive information (passwords, etc.) is sent with POST -->
  <form action="/register" method="post">

    <!-- ============================== -->
    <!-- fieldset 1: basic account info  -->
    <!-- ============================== -->
    <fieldset>
      <!-- fieldset: groups related form elements visually and logically -->
      <legend>Account Information</legend>
      <!-- legend: the title of the fieldset. Placed first inside the fieldset -->

      <!-- Username input -->
      <div>
        <label for="username">Username *</label>
        <!-- label: the description of the input element. The for attribute connects it to the input's id -->
        <!-- Clicking the label moves focus to the connected input -->
        <input
          type="text"
          id="username"
          name="username"
          placeholder="4-20 letters and numbers"
          minlength="4"
          maxlength="20"
          required
          <!-- required: the form cannot be submitted unless this field is filled in -->
        >
      </div>

      <!-- Email input -->
      <div>
        <label for="email">Email *</label>
        <input
          type="email"
          <!-- type="email": automatically validates that the value is an email format including @ -->
          id="email"
          name="email"
          placeholder="[email protected]"
          required
        >
      </div>

      <!-- Password input -->
      <div>
        <label for="password">Password *</label>
        <input
          type="password"
          <!-- type="password": what you type is masked with ••• -->
          id="password"
          name="password"
          placeholder="8 or more characters (letters, numbers, symbols)"
          minlength="8"
          required
        >
      </div>

      <!-- Confirm password -->
      <div>
        <label for="password-confirm">Confirm Password *</label>
        <input
          type="password"
          id="password-confirm"
          name="password_confirm"
          placeholder="Enter your password again"
          minlength="8"
          required
        >
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 2: personal info       -->
    <!-- ============================== -->
    <fieldset>
      <legend>Personal Information</legend>

      <!-- Full name input -->
      <div>
        <label for="fullname">Full Name *</label>
        <input
          type="text"
          id="fullname"
          name="fullname"
          placeholder="Enter your real name"
          required
        >
      </div>

      <!-- Date of birth input -->
      <div>
        <label for="birthday">Date of Birth</label>
        <input
          type="date"
          <!-- type="date": a calendar for picking a date appears -->
          id="birthday"
          name="birthday"
          min="1900-01-01"
          <!-- min: the earliest selectable date -->
          max="2026-12-31"
          <!-- max: the latest selectable date -->
        >
      </div>

      <!-- Age input (number) -->
      <div>
        <label for="age">Age</label>
        <input
          type="number"
          <!-- type="number": only numbers can be entered, with arrow buttons -->
          id="age"
          name="age"
          min="1"
          max="150"
          step="1"
          <!-- step: increment size. With 1, only whole numbers can be entered -->
          placeholder="Age"
        >
      </div>

      <!-- Gender selection (radio buttons) -->
      <div>
        <span>Gender</span>
        <!-- radio: only one can be selected within a group that shares the same name attribute -->
        <input type="radio" id="gender-male" name="gender" value="male">
        <label for="gender-male">Male</label>

        <input type="radio" id="gender-female" name="gender" value="female">
        <label for="gender-female">Female</label>

        <input type="radio" id="gender-other" name="gender" value="other">
        <label for="gender-other">Other</label>

        <input type="radio" id="gender-none" name="gender" value="prefer-not-to-say" checked>
        <!-- checked: selected by default when the page loads -->
        <label for="gender-none">Prefer not to say</label>
      </div>

      <!-- Region of residence (dropdown) -->
      <div>
        <label for="region">Region</label>
        <select id="region" name="region">
        <!-- select: a dropdown selection list -->
          <option value="">-- Select a region --</option>
          <!-- an option with value="" represents the unselected state -->
          <optgroup label="Metro Areas">
          <!-- optgroup: groups related options together -->
            <option value="new-york-city">New York City</option>
            <option value="los-angeles">Los Angeles</option>
            <option value="chicago">Chicago</option>
            <option value="houston">Houston</option>
            <option value="phoenix">Phoenix</option>
            <option value="philadelphia">Philadelphia</option>
            <option value="san-diego">San Diego</option>
          </optgroup>
          <optgroup label="States">
            <option value="california">California</option>
            <option value="texas">Texas</option>
            <option value="florida">Florida</option>
            <option value="new-york">New York</option>
            <option value="illinois">Illinois</option>
            <option value="washington">Washington</option>
            <option value="colorado">Colorado</option>
            <option value="oregon">Oregon</option>
            <option value="arizona">Arizona</option>
          </optgroup>
        </select>
      </div>

      <!-- Phone number input -->
      <div>
        <label for="phone">Phone Number</label>
        <input
          type="tel"
          <!-- type="tel": phone number input. Shows a numeric keypad on mobile -->
          id="phone"
          name="phone"
          placeholder="555-000-0000"
          pattern="[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}"
          <!-- pattern: strictly validates the input format with a regular expression -->
        >
      </div>

      <!-- Profile image upload -->
      <div>
        <label for="profile-img">Profile Photo</label>
        <input
          type="file"
          <!-- type="file": opens a file selection dialog -->
          id="profile-img"
          name="profile_image"
          accept="image/jpeg, image/png, image/gif"
          <!-- accept: specifies the allowed file formats -->
        >
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 3: learning info       -->
    <!-- ============================== -->
    <fieldset>
      <legend>Learning Information</legend>

      <!-- Development experience level (radio) -->
      <div>
        <span>Development Experience Level *</span>
        <input type="radio" id="level-beginner" name="level" value="beginner" checked>
        <label for="level-beginner">Beginner (just starting)</label>

        <input type="radio" id="level-junior" name="level" value="junior">
        <label for="level-junior">Junior (less than 1 year)</label>

        <input type="radio" id="level-mid" name="level" value="mid">
        <label for="level-mid">Intermediate (1-3 years)</label>

        <input type="radio" id="level-senior" name="level" value="senior">
        <label for="level-senior">Advanced (3 years or more)</label>
      </div>

      <!-- Areas of interest (checkboxes - multiple selection) -->
      <div>
        <span>Areas of Interest (multiple selections allowed)</span>
        <!-- checkbox: multiple items can be selected -->
        <input type="checkbox" id="interest-html" name="interest" value="html">
        <label for="interest-html">HTML/CSS</label>

        <input type="checkbox" id="interest-js" name="interest" value="javascript">
        <label for="interest-js">JavaScript</label>

        <input type="checkbox" id="interest-react" name="interest" value="react">
        <label for="interest-react">React</label>

        <input type="checkbox" id="interest-node" name="interest" value="nodejs">
        <label for="interest-node">Node.js</label>

        <input type="checkbox" id="interest-python" name="interest" value="python">
        <label for="interest-python">Python</label>

        <input type="checkbox" id="interest-db" name="interest" value="database">
        <label for="interest-db">Databases</label>
      </div>

      <!-- Planned weekly study hours (range slider) -->
      <div>
        <label for="weekly-hours">Planned study hours per week: <span id="hours-display">10</span> hours</label>
        <input
          type="range"
          <!-- type="range": a slider-style input -->
          id="weekly-hours"
          name="weekly_hours"
          min="1"
          max="40"
          step="1"
          value="10"
          <!-- value: the initial value -->
        >
      </div>

      <!-- Self-introduction (multi-line text) -->
      <div>
        <label for="intro">Self-Introduction</label>
        <textarea
          <!-- textarea: an element for entering multiple lines of text -->
          id="intro"
          name="introduction"
          rows="5"
          <!-- rows: the default number of rows in the text area -->
          cols="40"
          <!-- cols: the default number of columns in the text area -->
          placeholder="Write a short introduction and your learning goals (up to 500 characters)"
          maxlength="500"
        ></textarea>
      </div>

      <!-- Referral code (optional, disabled example) -->
      <div>
        <label for="promo-code">Promo Code (event period has ended)</label>
        <input
          type="text"
          id="promo-code"
          name="promo_code"
          value="Event ended"
          disabled
          <!-- disabled: cannot be edited, and the value is not sent when the form is submitted -->
        >
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 4: terms agreement     -->
    <!-- ============================== -->
    <fieldset>
      <legend>Terms Agreement</legend>

      <div>
        <input type="checkbox" id="agree-terms" name="agree_terms" required>
        <!-- required: when used on a checkbox, the form can only be submitted if it is checked -->
        <label for="agree-terms">
          [Required] I agree to the <a href="/terms" target="_blank">Terms of Service</a>
        </label>
      </div>

      <div>
        <input type="checkbox" id="agree-privacy" name="agree_privacy" required>
        <label for="agree-privacy">
          [Required] I agree to the <a href="/privacy" target="_blank">Privacy Policy</a>
        </label>
      </div>

      <div>
        <input type="checkbox" id="agree-marketing" name="agree_marketing">
        <!-- no required: an optional item -->
        <label for="agree-marketing">
          [Optional] I agree to receive marketing information
        </label>
      </div>

      <!-- Hidden value: not visible to the user, but sent along with the form -->
      <input type="hidden" name="signup_source" value="web">
      <!-- hidden: internal data passed to the server, such as the form's source -->

    </fieldset>

    <!-- ============================== -->
    <!-- button area                     -->
    <!-- ============================== -->
    <div>
      <!-- type="submit": the button that sends the form to the server -->
      <button type="submit">Complete Sign-Up</button>

      <!-- type="reset": the button that resets every input in the form to its initial state -->
      <button type="reset">Start Over</button>
    </div>

  </form>

  <hr>
  <p>Already a member? <a href="/login">Log in</a></p>

</body>
</html>

Assignment

Lesson 05 Assignment — Build a Survey Page

Assignment Goal

Using the various form elements you learned in this lesson,
choose any topic you like and build a survey page with at least 5 questions.


Example Survey Topics (Choose Freely)

  • Club/meetup application form
  • Reading preference survey
  • School lunch menu satisfaction survey
  • Web development learning experience survey
  • Travel plan survey
  • Course registration form

Requirements Checklist

form Tag

  • Use the <form> tag (including the action and method attributes)
  • Use method="post" (because the form contains personal information)

Required input Types (Use at least 5 of the following)

  • type="text" - short-answer text input
  • type="email" - email input (automatic format validation)
  • type="number" - number input
  • type="radio" - single selection
  • type="checkbox" - multiple selection
  • type="date" - date picker
  • type="range" - range slider
  • type="file" - file upload

select and textarea

  • Use at least one <select> dropdown menu
  • Use at least one <textarea> multi-line text input

label and Structure

  • Connect every input element to a <label> (for-id or wrapping)
  • Group related questions with <fieldset> and <legend> (at least 2 groups)

Validation Attributes

  • Use the required attribute in at least 3 places
  • Use the placeholder attribute in at least 2 places
  • Use min, max or minlength, maxlength in at least 1 place

Buttons

  • A type="submit" submit button
  • A type="reset" reset button

Survey Question Guide (At Least 5 Questions)

Use one of the following formats for each question:

Question Type Suitable Input Element
Simple information such as name/email input type="text", type="email"
"Choose one of the following" input type="radio"
"Select all that apply" input type="checkbox"
"Choose from the list" select
"Rate your satisfaction from 1 to 10" input type="range" or type="number"
"Please explain in detail" textarea
"Choose a date" input type="date"
"Attach a file" input type="file"

Hints

Hint 1: Telling radio buttons and checkboxes apart
<!-- radio: only one can be selected in a group (same name = same group) -->
<p>What is your gender?</p>
<input type="radio" id="male" name="gender" value="male">
<label for="male">Male</label>
<input type="radio" id="female" name="gender" value="female">
<label for="female">Female</label>

<!-- checkbox: multiple selections allowed -->
<p>Select all of your favorite foods:</p>
<input type="checkbox" id="food1" name="food" value="pizza">
<label for="food1">Pizza</label>
<input type="checkbox" id="food2" name="food" value="sushi">
<label for="food2">Sushi</label>
<input type="checkbox" id="food3" name="food" value="chicken">
<label for="food3">Chicken</label>
Hint 2: Grouping questions with fieldset
<form action="/survey" method="post">

  <fieldset>
    <legend>Basic Information</legend>
    <!-- name, email, age, etc. -->
  </fieldset>

  <fieldset>
    <legend>Survey Questions</legend>
    <!-- the main survey questions -->
  </fieldset>

  <fieldset>
    <legend>Additional Comments</legend>
    <!-- textarea, etc. -->
  </fieldset>

  <button type="submit">Submit</button>
  <button type="reset">Reset</button>
</form>
Hint 3: Building a dropdown with select
<label for="satisfaction">Overall satisfaction:</label>
<select id="satisfaction" name="satisfaction" required>
  <option value="">-- Select one --</option>
  <option value="5">Very satisfied</option>
  <option value="4">Satisfied</option>
  <option value="3">Neutral</option>
  <option value="2">Dissatisfied</option>
  <option value="1">Very dissatisfied</option>
</select>
Hint 4: Using a range slider
<label for="recommend">Recommendation score (1-10): <output id="recommend-value">5</output></label>
<input
  type="range"
  id="recommend"
  name="recommend_score"
  min="1"
  max="10"
  step="1"
  value="5"
>
<!-- JavaScript is required to display the slider value in real time -->
<!-- It is fine if the number does not update automatically for now -->

File Name

Save it as signup.html.


Grading Criteria

Item Points
form tag (including action, method) 10 points
Using 5 or more input types 25 points
Using select, textarea 10 points
label connections (every input element) 15 points
Using fieldset, legend (2 or more groups) 15 points
Validation attributes such as required, placeholder 10 points
Submit/reset buttons 5 points
Completeness and naturalness of the content 10 points
Total 100 points
Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

signup.htmlHTML
<!DOCTYPE html>
<!-- HTML5 document declaration -->
<html lang="en">
<!-- Sets the document language to English -->
<head>
  <meta charset="UTF-8">
  <!-- UTF-8 encoding so that text is not garbled -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Web Development Learning Experience Survey</title>
</head>
<body>

  <h1>Web Development Learning Experience Survey</h1>
  <!-- h1: the page's main heading -->

  <p>
    This survey is used to understand the experiences of web development learners and to improve the quality of our lessons.<br>
    Time required: about 3-5 minutes / A <strong>*</strong> marks a required field.
  </p>

  <!-- form: the container that collects the user's input data and sends it to the server -->
  <!-- action="/survey": the server URL the form data is sent to -->
  <!-- method="post": the POST method, which does not expose data in the URL. Suitable for forms with personal information -->
  <form action="/survey" method="post">

    <!-- ============================== -->
    <!-- fieldset 1: respondent basic info -->
    <!-- ============================== -->
    <fieldset>
    <!-- fieldset: draws a border around related form elements to group them visually -->
      <legend>Respondent Basic Information</legend>
      <!-- legend: the title of the fieldset. Displayed on the border -->

      <!-- Question 1: name (text input) -->
      <div>
        <label for="name">1. Name (a nickname is fine) *</label>
        <!-- label: the description of the input element. The for value must match the input's id value to be connected -->
        <input
          type="text"
          <!-- type="text": enters general text on a single line -->
          id="name"
          <!-- id: connects to the label's for and is used when referencing the element from JavaScript -->
          name="respondent_name"
          <!-- name: the key name of this input value when it is sent to the server -->
          placeholder="John Doe"
          <!-- placeholder: hint text shown in gray before the user types -->
          required
          <!-- required: the form cannot be submitted if this is left empty (a required field) -->
          maxlength="30"
          <!-- maxlength: the maximum number of characters that can be entered -->
        >
      </div>

      <!-- Question 2: email (email input) -->
      <div>
        <label for="email">2. Email Address *</label>
        <input
          type="email"
          <!-- type="email": automatically validates that the value is an email format including @ -->
          id="email"
          name="email"
          placeholder="[email protected]"
          required
        >
      </div>

      <!-- Question 3: age (number input) -->
      <div>
        <label for="age">3. Age</label>
        <input
          type="number"
          <!-- type="number": only numbers can be entered. Up and down arrow buttons are provided -->
          id="age"
          name="age"
          min="10"
          <!-- min: the minimum value that can be entered -->
          max="100"
          <!-- max: the maximum value that can be entered -->
          step="1"
          <!-- step: the increment when the arrows are clicked (1 allows whole numbers only) -->
          placeholder="25"
        >
      </div>

      <!-- Question 4: learning start date (date input) -->
      <div>
        <label for="start-date">4. Date You Started Learning Web Development</label>
        <input
          type="date"
          <!-- type="date": provides a calendar popup for picking a date -->
          id="start-date"
          name="learning_start_date"
          min="2020-01-01"
          <!-- min: the earliest selectable date -->
        >
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 2: learning status (key questions) -->
    <!-- ============================== -->
    <fieldset>
      <legend>Learning Status</legend>

      <!-- Question 5: development experience level (radio single selection) -->
      <div>
        <span>5. What is your current development experience level? *</span>
        <!-- radio: only one can be selected within a group that shares the same name -->
        <input type="radio" id="level-none" name="level" value="none" required>
        <label for="level-none">None (complete beginner)</label>

        <input type="radio" id="level-beginner" name="level" value="beginner">
        <label for="level-beginner">Beginner (less than 6 months)</label>

        <input type="radio" id="level-junior" name="level" value="junior">
        <label for="level-junior">Junior (6 months to 1 year)</label>

        <input type="radio" id="level-mid" name="level" value="mid">
        <label for="level-mid">Intermediate (1-3 years)</label>

        <input type="radio" id="level-senior" name="level" value="senior">
        <label for="level-senior">Advanced (3 years or more)</label>
      </div>

      <!-- Question 6: main learning languages/technologies (checkbox multiple selection) -->
      <div>
        <span>6. Select all the technologies you are currently studying. (multiple selections allowed)</span>
        <!-- checkbox: several items can be selected at the same time -->
        <input type="checkbox" id="tech-html" name="tech" value="html">
        <label for="tech-html">HTML/CSS</label>

        <input type="checkbox" id="tech-js" name="tech" value="javascript">
        <label for="tech-js">JavaScript</label>

        <input type="checkbox" id="tech-react" name="tech" value="react">
        <label for="tech-react">React</label>

        <input type="checkbox" id="tech-vue" name="tech" value="vue">
        <label for="tech-vue">Vue.js</label>

        <input type="checkbox" id="tech-node" name="tech" value="nodejs">
        <label for="tech-node">Node.js</label>

        <input type="checkbox" id="tech-python" name="tech" value="python">
        <label for="tech-python">Python</label>

        <input type="checkbox" id="tech-java" name="tech" value="java">
        <label for="tech-java">Java</label>

        <input type="checkbox" id="tech-db" name="tech" value="database">
        <label for="tech-db">SQL/Databases</label>
      </div>

      <!-- Question 7: main learning method (select dropdown) -->
      <div>
        <label for="learning-method">7. Which method do you mainly use to learn? *</label>
        <select id="learning-method" name="learning_method" required>
        <!-- select: chooses one item from a dropdown list -->
          <option value="">-- Select one --</option>
          <!-- an option with an empty value is the default display for the unselected state -->
          <optgroup label="Online">
          <!-- optgroup: groups related options -->
            <option value="youtube">Free YouTube courses</option>
            <option value="online-paid">Paid online courses (Udemy, Coursera, etc.)</option>
            <option value="blog">Reading blogs/docs</option>
            <option value="bootcamp">Online bootcamp</option>
          </optgroup>
          <optgroup label="Offline">
            <option value="school">School classes</option>
            <option value="offline-bootcamp">Offline bootcamp</option>
            <option value="study-group">Study group</option>
            <option value="book">Self-study with books</option>
          </optgroup>
          <option value="mix">A mix of several methods</option>
          <option value="other">Other</option>
        </select>
      </div>

      <!-- Question 8: weekly study hours (range slider) -->
      <div>
        <label for="weekly-hours">8. Average study hours per week: <strong id="hours-output">10</strong> hours</label>
        <input
          type="range"
          <!-- type="range": selects a value between the minimum and maximum with a slider -->
          id="weekly-hours"
          name="weekly_hours"
          min="1"
          max="60"
          step="1"
          value="10"
          <!-- value: the slider's initial position value -->
        >
        <span>1 hour</span> ~ <span>60 hours</span>
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 3: satisfaction and feedback -->
    <!-- ============================== -->
    <fieldset>
      <legend>Satisfaction and Feedback</legend>

      <!-- Question 9: satisfaction with the current lesson (radio) -->
      <div>
        <span>9. How satisfied are you with the HTML lesson you are taking? *</span>
        <input type="radio" id="sat-5" name="satisfaction" value="5" required>
        <label for="sat-5">★★★★★ Very satisfied</label>

        <input type="radio" id="sat-4" name="satisfaction" value="4">
        <label for="sat-4">★★★★☆ Satisfied</label>

        <input type="radio" id="sat-3" name="satisfaction" value="3">
        <label for="sat-3">★★★☆☆ Neutral</label>

        <input type="radio" id="sat-2" name="satisfaction" value="2">
        <label for="sat-2">★★☆☆☆ Dissatisfied</label>

        <input type="radio" id="sat-1" name="satisfaction" value="1">
        <label for="sat-1">★☆☆☆☆ Very dissatisfied</label>
      </div>

      <!-- Question 10: areas that need improvement (checkbox multiple selection) -->
      <div>
        <span>10. Select everything that needs improvement in the lesson. (multiple selections allowed)</span>
        <input type="checkbox" id="imp-content" name="improvement" value="content">
        <label for="imp-content">Depth of the lesson content</label>

        <input type="checkbox" id="imp-speed" name="improvement" value="speed">
        <label for="imp-speed">Pace of the lesson</label>

        <input type="checkbox" id="imp-example" name="improvement" value="example">
        <label for="imp-example">Variety of examples</label>

        <input type="checkbox" id="imp-assignment" name="improvement" value="assignment">
        <label for="imp-assignment">Difficulty of the assignment</label>

        <input type="checkbox" id="imp-explanation" name="improvement" value="explanation">
        <label for="imp-explanation">Clarity of the explanations</label>

        <input type="checkbox" id="imp-none" name="improvement" value="none">
        <label for="imp-none">Nothing to improve (satisfied)</label>
      </div>

      <!-- Question 11: attach lesson materials (file upload) -->
      <div>
        <label for="screenshot">11. Attach a screenshot of code you wrote yourself (optional)</label>
        <input
          type="file"
          <!-- type="file": opens a file selection dialog -->
          id="screenshot"
          name="code_screenshot"
          accept="image/*"
          <!-- accept: the allowed file formats. image/* allows any image file -->
        >
      </div>

      <!-- Question 12: free-form feedback (textarea multi-line text) -->
      <div>
        <label for="comment">12. Please leave any free-form feedback about the lesson.</label>
        <textarea
          <!-- textarea: an element for entering multiple lines of text -->
          id="comment"
          name="free_comment"
          rows="6"
          <!-- rows: the default number of rows in the text area (determines the height) -->
          cols="50"
          <!-- cols: the default number of columns in the text area (determines the width) -->
          placeholder="Feel free to write about what was good, what could be improved, or any suggestions. (up to 1,000 characters)"
          maxlength="1000"
          <!-- maxlength: the maximum number of characters that can be entered -->
        ></textarea>
      </div>

    </fieldset>

    <!-- ============================== -->
    <!-- fieldset 4: privacy consent     -->
    <!-- ============================== -->
    <fieldset>
      <legend>Privacy Consent</legend>

      <div>
        <input
          type="checkbox"
          id="agree-privacy"
          name="agree_privacy"
          required
          <!-- required: the form cannot be submitted unless this checkbox is checked -->
        >
        <label for="agree-privacy">
          [Required] The personal information collected is used only to improve lesson quality
          and is destroyed within 6 months after the responses are completed. I agree to this.
        </label>
      </div>

      <!-- hidden: data not visible to the user but sent to the server with the form -->
      <input type="hidden" name="survey_version" value="2026-v1">
      <!-- hidden data that tells the server which version of the survey this is -->
      <input type="hidden" name="survey_type" value="html_course">

    </fieldset>

    <!-- ============================== -->
    <!-- buttons                         -->
    <!-- ============================== -->
    <div>
      <button type="submit">Submit Survey</button>
      <!-- type="submit": the button that sends all of the form's data to the action URL -->

      <button type="reset">Start Over from the Beginning</button>
      <!-- type="reset": resets every input in the form to its initial state (default values) -->
    </div>

    <p>Thank you for taking part in this survey!</p>

  </form>

</body>
</html>

Learn this lesson with a mentor

Work through the Build Your Homepage series on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now