JavaScript DOM Forms

Read Values, Handle Submits, Send `FormData`

JavaScript DOM Forms

Forms are how users send data into your app. Learn to read values, intercept submits, and use the `FormData` API.

5 min read Level 2/5 #DOM#forms#FormData
What you'll learn
  • Read input values and handle changes
  • Intercept `submit` and validate inline
  • Use `FormData` to grab everything at once

A form is just an HTML element wrapping inputs. JavaScript reads values via the inputs’ .value, listens for submit on the form, and (most of the time) prevents the default navigation so you can send the data with fetch.

Reading One Input

Read a single field script.js
const name = document.querySelector("input[name='name']");
console.log(name.value);          // current value

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

The input event fires on every keystroke; change fires once when focus leaves.

Submit Once, Grab Everything

The clean pattern is one submit listener that reads all fields.

Intercept submit, log values script.js
const form = document.querySelector("form");

form.addEventListener("submit", e => {
  e.preventDefault();
  const data = new FormData(form);
  for (const [key, value] of data) {
    console.log(key, "=", value);
  }
});
▶ Preview: console

FormData reads every [name]’d input in the form. It iterates as [name, value] pairs.

To a Plain Object

FormData → plain object script.js
const form = document.querySelector("form");
form.addEventListener("submit", e => {
  e.preventDefault();
  const obj = Object.fromEntries(new FormData(form));
  console.log(obj);   // { name: "Ada", email: "ada@…" }
});
▶ Preview: console

Send It With fetch

You can pass a FormData straight to fetch’s body. The browser sets the right Content-Type for you.

form.addEventListener("submit", async e => {
  e.preventDefault();
  const res = await fetch("/api/signup", {
    method: "POST",
    body: new FormData(form),
  });
  if (!res.ok) console.log("failed");
});

For a JSON API, build the object yourself and stringify:

const body = JSON.stringify(Object.fromEntries(new FormData(form)));
fetch("/api/signup", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body,
});

Inline Validation

Inputs have a validity object the browser fills in based on type, required, pattern, min, max, etc. You can show a custom message:

Custom validation message script.js
const email = document.querySelector("input[type='email']");

email.addEventListener("input", () => {
  if (!email.validity.valid) {
    email.setCustomValidity("Hmm, that doesn't look like an email.");
  } else {
    email.setCustomValidity("");   // clear it
  }
});
▶ Preview: console

Checkboxes, Radios, Selects

ControlRead with…
<input> text/number/emailel.value (always a string)
<input type="checkbox">el.checked (boolean)
<input type="radio">The checked one’s .value (or formData.get(name))
<select>el.value (the selected option’s value)
<select multiple>[...el.selectedOptions].map(o => o.value)
<textarea>el.value

Up Next

Most APIs trade JSON. Time to learn how to parse and serialize it.

JavaScript JSON →