← JS Mastery | Module 5: DOM Manipulation Forms, Validation & User Input
Module 5

Forms, Validation & User Input

⏱ 22 min read ● Intermediate 🆓 Free

Reading Form Data

// Basic form handling:
const form = document.querySelector("#signup-form");

form.addEventListener("submit", (e) => {
  e.preventDefault();  // stop page refresh!
  
  // Method 1: individual element access
  const name = document.querySelector("#name").value;
  const email = document.querySelector("#email").value;
  
  // Method 2: FormData API (best for complex forms)
  const data = new FormData(form);
  const name = data.get("name");         // single value
  const interests = data.getAll("interest"); // multiple checkboxes
  
  // Convert to plain object:
  const obj = Object.fromEntries(data.entries());
  console.log(obj);  // { name: "Alice", email: "alice@example.com" }
  
  // Method 3: Named access (old but simple)
  const name = form.elements["name"].value;
  const name2 = form.name.value;
});

// Handling different input types:
const textInput = document.querySelector('input[type="text"]');
textInput.value;       // current value (string)
textInput.focus();     // focus the input
textInput.select();    // select all text
textInput.setSelectionRange(0, 5);  // select specific range

const checkbox = document.querySelector('input[type="checkbox"]');
checkbox.checked;      // boolean — true if checked

const radioGroup = document.querySelectorAll('input[name="gender"]');
const selectedRadio = [...radioGroup].find(r => r.checked)?.value;

const select = document.querySelector("select");
select.value;          // selected option value
select.selectedIndex;  // index of selected option
select.multiple;       // true for multi-select

Form Validation

// HTML5 built-in validation (use this first!):
// 
// 
// 
// 

// checkValidity() — check HTML5 validation:
const input = document.querySelector("#email");
input.checkValidity();         // true/false
input.validationMessage;       // built-in error message

// Custom validation with setCustomValidity:
input.addEventListener("input", () => {
  if (input.value.includes("+")) {
    input.setCustomValidity("Plus signs not allowed in email");
  } else {
    input.setCustomValidity("");  // clear error
  }
});

// Manual validation function:
function validateEmail(email) {
  const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return re.test(email);
}

function validatePassword(password) {
  return {
    length: password.length >= 8,
    uppercase: /[A-Z]/.test(password),
    lowercase: /[a-z]/.test(password),
    number: /[0-9]/.test(password),
    special: /[!@#$%^&*]/.test(password)
  };
}

// Real-time validation feedback:
const emailInput = document.querySelector("#email");
const emailError = document.querySelector("#email-error");

emailInput.addEventListener("blur", () => {
  if (!validateEmail(emailInput.value)) {
    emailError.textContent = "Please enter a valid email";
    emailInput.classList.add("invalid");
  } else {
    emailError.textContent = "";
    emailInput.classList.remove("invalid");
  }
});

Real-Time Input Features

// Live character counter:
const textarea = document.querySelector("#message");
const counter = document.querySelector("#char-count");
const MAX = 280;

textarea.addEventListener("input", () => {
  const remaining = MAX - textarea.value.length;
  counter.textContent = remaining;
  counter.className = remaining < 20 ? "warning" : "normal";
});

// Debounced search (don't fire on every keystroke):
function debounce(fn, delay) {
  let timeout;
  return (...args) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn(...args), delay);
  };
}

const searchInput = document.querySelector("#search");
const search = debounce(async (query) => {
  if (query.length < 2) return;
  const results = await fetchSearchResults(query);
  displayResults(results);
}, 300);

searchInput.addEventListener("input", (e) => search(e.target.value));

// Auto-resize textarea:
textarea.addEventListener("input", function() {
  this.style.height = "auto";
  this.style.height = this.scrollHeight + "px";
});

⚡ Key Takeaways

🎯 Practice Exercises

EXERCISE 1

Build a registration form with: name, email, password, confirm password. Validate all fields in real-time and show/hide error messages. Disable submit until all fields are valid.

EXERCISE 2 — CHALLENGE

Create a multi-step form wizard: 3 steps, each with Next/Back buttons, validation before advancing, and a summary view at the end before final submission.

← DOM Manipulation