← Back to JavaScript series
πŸ“
DOM
Intermediate Β· Prerequisite: 19_Event_Handling

20. Forms and Inputs

The browser validates inputs for you. You can also check from JavaScript using `form.checkValidity()` or each element's `validity` object.

formsubmitvalidationFormData
Duration
⏱ ~1.5 hours
Level
πŸ“Š Intermediate
Prerequisite
🎯 Lecture 19
OUTCOME
The browser validates inputs for you. You can also check from JavaScript using `form.checkValidity()` or each element's `validity` object.

What you'll learn

  • 1Distinguish input, change, and submit events.
  • 2Use built-in HTML5 validation (required, type, pattern).
  • 3Collect all form values at once with `FormData`.
  • 4Control and validate inputs from JavaScript.
  • 5Use the preventDefault + fetch pattern for submission.

Overview

The browser validates inputs for you. You can also check from JavaScript using `form.checkValidity()` or each element's `validity` object.

Core Concepts

1. input vs change vs submit

  • `input`: every time the value changes (on every keystroke for text)
  • `change`: when the value is committed after focus loss (text), or on each change (select/checkbox)
  • `submit`: when a form is submitted
javascript
form.addEventListener("submit", (e) => {
  e.preventDefault();
  // handle the data
});

2. HTML5 validation

html
<input type="email" required minlength="3" />

The browser validates inputs for you. You can also check from JavaScript using `form.checkValidity()` or each element's `validity` object.

3. FormData

javascript
const data = new FormData(form);
data.get("email");
for (const [k, v] of data) console.log(k, v);

`FormData` also handles file uploads transparently.

4. Controlled inputs

The pattern where JavaScript always owns the value and reflects it back to the input.

javascript
input.addEventListener("input", (e) => {
  state.value = e.target.value.toUpperCase();
  input.value = state.value;
});

5. Submission pattern

javascript
form.addEventListener("submit", async (e) => {
  e.preventDefault();
  if (!form.checkValidity()) {
    form.reportValidity();
    return;
  }
  const data = new FormData(form);
  // Submit with fetch (covered in the next lecture)
});

Examples

FileWhat it covers
index.htmlExample form
01_input_submit.jsinput and submit events
02_validation.jsUsing HTML5 validation
03_formdata.jsUsing FormData
04_controlled.jsJS-controlled values

src/01_input_submit.js

javascript
/**
 * input and submit events.
 */
const form = document.querySelector("#loginForm");
const email = form.querySelector("[name=email]");

email.addEventListener("input", (e) => {
  console.log("typing:", e.target.value);
});

form.addEventListener("submit", (e) => {
  e.preventDefault();
  console.log("form submitted");
});

src/02_validation.js

javascript
/**
 * Use the HTML5 validation API.
 */
const form = document.querySelector("#loginForm");
form.addEventListener("submit", (e) => {
  if (!form.checkValidity()) {
    e.preventDefault();
    form.reportValidity();
    console.log("validation failed");
  } else {
    console.log("validation passed");
  }
});

src/03_formdata.js

javascript
/**
 * Collect all values at once with FormData.
 */
const form = document.querySelector("#loginForm");
form.addEventListener("submit", (e) => {
  e.preventDefault();
  if (!form.checkValidity()) {
    form.reportValidity();
    return;
  }
  const data = new FormData(form);
  for (const [key, value] of data) {
    console.log(`${key} = ${value}`);
  }
});

src/04_controlled.js

javascript
/**
 * JS controls the value (force uppercase).
 */
const username = document.querySelector("[name=username]");
const echo = document.querySelector("#echo");

username.addEventListener("input", (e) => {
  const upper = e.target.value.toUpperCase();
  e.target.value = upper;
  echo.textContent = `current value: ${upper}`;
});

src/index.html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Forms and inputs</title>
  </head>
  <body>
    <form id="loginForm">
      <label>Email <input type="email" name="email" required /></label>
      <label>Password <input type="password" name="password" required minlength="4" /></label>
      <label>Name <input type="text" name="username" /></label>
      <label><input type="checkbox" name="remember" /> Keep me logged in</label>
      <button type="submit">Submit</button>
    </form>
    <p id="echo"></p>

    <script src="01_input_submit.js"></script>
    <script src="02_validation.js"></script>
    <script src="03_formdata.js"></script>
    <script src="04_controlled.js"></script>
  </body>
</html>

Common Mistakes

  1. Forgetting `preventDefault` in `submit` and getting a page reload.
  2. Reading `e.value` instead of `e.target.value`.
  3. Mixing up `.checked` (checkbox) and `.value` (text).
  4. Forgetting to give inputs a `name` and getting nothing back from FormData.
  5. Trying to enforce domain rules (like password matching) with HTML5 alone.

FAQ

Q1. checkValidity vs reportValidity?

`checkValidity` only checks; `reportValidity` also shows a message to the user when invalid.

Q2. Are controlled inputs always best?

They have a rendering cost on every keystroke β€” only use them when needed.

Q3. Can file inputs use FormData?

Yes β€” encoding is automatically `multipart/form-data`.

Practice

Build an email + password form. On submit, dump the values via FormData. Block empty submissions.

homework/README.md

Build a form with email and password fields:

  1. Block the default reload on submit.
  2. Collect values via FormData and log them.
  3. Block submission when any field is empty.

See `answer/homework_01.html` and `answer/homework_01.js`.

homework/answer/homework_01.html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Homework 20-1</title>
  </head>
  <body>
    <form id="login">
      <label>Email <input type="email" name="email" required /></label>
      <label>Password <input type="password" name="password" required /></label>
      <button type="submit">Log in</button>
    </form>
    <script src="homework_01.js"></script>
  </body>
</html>

homework/answer/homework_01.js

javascript
/**
 * Dump form values via FormData on submit.
 */
const form = document.querySelector("#login");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  if (!form.checkValidity()) {
    form.reportValidity();
    return;
  }
  const data = new FormData(form);
  for (const [key, value] of data) {
    console.log(`${key}: ${value}`);
  }
});

Next Lecture

[21_Fetch_and_JSON](../../06_λΈŒλΌμš°μ €_API/21_Fetch와_JSON/) β€” Talking to a server.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub β†—