A
AiTechWorlds
AiTechWorlds
Forms are how users send data to your application. JavaScript lets you validate input before submission, build rich interactive forms, and handle submission without page reloads.
const form = document.querySelector("#signup-form");
const email = document.querySelector("#email");
// Read individual values
email.value; // current text
email.type; // "email"
email.name; // "email" (name attribute)
email.placeholder; // "Enter your email"
email.required; // true/false
email.disabled; // true/false
// Checkboxes and radio buttons use .checked
document.querySelector("#terms").checked; // true/false
// Select elements
const select = document.querySelector("#country");
select.value; // selected value
select.selectedIndex; // index of selected option
select.options[select.selectedIndex].text; // display text
// Multiple select
const langs = document.querySelector("#languages[multiple]");
const selected = [...langs.options].filter(o => o.selected).map(o => o.value);
// Collect all form fields at once
form.addEventListener("submit", (e) => {
e.preventDefault();
const data = new FormData(form);
data.get("email"); // "alice@example.com"
data.get("username"); // "alice"
data.has("newsletter"); // true if checkbox was checked
// Convert to plain object
const obj = Object.fromEntries(data);
// { email: "alice@...", username: "alice", ... }
// For checkboxes that might be unchecked (not included in FormData):
const withDefaults = {
...Object.fromEntries(data),
newsletter: data.has("newsletter") // explicit boolean
};
});
Browser-built-in validation is fast and accessible — use it before adding JavaScript:
<input type="email" required>
<input type="password" minlength="8" maxlength="50">
<input type="text" pattern="[A-Za-z0-9]+" title="Letters and numbers only">
<input type="number" min="0" max="100" step="5">
<input type="url" required>
// Check validity programmatically
const input = document.querySelector("#username");
input.validity.valid; // overall valid/invalid
input.validity.valueMissing; // required but empty
input.validity.tooShort; // shorter than minlength
input.validity.tooLong; // longer than maxlength
input.validity.patternMismatch; // doesn't match pattern
input.validity.typeMismatch; // wrong type (e.g., "abc" in email field)
input.validationMessage; // browser's error message
// Set a custom validation message
input.setCustomValidity("Username is already taken");
input.reportValidity(); // show the message
// Clear custom validity
input.setCustomValidity("");
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function validatePassword(password) {
const errors = [];
if (password.length < 8) errors.push("Must be at least 8 characters");
if (!/[A-Z]/.test(password)) errors.push("Must contain uppercase letter");
if (!/[0-9]/.test(password)) errors.push("Must contain a number");
return errors;
}
function showError(input, message) {
const group = input.closest(".form-group");
const error = group.querySelector(".error-msg") || document.createElement("p");
error.className = "error-msg";
error.textContent = message;
error.style.color = "red";
if (!group.querySelector(".error-msg")) group.appendChild(error);
input.classList.add("error");
}
function clearError(input) {
const group = input.closest(".form-group");
group.querySelector(".error-msg")?.remove();
input.classList.remove("error");
}
const form = document.querySelector("#signup-form");
// Real-time validation as user types
form.querySelectorAll("input").forEach(input => {
input.addEventListener("blur", () => validateField(input));
input.addEventListener("input", () => clearError(input));
});
function validateField(input) {
const value = input.value.trim();
switch (input.name) {
case "username":
if (!value) return showError(input, "Username is required");
if (value.length < 3) return showError(input, "Must be at least 3 characters");
if (!/^[a-z0-9_]+$/i.test(value)) return showError(input, "Letters, numbers, underscores only");
break;
case "email":
if (!value) return showError(input, "Email is required");
if (!validateEmail(value)) return showError(input, "Enter a valid email");
break;
case "password":
if (!value) return showError(input, "Password is required");
const errors = validatePassword(value);
if (errors.length) return showError(input, errors[0]);
break;
case "confirm-password":
const password = form.querySelector("[name='password']").value;
if (value !== password) return showError(input, "Passwords must match");
break;
}
clearError(input);
return true;
}
form.addEventListener("submit", async (e) => {
e.preventDefault();
// Validate all fields
const inputs = [...form.querySelectorAll("input")];
const allValid = inputs.every(input => validateField(input));
if (!allValid) return;
// Submit
const submitBtn = form.querySelector("[type='submit']");
submitBtn.disabled = true;
submitBtn.textContent = "Creating account...";
try {
const data = Object.fromEntries(new FormData(form));
const res = await fetch("/api/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
if (!res.ok) {
const { message } = await res.json();
throw new Error(message);
}
form.innerHTML = `<p class="success">Account created! <a href="/login">Sign in</a></p>`;
} catch (err) {
showError(form, err.message);
} finally {
submitBtn.disabled = false;
submitBtn.textContent = "Create Account";
}
});
const fileInput = document.querySelector("#avatar");
fileInput.addEventListener("change", (e) => {
const file = e.target.files[0]; // FileList
if (!file) return;
// Validate
if (!file.type.startsWith("image/")) {
alert("Please select an image");
return;
}
if (file.size > 5 * 1024 * 1024) {
alert("Image must be under 5MB");
return;
}
// Preview
const reader = new FileReader();
reader.onload = (e) => {
document.querySelector("#preview").src = e.target.result;
};
reader.readAsDataURL(file);
// Upload with FormData
const formData = new FormData();
formData.append("avatar", file);
fetch("/api/upload", { method: "POST", body: formData });
});
Next lesson: Local Storage & Session Storage — persisting data in the browser.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises