7.6 — Forms & user input
You've wired listeners (7.4) and mastered delegation (7.5). Today's target is the #1 thing every automation script touches: forms — reading what a human typed, checking it's actually usable, and deciding what happens next.
One habit runs through the whole lesson: READ the field, VALIDATE it, then ACT — never skip a step, and never act on data you haven't checked.
const form = document.querySelector("form");
const nameInput = document.querySelector("#name");
const subscribe = document.querySelector("#subscribe");
form.addEventListener("submit", (event) => {
event.preventDefault();
const name = nameInput.value.trim();
if (name === "") {
console.log("error: name is required");
return;
}
console.log("submitting: " + name + ", subscribed: " + subscribe.checked);
});nameInput.value reads whatever text currently sits in the field — always a plain string, even if the input type is "number".
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
The browser has its OWN built-in validation too — attributes like required, type="email", minlength block a submit before your JS even runs, and input.checkValidity() asks it directly.
Real apps almost always also validate in JS, for custom error messages and cross-field rules the browser can't express (like matching passwords).
Precision worth remembering: value is ALWAYS a string, even for <input type="number">. Need to compute with it? Read input.valueAsNumber, or convert yourself with Number(input.value) — a forgotten conversion is a classic silent bug (string concatenation instead of addition).
Job note: every one of Playwright's form actions — fill, check, uncheck, selectOption — is just setting the property and dispatching the event you read today. There is nothing more exotic underneath; that's why this lesson transfers directly.
⌨️ the read → validate → act flow
Model a form submit handler as a plain function — no real DOM needed to feel the shape every form follows.
requirements:
- A function
trySubmit(formState), whereformStatelooks like{ name: " ", subscribed: true }. - Inside: trim the name. If it’s empty, RETURN the string
"error: name is required"immediately. - Otherwise, return
"submitting: " + name + ", subscribed: " + subscribed. Call it once with an all-space name (print the result), then once with"Vasavi"andsubscribed: false(print that result too).
when you press RUN, the console must show exactly:
✏️ Quick check 1
A number input holds "42". Type the JavaScript TYPE that input.value always is, regardless of what was typed:
✏️ Quick check 2
Does a form’s DEFAULT submit behavior reload the page? Type yes or no.
✏️ Quick check 3
checkbox.checked is true. Type exactly what console.log(subscribe.checked) prints:
🗣️ Now teach it back
Explain to a friend the whole path from a human typing in a form to your code deciding what to do: reading value/checked, why preventDefault matters on submit, and where validation fits in that order.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.