Frontend Master

JavaScript Curriculum

Forms with JavaScript
+60 XP

Forms with JavaScript

medium
~30 min·60 XP

The coffee shop contact form was submitting to nowhere and reloading the page. The order form had no validation. JavaScript takes over — intercept every submit, validate every field, and send data without a page reload.

Forms with JavaScript

Forms are the backbone of user interaction. JavaScript intercepts submissions, validates inputs live, reads all values at once, and sends data without page reloads.

Form Events

Five events cover every form interaction — knowing which to use for each situation matters:

form-events.js

Fires when the form is submitted — button click or Enter key in a text field. Always call preventDefault() to stop the page reload.

form.addEventListener('submit', (e) => {
  e.preventDefault()  // stop page reload
  const data = new FormData(e.target)
  console.log(data.get('email'))  // field by name
  console.log(Object.fromEntries(data)) // all fields
})
💡 Tip: Access all field values at once with new FormData(form). No need to querySelector each input.
💡validate on blur, not on input
Showing errors as the user types feels aggressive. Attach validation to the `blur` event — validate when they leave a field. Show success (green border) on `input` once the field is valid. This gives instant positive feedback without penalising partial input.

Live Validation — In Action

A real form with blur validation, live error messages, and a submit guard:

live-validation.js
ℹ️FormData is the cleanest way to read form values
Instead of querySelector-ing every input individually, pass the form element to `new FormData(form)`. It reads all named fields at once. Convert to a plain object with `Object.fromEntries(data)`. Works for text, email, select, checkbox, file — everything.

FormData Inspector

See exactly what FormData gives you — and how to convert it for JSON APIs:

formdata-inspector.js
Edit form fields
name
email
category
vegan
message
data.get('name')  →  "Jordan Lee"
data.get('email')  →  "jordan@example.com"
data.get('category')  →  "coffee"
data.get('vegan')  →  "true"
data.get('message')  →  "Looking forward to your cold brew!"
form.addEventListener('submit', (e) => {
  e.preventDefault()
  const data = new FormData(e.target)
  // Read individual fields:
  data.get('name')
  // Convert to plain object:
  Object.fromEntries(data)
})
⚠️Inputs must have a name attribute
FormData only picks up fields with a `name` attribute. `<input type="text" name="email">` works. `<input type="text" id="email">` alone does NOT appear in FormData. Always add `name` to every form field.

Your Challenge

Build the contact form. On submit: call e.preventDefault(), create new FormData(e.target), validate name (min 2 chars) and email (contains @). If valid, log Object.fromEntries(data) and call form.reset(). If invalid, add .error class to the relevant .form-group.

Challenge

Build a contact form with name, email, and message fields. Validate each field on blur. On submit: preventDefault, build a FormData object, validate all fields, and if valid log Object.fromEntries(data) to the console.

submitinputchangefocusblurFormDatapreventDefaultform-validationform.resete.target.elements
Forms with JavaScript | Nexus Learn