MGU Computer Science Series — Web Development: HTML, CSS, and JavaScript
Part IV: JavaScript: Interaction and Logic
Variables · Functions · Events · DOM · Forms
Chapter 24 of 30
24
MGU Computer Science Series  ·  Web Development: HTML, CSS, and JavaScript  ·  Library Textbook Edition

Chapter 24:
Forms, Validation, and
User Feedback

Reading form values, validating user input, showing error and success messages, preventing submission, and giving every user clear, accessible feedback

■ Part IV of VII ■

■ 10 Sections  •  Chapter 24 of 30 ■

Builds on Chapters 19–23 — JavaScript basics, events, and the DOM are assumed

Chapter Introduction and Learning Objectives

A form is a promise. It tells a visitor: type something here, and the page will do something useful with it. Every contact form, sign-up form, search box, and comment field makes this same quiet promise. But a form that accepts input without ever responding to it breaks that promise. If a user leaves a required field empty, types an email address with no "@" symbol, or clicks submit and nothing visibly happens, the form has failed — not because the HTML was wrong, but because the user was never told what was happening.

This chapter teaches you how JavaScript closes that gap. You will learn how to read the values a user has typed or selected, how to check those values against simple rules, how to show clear error messages when something is wrong, how to show success messages when everything checks out, and how to stop a form from submitting until it is ready. You will also learn that good feedback is not only visual — it must reach users who rely on screen readers and keyboards, and it must never assume that raw user input is automatically safe to display. By the end of the chapter, you will be able to build a small but genuinely usable validated form, the kind found throughout the real web.

Opening Question

Imagine two versions of the same sign-up form. In Version A, a user leaves the email field empty, clicks "Submit," and the page does nothing at all — no message, no color change, no sound. In Version B, the same action instantly produces a message next to the email field: "Please enter your email address." Both forms have identical HTML. What makes Version B work and Version A fail? The answer is feedback — and feedback, on the modern web, is built with JavaScript. This chapter shows you how.

10Sections
12Objectives
16Key Terms
30Total Chapters

Learning Objectives

By the end of this chapter, you should be able to:

  1. 1Explain why forms need JavaScript-driven feedback beyond what plain HTML provides on its own.
  2. 2Read values from text inputs, checkboxes, radio buttons, and select menus using JavaScript.
  3. 3Check whether a required field has been left empty and respond accordingly.
  4. 4Write simple validation rules for length, format, matching fields, and numeric range.
  5. 5Distinguish between built-in HTML validation attributes and custom JavaScript validation logic.
  6. 6Display a clear, specific error message next to the field that caused it.
  7. 7Display a success message after a form passes all validation checks.
  8. 8Use event.preventDefault() to stop a form from submitting when validation fails.
  9. 9Explain why client-side validation improves user experience but does not replace server-side validation.
  10. 10Connect form feedback to accessibility using aria-live regions, aria-describedby, and aria-invalid.
  11. 11Explain the risk of inserting raw user input into the page and describe a safer alternative.
  12. 12Test a validated form systematically using valid input, invalid input, and edge cases.

Sections at a Glance

Sections 24.1 – 24.3
The Problem: Why Forms Need Feedback, and How to Read Them
User Experience · Reading Values · Required Fields

Why Forms Need Feedback

A form is one of the few places on a website where the conversation runs both ways. Most of a web page simply presents information to a visitor. A form asks the visitor a question — a name, an email address, a message — and waits for an answer. Like any conversation, it goes wrong quickly if one side stops responding.

Consider what happens when a form gives no feedback at all. A user fills in three of four fields, forgets the fourth, and clicks "Submit." If nothing happens — no message appears, no field is highlighted, the page simply sits there — the user has no way to know what went wrong, or even that anything went wrong. They may click again. They may give up. They may assume the website is broken.

Feedback is any information returned to a user about the state of their action. Good forms give feedback at several moments: while the user is typing, immediately after they try to submit, and clearly when the action succeeds. JavaScript is the tool that makes this kind of responsive, moment-by-moment feedback possible in the browser.

