Loading...
Loading...
Collect and validate user input. The most common interactive pattern on the web.
The Document Object Model is how JavaScript reads and changes web pages. Selecting elements, modifying content, handling events, validating forms, and persisting data in storage are the core skills of frontend development.
Learn Forms & Validation in JavaScript — covering Form Basics, Reading Values, FormData API, Validation with interactive visual examples and step-by-step explanations.
JavaScript in the browser is all about the DOM — the live tree of HTML elements your code can select, modify, and respond to. Click handlers, form validation, dynamic content updates, and local storage all build on DOM APIs.
This module takes you from querySelector to full user interaction patterns. You will learn event delegation, form handling, and how to persist state in localStorage — the skills every frontend developer uses daily.
Understanding forms & validation is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
Handle form submission with JavaScript.
// HTML: // <form id="signup"> // <input name="email" type="email" required> // <input name="password" type="password" required> // <button type="submit">Sign Up</button> // </form> const form = document.getElementById("signup"); form.addEventListener("submit", (e) => { e.preventDefault(); // stop page reload! // Get values: const email = form.elements.email.value; const password = form.elements.password.value; // Do something: console.log("Signing up:", email); });
💡 Always call e.preventDefault() in the submit handler — otherwise the browser reloads the page (default form behavior).
Get data from different input types.
// Text, email, password, number: input.value; // string (always a string!) Number(input.value); // convert to number // Checkbox: checkbox.checked; // true/false // Radio buttons: const selected = form.querySelector('input[name="color"]:checked'); selected?.value; // value of selected radio // Select (dropdown): select.value; // selected option's value select.selectedIndex; // index of selected option select.options[select.selectedIndex].text; // display text // Multiple select: const selected = [...select.selectedOptions].map(o => o.value); // Textarea: textarea.value; // text content // File input: fileInput.files; // FileList fileInput.files[0]; // first File object
Get all form values at once — the modern way.
form.addEventListener("submit", (e) => { e.preventDefault(); // Grab ALL form values in one line: const formData = new FormData(form); // Read individual fields: formData.get("email"); // "user@test.com" formData.get("password"); // "secret123" // Convert to a plain object: const data = Object.fromEntries(formData); // { email: "user@test.com", password: "secret123" } // Send to API: fetch("/api/signup", { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json" } }); });
// FormData methods: formData.get("field"); // get value formData.getAll("tags"); // get all values (multi-select) formData.has("field"); // check if exists formData.set("field", "new value"); // set/overwrite formData.append("tags", "new"); // add another value formData.delete("field"); // remove // Iterate all entries: for (const [key, value] of formData) { console.log(key, value); } // Send FormData directly (for file uploads): fetch("/api/upload", { method: "POST", body: formData, // Content-Type set automatically! });
Built-in HTML validation + Constraint Validation API.
// HTML validation attributes: // <input type="email" required> // <input type="number" min="0" max="100"> // <input minlength="8" maxlength="50"> // <input pattern="[A-Za-z]{3,}"> // Check validity with JavaScript: const input = document.querySelector("input"); input.validity.valid; // true/false (overall) input.validity.valueMissing; // true if required + empty input.validity.typeMismatch; // true if wrong type (email) input.validity.tooShort; // true if < minlength input.validity.tooLong; // true if > maxlength input.validity.patternMismatch; // true if doesn't match pattern input.validity.rangeUnderflow; // true if < min input.validity.rangeOverflow; // true if > max // Check entire form: form.checkValidity(); // true if all fields valid form.reportValidity(); // show validation UI
Build your own validation logic.
// Custom validation messages: const email = document.querySelector("#email"); email.addEventListener("input", () => { if (email.validity.typeMismatch) { email.setCustomValidity("Please enter a valid email"); } else { email.setCustomValidity(""); // clear = valid } }); // Full custom validation pattern: form.addEventListener("submit", (e) => { e.preventDefault(); const errors = validateForm(form); if (errors.length > 0) { showErrors(errors); return; } submitForm(form); }); function validateForm(form) { const errors = []; const data = Object.fromEntries(new FormData(form)); if (!data.email.includes("@")) { errors.push({ field: "email", message: "Invalid email" }); } if (data.password.length < 8) { errors.push({ field: "password", message: "Min 8 characters" }); } if (data.password !== data.confirmPassword) { errors.push({ field: "confirmPassword", message: "Passwords don't match" }); } return errors; }
// Real-time validation (as user types): const passwordInput = document.querySelector("#password"); const feedback = document.querySelector("#password-feedback"); passwordInput.addEventListener("input", () => { const val = passwordInput.value; const checks = [ { test: val.length >= 8, msg: "8+ characters" }, { test: /[A-Z]/.test(val), msg: "Uppercase letter" }, { test: /[0-9]/.test(val), msg: "Number" }, { test: /[^A-Za-z0-9]/.test(val), msg: "Special character" }, ]; feedback.innerHTML = checks .map(c => `<span class="${c.test ? 'valid' : 'invalid'}">${c.msg}</span>`) .join(""); });
Common questions about forms & validation.