Skip to main content

Forms are everywhere

Every web app has forms — login, signup, search, settings, creating content. In vanilla JavaScript, you handle forms by listening for the submit event, reading input values, and sending data to your backend.

Getting form values

Individual input values

Different input types

Input values are always strings, even from <input type="number">. Convert them with Number() when you need a number. The checked property on checkboxes is a boolean.

FormData — read all values at once

FormData collects all named inputs in a form into a single object:
Object.fromEntries(new FormData(form)) is the cleanest way to get all form values as a plain object. It requires each input to have a name attribute.

Handling form submission

The standard pattern: listen for submit, prevent the default page reload, read values, and send to your API.
e.preventDefault() is required. Without it, the browser submits the form the old-fashioned way — a full page reload with form data in the URL. You’ll lose your application state. This is the most common form handling mistake.

Real-time input handling

The input event — fires on every keystroke

The change event — fires when input loses focus

Basic validation

HTML validation attributes

The browser has built-in validation. Use HTML attributes first:
The browser shows error messages automatically. The form won’t submit until all validations pass.

JavaScript validation

For more complex rules, validate in your submit handler:

Disabling the submit button

Common mistakes

Without e.preventDefault(), the browser handles the form submission itself — reloading the page and appending form data to the URL. Your JavaScript fetch never completes.
FormData uses the name attribute, not id. If your inputs don’t have name, Object.fromEntries(new FormData(form)) will return an empty object.

What’s next?

You can handle forms and user input. Let’s wrap up the DOM & Browser section with localStorage — persisting data between page loads.

Local storage

Persist data in the browser between page loads