Two Forms, Two Experiences
The same HTML, two very different outcomes
  • Silent formA user leaves the email field blank and clicks Submit. The page either reloads with no result or does nothing visible. The user has no idea what to fix, or whether anything is wrong at all.
  • Responsive formThe same user leaves the email field blank and clicks Submit. A message appears immediately next to that field: "Please enter your email address." The field is outlined to draw the eye. The page does not reload, and the user fixes the problem in seconds.
  • The differenceBoth forms use identical HTML markup. The difference is entirely in the JavaScript that reads the form, checks it, and reports back to the user. Feedback is not decoration — it is the difference between a form that works for people and one that only works for perfect input.
Study Note

HTML already gives some feedback on its own. Browsers display a small pop-up bubble when a required field is empty or an email-type field is malformed. This built-in feedback is useful, but it looks different in every browser, cannot be styled to match your page, and offers limited control over wording or timing. JavaScript validation builds on top of these HTML basics to give you consistent, well-designed, fully controllable feedback.

Reading Form Values

Before JavaScript can check anything about a form, it has to know what the user actually typed, clicked, or chose. Every form control stores its current state in a property that JavaScript can read directly. The property you read depends on the kind of control.

ControlProperty to ReadWhat It Returns
Text, email, password, textarea.valueThe text currently typed, as a string
Checkbox.checkedtrue or false
Radio button.checked on the selected optiontrue for the chosen option in the group, false for the others
Select menu.valueThe value of the currently chosen option
Number input.value (as text) or .valueAsNumberA string by default; convert to a number when needed
Reading a text input's value// select the input element from the page const nameInput = document.querySelector('#name'); // read the current text the user has typed const nameValue = nameInput.value; console.log(nameValue);

Notice that nameValue is read at one specific moment. If the user keeps typing afterward, that variable does not update on its own — it holds the value as it was when the line ran. This is why form values are almost always read inside an event handler, at the moment they are needed, rather than once when the page first loads.

Text values often need a small cleanup step before they are checked. Users sometimes leave stray spaces at the beginning or end of what they type, especially after copying and pasting. The string method .trim() removes that leading and trailing whitespace without changing the meaningful content in the middle.

A Key Habit

Always read values fresh, at the moment you need them. A common beginner mistake is to read a form's values once, near the top of a script, and then check that old copy later. By the time the user clicks Submit, the stored copy may no longer match what is actually in the field. Read the value inside the function that responds to the relevant event — typically the submit handler — so you always check what the user currently sees on the screen.

Required Fields

The simplest and most common validation check is also the most important one: has the user actually entered anything at all? A required field is a field that must contain a value before the form can be considered complete.

HTML provides a built-in required attribute that marks a field this way and triggers the browser's default warning bubble. That attribute is valuable and you should keep using it. But once you are writing your own JavaScript feedback, you need a way to perform the same check yourself, so that you control exactly what happens when a required field is empty.

