What you'll learn
A form is an accessible data-and-interaction contract. JavaScript enhances it with domain validation and async feedback while preserving native semantics.
By the end of this lesson, you'll be able to:
- Read forms with FormData
- Combine native and custom validation
- Report errors accessibly
Core mental model
Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.
| Concept | What it means | Decision rule |
|---|---|---|
| Constraint validation | Browser checks required, type, range, and pattern rules | Express simple constraints in HTML first |
| FormData | Successful controls serialized as key-value pairs | Use instead of manual field scraping |
| Server validation | Trusted boundary validates every request | Never treat client validation as security |
Professional workflow
Build the behavior in small, observable steps. Each step should leave something you can inspect or test.
- Describe the form submission boundary: inputs, outputs, state, timing, and expected failures.
- Implement the smallest correct path with names that expose intent.
- Add edge cases and failure handling before introducing abstractions.
- Verify behavior with realistic data and one deliberately adversarial example.
- Refactor only after the observable behavior is protected.
Make behavior observable
Guided code lab
Validate a password confirmation
Custom validity integrates a domain rule with the browser's normal reporting.
const form = document.querySelector("#signup");
const password = form.elements.password;
const confirmation = form.elements.confirmation;
confirmation.addEventListener("input", () => {
confirmation.setCustomValidity(
confirmation.value === password.value ? "" : "Passwords must match",
);
});Serialize a valid submission
The submitter checks the whole form before creating a data object.
form.addEventListener("submit", event => {
event.preventDefault();
if (!form.reportValidity()) return;
const data = Object.fromEntries(new FormData(form));
console.log(data.email);
});Production practice
Contract
Keep the form submission API explicit: accepted state, emitted events, DOM ownership, and cleanup.
Verification
Test with keyboard input, missing elements, repeated initialization, and teardown—not only a mouse happy path.
Operations
Measure user-visible latency and remove listeners, observers, object URLs, or media tracks when the feature ends.
Common failure mode
Independent workshop
Build an accessible registration form with synchronous and simulated server errors.
Your finished workshop must include:
- Native HTML constraints
- One cross-field custom rule
- Focus and text feedback for invalid submission
Definition of done
Recap & quick check
Key takeaways
- Start with semantic form controls
- FormData follows browser submission rules
- Client checks improve UX
- The server remains the authority
Quick check
1. What does FormData collect?
2. Where must security validation occur?
3. What clears a custom validity error?
Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.