JavaScript course · Part 8: Projects · lab 10 of 11
Project: a quote calculator that works
Build one real feature end to end: a live total as people type, validation that explains itself, a saved draft, and a submission with loading and error states.
By the end you can
- Update a total as the visitor types, without reloading anything
- Validate at the edge and explain what is wrong, out loud
- Keep a draft so a half-filled form survives a refresh
- Submit with a loading state, a failure state and no double sends
Easier if you did first
step 1 of 4
A total that updates as they type
The HTML and CSS are done. Everything from here is behaviour.
The rule for the whole project: one function works out the total from the current values, and one function puts it on screen. Everything else calls those two. Mixing the arithmetic into the event handlers is how a feature becomes impossible to change.
The calculation is pure, in the sense from the structure lab: give it the inputs and it returns a number, touching nothing. That means you can check it without clicking anything.
Listen for the input event rather than change. input fires on every keystroke and on the arrows of a number field; change waits until the field loses focus, which makes the total feel broken.
Remember that every value from a form is text, so convert before any arithmetic.
Make the total update live.
const RATE = { buffet: 45, plated: 80, finger: 25 };
function quoteFor(guests, menu) {
return guests * (RATE[menu] ?? 0);
}
function render() {
const guests = Number(form.guests.value);
total.textContent = `GHS ${quoteFor(guests, form.menu.value)}`;
}
form.addEventListener("input", render);What these words mean
- input event
- Fires on every keystroke. The one to use for a live total.
- change event
- Fires when the field loses focus. Too late for live feedback.
- pure calculation
- A function that only works out a number from its arguments.
- render
- One function that puts the current state on screen.
Easy to get wrong
Doing the arithmetic inside the event handler
A separate function that takes the values and returns a number
Logic trapped in a handler can only be tested by clicking, and the day you need the same total on the server, you have to write it again.
Listening for change
Listening for input
With change the total does not move while someone types, so they assume it is broken and tab away to check.
What we check
- The calculation is right
- An unknown menu gives 0 rather than NaN
- The total is correct as soon as the page loads
- Typing a new guest count updates the total live
- Changing the menu updates it too
- You listened for input, not change