A reusable empty-check functionfunction isEmpty(value) { // trim first, so a field containing only spaces still counts as empty return value.trim() === ''; } const email = document.querySelector('#email').value; if (isEmpty(email)) { console.log('The email field is empty.'); }

Real forms usually have several required fields at once. Rather than writing a separate if statement for each one, it is common to collect the fields that need checking and loop through them, applying the same empty-check to each.

Looking Ahead

Browsers also expose a built-in method called checkValidity(), which asks an input whether it currently satisfies its HTML validation attributes (required, type="email", minlength, and others). This chapter focuses on writing your own checks so you understand exactly what is happening, but it is worth knowing that checkValidity() exists once you are comfortable with the fundamentals.

Common Mistake

Checking only value === '' misses fields that contain nothing but spaces, which look empty to a human but are technically a non-empty string to JavaScript. Always trim before comparing, as shown in the isEmpty() function above.

Sections 24.4 – 24.7
The Logic: Validating Input and Responding to It
Validation Rules · Error Messages · Success Messages · Preventing Submission

Validation Rules

Once you can confirm that a field is not empty, the next question is whether its content makes sense. A validation rule is a small, specific test that a value must pass — and like an algorithm, a validation rule is the idea, while the JavaScript code that checks it is the implementation. The same rule, "this field must be a valid-looking email address," can be checked in slightly different ways, but the underlying rule stays the same.

Most beginner-level web forms rely on a small set of recurring rule patterns.

Common Validation Rule Patterns
Four patterns that cover most everyday forms
  • LengthA password must be at least 8 characters: password.length >= 8.
  • FormatAn email address must contain an "@" symbol and at least one character after it: a simple introductory check can use email.includes('@') combined with a length check, or a basic regular expression such as /^\S+@\S+\.\S+$/.
  • MatchingA "confirm password" field must equal the original password field: password === confirmPassword.
  • RangeAn age field must fall between reasonable limits: age >= 13 && age <= 120.

HTML itself offers a first layer of these same rules through attributes such as minlength, maxlength, min, max, pattern, and type="email". These attributes are valuable and should generally be kept in your markup even when you also validate with JavaScript — they provide a baseline of feedback for every browser, including situations where your script has not yet finished loading.

Study Note

You do not need to memorize a complicated email-validating regular expression. A simple check that looks for the basic shape of an email address — some text, an "@" symbol, more text, a period, and more text — is appropriate for an introductory course. No simple pattern catches every invalid address, and real applications generally confirm an email address by sending an actual message to it, not just by inspecting its shape.

Showing Error Messages

Detecting an invalid value is only half the job. The other half is telling the user, clearly and specifically, what is wrong and how to fix it. A common pattern is to reserve a small, empty element near each input — often a <span> or <p> with a matching id — and fill that element's text whenever validation fails.

A reusable showError functionfunction showError(input, message) { const errorEl = document.querySelector('#' + input.id + '-error'); errorEl.textContent = message; input.classList.add('input-invalid'); } function clearError(input) { const errorEl = document.querySelector('#' + input.id + '-error'); errorEl.textContent = ''; input.classList.remove('input-invalid'); }

This pattern depends on matching HTML, where each input has a sibling element ready to hold its message:

Matching HTML structure<label for="email">Email</label> <input type="email" id="email" name="email"> <span id="email-error" class="error-text"></span>
Common Mistake

A message like "Invalid input" tells the user that something is wrong but not what or how to fix it. Specific, friendly wording — "Please enter your email address" or "Password must be at least 8 characters" — respects the user's time and reduces frustration far more effectively than a generic warning.

Showing Success Messages

Error messages tell a user what went wrong. Success messages tell a user that everything went right — and they matter just as much. Without a clear confirmation, a user who has correctly filled out a form is left wondering whether their submission actually worked.

A reusable showSuccess functionfunction showSuccess(message) { const successEl = document.querySelector('#form-success'); successEl.textContent = message; successEl.classList.add('visible'); }

A few practical habits make success messages more effective. Place the message somewhere the user is already looking — near the top of the form or directly above the submit button, rather than somewhere they would have to scroll to find. Clear any leftover error messages at the same time you show success, so the page does not display contradictory feedback. And keep the wording calm and specific: "Thank you — your message has been sent" tells the user exactly what happened.

Looking Ahead

In a real application connected to a server, the success message usually appears only after the server confirms that the data was received and processed — not the instant the JavaScript finishes running on the page. Chapter 28 introduces fetch(), which is how a page eventually learns whether a server-side action actually succeeded.

Preventing Submission at an Introductory Level

By default, clicking a form's submit button does something dramatic: the browser gathers up the form's data and navigates to a new page, even if no server is actually listening on the other end. For a form validated entirely in JavaScript, this default behavior gets in the way — the page would reload before your error messages ever had a chance to appear.

The submit event fires the moment a form is about to be submitted, and the event object it provides has a method, preventDefault(), that cancels that default navigation. This gives your JavaScript full control: check the values, and only allow the "real" submission to proceed — or, in a practice exercise with no server, show a success message instead — once everything is valid.

Validating before allowing submissionconst form = document.querySelector('#contact-form'); form.addEventListener('submit', function (event) { event.preventDefault(); // stop the page from reloading const email = document.querySelector('#email'); let formIsValid = true; if (isEmpty(email.value)) { showError(email, 'Please enter your email address.'); formIsValid = false; } else { clearError(email); } if (formIsValid) { showSuccess('Thank you — your message has been sent.'); } });
An Important Distinction

In the examples throughout this chapter, there is no real server receiving the form's data, so preventDefault() simply stops a pointless page reload and lets the success message take its place. In a production application connected to a server, client-side validation and preventDefault() only improve the experience for honest users typing into a browser. A user can disable JavaScript entirely or send data directly to the server through other tools, bypassing every check this chapter teaches. That is why every real web application must also validate data again on the server — a topic for later, full-stack courses. Client-side validation is about user experience; server-side validation is about safety and correctness.

Sections 24.8 – 24.10
The Craft: Accessibility, Safety, and Testing
Accessible Feedback · Safe Input Handling · Testing

Accessible Form Feedback

A red border and a small caption of text communicate an error clearly to a sighted user reading the page visually. They communicate nothing at all to a person using a screen reader, unless the page explicitly tells the assistive technology what changed. Accessible form feedback is feedback that reaches every user, regardless of how they are experiencing the page.

Attribute
aria-live
Marks a region of the page so that screen readers announce changes to its content automatically, even if the user's focus is somewhere else. A value of "polite" waits for a natural pause before announcing.
Attribute
aria-describedby
Placed on an input, this attribute points to the id of its error or help text, so a screen reader reads that text aloud whenever the user focuses the field — connecting the message to the exact field it concerns.
Attribute
aria-invalid
Set to "true" on an input that has failed validation, and removed or set to "false" once it is corrected, so assistive technology can announce the field's current state.
Connecting an input to its error message<label for="email">Email</label> <input type="email" id="email" name="email" aria-describedby="email-error"> <span id="email-error" class="error-text" aria-live="polite"></span>

With this markup in place, the same showError() function from Section 24.5 now does double duty: setting the error span's text content both displays the message visually and triggers a screen reader announcement, because the span is marked as a live region. A small addition to your JavaScript — toggling aria-invalid alongside your existing CSS class — completes the picture.

Study Note

Accessible feedback is not an advanced extra step reserved for specialists. The same handful of attributes shown above — aria-live, aria-describedby, and aria-invalid — cover the overwhelming majority of everyday form feedback. Building the habit now, in small introductory forms, makes it automatic in larger projects later.

Safe Handling of User Input

Whenever your JavaScript displays text that a user typed, it has a choice about how to insert that text into the page. That choice matters more than it might first appear.

The DOM property textContent inserts text exactly as plain text — whatever the user typed appears on the page as visible characters, even if it happens to contain something that looks like an HTML tag. The property innerHTML, by contrast, interprets its contents as HTML markup. If a user's input is inserted with innerHTML and that input happens to contain HTML or script-like content, the browser may render it as part of the page rather than as plain text — which can break the page's appearance or, in more serious cases, run unintended code.

A Key Habit

Prefer textContent whenever you are displaying text that came from a user. Reserve innerHTML for content you wrote yourself or have deliberately built and trust, such as a template string composed entirely of your own fixed markup with no raw user text inserted directly into it. This single habit prevents the large majority of introductory-level input-handling mistakes.

Safer versus riskier display of user inputconst commentText = document.querySelector('#comment').value; const display = document.querySelector('#comment-preview'); // safer: always shows the literal text the user typed display.textContent = commentText; // riskier: would interpret any HTML-like text as markup // display.innerHTML = commentText; -- avoid this with raw user input
Study Note

This chapter does not expect you to become a security expert. The goal at this introductory level is a single durable habit: treat any value typed by a user as plain text unless you have a specific, deliberate reason to do otherwise, and never assume client-side checks alone make a form "safe." Real protection always also happens on the server, which later courses in this series cover in depth.

Testing Form Interactions

A form that works the one time you tried it while writing the code is not the same as a form that works. Testing a validated form means deliberately trying to break it — checking every kind of input a real user, careless or otherwise, might provide.

Test Case Checklist for a Validated Form
Run each of these against your form before considering it finished
  • Empty fieldsLeave every required field blank and submit. Every field should show its own specific error message.
  • Partial inputFill in some fields correctly and leave others invalid. Only the invalid fields should show errors; the valid ones should not.
  • Whitespace onlyType only spaces into a required field. This should be treated as empty, not as valid content.
  • Boundary valuesFor a length or range rule, try values exactly at the limit, just below it, and just above it — for example, a password of exactly 8 characters and one of exactly 7.
  • Valid inputFill in every field correctly. The success message should appear, and no error messages should remain visible from earlier attempts.
  • Keyboard onlyComplete the entire form using only the Tab and Enter keys, without a mouse. Every field, message, and button should remain reachable and usable.
  • Re-submissionAfter fixing an error and resubmitting, confirm the old error message is cleared rather than left on screen alongside the new result.
Looking Ahead

Chapter 29 returns to testing and debugging in greater depth, alongside accessibility and performance review, once you have more components and patterns to test together. The habits introduced here — trying empty input, boundary values, and keyboard-only navigation — apply to every interactive feature you build for the rest of this book.

Chapter Summary

Key Terms

accessible feedback
Feedback designed to reach every user, including those using screen readers or keyboard-only navigation, not only sighted mouse users.
aria-describedby
An HTML attribute that links an input to the element containing its description or error message, so assistive technology can read them together.
aria-invalid
An HTML attribute set on an input to indicate, for assistive technology, that its current value has failed validation.
aria-live
An HTML attribute that marks a region of the page so screen readers automatically announce changes to its content.
client-side validation
Validation performed by JavaScript running in the user's browser, before any data reaches a server. Improves user experience but can be bypassed.
error message
Specific, user-facing text explaining what is wrong with a field's value and, ideally, how to fix it.
event.preventDefault()
A method on an event object that cancels the browser's default behavior for that event, such as a form's default page reload on submission.
form feedback
Any information returned to a user about the state of an action they took within a form, such as an error, a success message, or a visual change.
required field
A field that must contain a value before a form can be considered complete.
server-side validation
Validation performed on the server after data is submitted, providing real protection because it cannot be bypassed by disabling browser JavaScript.
submit event
The event fired by a form when it is about to be submitted, used as the moment to run validation and decide whether to allow or prevent submission.
success message
User-facing text confirming that a submitted form passed all validation checks and was accepted.
test case
A specific input or scenario deliberately tried against a form to confirm it behaves correctly, including edge cases and invalid input.
textContent
A DOM property that inserts a string into an element as plain text, without interpreting it as HTML markup.
user input sanitization
The general practice of treating values typed by a user as plain text, rather than trusted markup, when displaying them on a page.
validation rule
A specific test a value must pass, such as a length check, format check, matching check, or range check.

Concept Check

Answer these questions before beginning the full review questions. They check basic understanding, not deep analysis.

  1. In your own words, what does it mean for a form to give feedback?
  2. Which property do you read to get the text from a text input? Which property do you read to find out whether a checkbox is checked?
  3. What does the isEmpty() function need to do besides comparing the value to an empty string, and why?
  4. What is the difference between a validation rule and the JavaScript code that checks it?
  5. What does event.preventDefault() do when called inside a form's submit handler?
  6. Name one ARIA attribute mentioned in this chapter and explain what it does.
  7. Why is textContent usually safer than innerHTML when displaying user-typed text?

Common Misconceptions

Misconception 1
"If a field has the required attribute, I don't need JavaScript validation."
The required attribute gives a useful baseline warning, but its appearance and wording differ across browsers and cannot be styled to match your page. JavaScript validation lets you control exactly what message appears, where it appears, and how it looks — and lets you add rules, such as matching fields or custom formats, that required alone cannot express.
Misconception 2
"Client-side validation makes a form secure."
Client-side validation runs in the user's own browser, which means a user can disable JavaScript or send data to a server through other means entirely, bypassing every check. Client-side validation exists to improve user experience by giving fast, friendly feedback — not to protect a server from bad or malicious data. Real protection requires validating the data again on the server, a topic covered in later full-stack courses.
Misconception 3
"A red border around an invalid field is enough feedback."
A color change communicates nothing to a screen reader user, who cannot see the border, and it may not communicate enough to a sighted user who cannot tell what specifically is wrong. Effective feedback combines a visible cue, specific text explaining the problem, and an accessible connection — such as aria-describedby — so the message reaches every user, not only those who can see and interpret the color.
Misconception 4
"Calling preventDefault() permanently disables the form."
preventDefault() only cancels the default behavior for that one occurrence of the event — the single click or keypress that triggered the handler. The form remains fully functional, and the user can try again; the next submit attempt fires its own fresh submit event, which your handler will check just as before.
Misconception 5
"Once a form looks correct on screen, the validation code is finished."
A form that happens to work for the exact input you tried while writing it may still fail for empty fields, whitespace-only input, boundary values, or keyboard-only navigation. Section 24.10's test case checklist exists precisely because visual appearance during casual testing is not the same as confirmed, systematic correctness.
ActivitiesForm Validation Practice

These activities ask you to write or extend small validation rules. Trace each rule by hand with a few sample values before testing it in a browser.

  1. Write a Length Rule. Write a function isValidPassword(password) that returns true only if the password is at least 8 characters long. Test it by hand with passwords of 5, 7, 8, and 12 characters.
  2. Write a Matching Rule. Write a function passwordsMatch(password, confirmPassword) that returns true only if the two values are exactly equal. Explain why trimming is usually not appropriate for this particular rule.
  3. Write a Range Rule. Write a function isValidAge(age) that returns true only if the numeric age is between 13 and 120, inclusive. Identify what should happen if the input cannot be converted to a number at all.
  4. Combine Rules. Given a sign-up form with name, email, password, and confirm-password fields, list each rule that should apply to each field, in the order they should be checked.
ActivitiesUser Feedback Code Reading

Read each code snippet carefully and answer the question that follows before running anything in a browser.

  1. Look again at the showError() and clearError() functions from Section 24.5. What would happen if a developer called showError() but forgot to ever call the matching clearError() once the field becomes valid?
  2. In the submit handler from Section 24.7, the variable formIsValid starts as true and is only set to false inside an if block. Explain why the code is written this way rather than starting as false.
  3. A teammate writes display.innerHTML = commentText; to show a user's comment on the page. Explain the risk in this line and rewrite it more safely.
ActivitiesAccessibility Review

Review a form you have built, or a form from a real website, against the following criteria.

  1. Does every input have an associated <label>, connected with a matching for and id?
  2. Does every error message live in an element connected to its input through aria-describedby?
  3. Is the error message container marked with aria-live so a screen reader announces new errors automatically?
  4. Can the entire form be completed using only the keyboard, with a visible focus indicator at every step?
  5. Does an invalid field have aria-invalid="true" set, and is it removed once the field becomes valid?
ActivitiesDebugging Practice

Each scenario describes a form that is not behaving correctly. Identify the likely cause before looking at any code.

  1. A form's error messages appear correctly the first time a field is left empty, but once the user types a valid value, the old error message never disappears. What is most likely missing from the validation code?
  2. Clicking "Submit" on a form reloads the page every time, even though a submit event listener has clearly been written. What single line is probably missing from the handler?
  3. A required-field check reports a field as valid even though the user only typed several spaces into it. What part of the empty-check is likely missing?
  4. A success message appears even when one of the fields is still invalid. What is most likely wrong with how the validity of each field is being tracked across the function?
ReviewReview Questions

Recall and Vocabulary

  1. Define form feedback in your own words.
  2. What property do you read to get the current text from a text input? What about a select menu?
  3. What is a required field, and how can JavaScript detect whether one has been left empty?
  4. Name the four common validation rule patterns described in Section 24.4.
  5. What event fires when a form is about to be submitted? What method on that event's object stops the default page reload?
  6. Name the three ARIA attributes introduced in Section 24.8 and state what each one does.
  7. What is the difference between textContent and innerHTML?
  8. What is the difference between client-side validation and server-side validation?

Understanding and Explanation

  1. Explain why reading a form's values once near the top of a script, rather than inside the event handler, can cause a form to check outdated information.
  2. The chapter says a validation rule is "the idea" and the JavaScript that checks it is "the implementation." Explain this distinction using an example that does not appear in the chapter.
  3. Why does the chapter recommend keeping HTML validation attributes such as required and type="email" even after you add your own JavaScript validation?
  4. Explain, in your own words, why client-side validation cannot be relied upon for security, even if it is well written.
  5. Choose two of the ARIA attributes from Section 24.8. For each one, explain what kind of user would notice its absence, and why.
  6. Explain the risk of displaying raw user input with innerHTML and why textContent avoids that risk.

Application and Analysis

  1. A sign-up form has fields for username, email, password, and confirm-password. For each field, identify: (a) the validation rule it needs, (b) the error message it should show if that rule fails, and (c) one boundary value you would test.
  2. Compare two error messages for the same problem. Message A: "Error." Message B: "Username must be between 3 and 20 characters." Which is more useful to a user, and why? What information does Message A fail to provide?
  3. A classmate argues: "Since our practice forms don't have a real server, there's no point learning about server-side validation yet." Write a response explaining why understanding the distinction matters even before building a connected, full-stack application.
  4. Look back at the misconceptions in this chapter's back matter. Choose one and describe a real situation where believing that misconception could cause a problem for actual users.

Design and Synthesis

  1. Design the validation rules, error messages, and success message for a "Request a Callback" form with fields for name, phone number, and a preferred callback time. Write each rule and message before writing any code.
  2. Write a short paragraph explaining, to a beginner who has only read Chapters 19–23, why a form needs more than just an event listener and a console.log() to be considered finished.
Mini-ProjectValidated Contact Form

Build a contact form with three fields — name, email, and message — plus a submit button. The form should meet every requirement below before you consider it complete.

  1. Every field is required. Leaving any field empty, or filling it with only spaces, must produce a specific error message next to that field.
  2. The email field must pass a simple format check confirming it contains an "@" symbol and at least one character after a following period.
  3. The message field must contain at least 10 characters once trimmed; shorter messages should produce an error explaining the minimum length.
  4. Clicking Submit must call event.preventDefault() so the page never reloads.
  5. If every field is valid, a success message appears and any previous error messages are cleared.
  6. If any field is invalid, no success message appears, and only the fields that are actually invalid show an error.
  7. Each error message element is connected to its input with aria-describedby, and the input's aria-invalid attribute is set and removed as its validity changes.
  8. The entire form can be completed and submitted using only the keyboard.
  9. The form passes every test case from the Section 24.10 checklist: empty fields, partial input, whitespace-only input, boundary-length input, fully valid input, and keyboard-only use.
Chapter 24 Checklist
Use this to confirm your understanding before moving to Chapter 25
Concepts
  • I can explain why forms need JavaScript-driven feedback beyond plain HTML.
  • I can read values from text inputs, checkboxes, radio buttons, and select menus.
  • I can write a reliable check for whether a required field has been left empty.
  • I can write simple validation rules for length, format, matching, and range.
  • I can explain the difference between HTML validation attributes and JavaScript validation.
Applications
  • I can display a specific error message next to the field that caused it, and clear it once corrected.
  • I can display a success message once a form passes all validation checks.
  • I can use event.preventDefault() inside a submit handler to stop a page reload.
  • I can connect form feedback to accessibility using aria-live, aria-describedby, and aria-invalid.
  • I can choose textContent over innerHTML when displaying user-typed text.
Study Habits
  • I understand that client-side validation improves experience but does not replace server-side validation.
  • I have tested a form using empty input, boundary values, and keyboard-only navigation, not just the first input I tried.
Preview — Chapter 25
Building Reusable Page Sections

Chapter 24 focused on a single, self-contained interaction: validating one form and responding to it. Chapter 25 opens Part V, where you begin combining HTML, CSS, and JavaScript into larger, reusable building blocks. You will learn to design hero sections, content sections, cards, callouts, and feature lists as repeatable patterns, using consistent CSS classes and spacing so the same design choices can appear across many pages without being rewritten each time. The validated contact form you just built will return as one of several reusable sections in your running Student Learning Site project.

MGU Library Connection
  • Web Development: HTML, CSS, and JavaScript — Appendix G: JavaScript Browser Reference
  • Web Development: HTML, CSS, and JavaScript — Appendix H: Forms and User Feedback Reference
  • Web Development: HTML, CSS, and JavaScript — Appendix C: Semantic HTML and Accessibility Reference
  • Companion resource: Form Validation Guide
  • Companion resource: Accessibility Checklist
  • Companion resource: Event Listener Guide
  • Next chapter: Chapter 25, Building Reusable Page Sections