Advanced Web Programming

Forms, Validation and Accessibility

PGCP-AC

Forms turn a web page from a document into an interface. Registration, login, search, checkout, feedback and file upload all depend on the same core ideas: controls collect values, the browser constructs a data set, validation finds errors and the server decides whether the operation is permitted.

1. The form element

<form> groups controls and defines how their data is submitted.

<form action="/accounts" method="post" autocomplete="on">
  <!-- controls -->
  <button type="submit">Create account</button>
</form>

Important attributes include:

AttributePurpose
actionURL that receives the submission
methodHTTP method, normally get or post in ordinary HTML forms
enctypeEncoding used for a POST body
autocompleteAllows or restricts browser autofill behavior
novalidateBypasses interactive native validation for this form
targetBrowsing context in which the response opens

If action is omitted, the current URL is used. A button can override form settings with attributes such as formaction and formmethod, but overrides should be used sparingly because hidden changes in submission behavior are difficult to understand.

2. Labels, names and identifiers

id, name and label solve different problems:

  • id uniquely identifies an element in the document and supports DOM selection.
  • name becomes the key used in submitted form data.
  • label gives a control a visible and accessible name.
<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email">

The label's for value must exactly match the control's id. Selecting the label then focuses or activates the control, increasing the clickable area. A control with an id but no name can be found by JavaScript but ordinarily contributes no named value to submission.

Placeholder text is a hint, not a label. It disappears during typing, may have weak contrast and makes reviewing the expected format harder. Keep a persistent visible label and associate extra guidance using aria-describedby when necessary.

3. Common form controls

Text-like inputs

text, password, email, url, tel, search, number, date and related input types communicate purpose and may provide specialized keyboards or validation. type="email" checks an email-shaped value; it does not prove that the mailbox exists.

Use textarea for multiline text. Its initial value appears between its tags rather than in a value attribute.

Choice controls

Radio buttons with the same name form one mutually exclusive group:

<fieldset>
  <legend>Delivery method</legend>
  <label><input type="radio" name="delivery" value="standard" checked> Standard</label>
  <label><input type="radio" name="delivery" value="express"> Express</label>
</fieldset>

Checkboxes represent independent choices. An unchecked checkbox normally contributes no entry at all; it is not automatically submitted as false or 0. A select contributes the selected option's value or its text when no value is declared. With multiple, several entries may share one name.

Buttons

Inside a form, a button without an explicit type behaves as a submit button. Use type="button" for actions that must not submit and type="reset" only when restoring every control to its initial value is truly useful. Reset does not necessarily clear controls; it restores defaults.

4. Successful controls and submitted data

The browser constructs submission data from successful controls. A control generally needs a name, must not be disabled and must satisfy type-specific participation rules.

<input name="email" value="a@example.com">
<input name="internalCode" value="A7" disabled>
<input name="newsletter" value="yes" type="checkbox">

If the checkbox is unchecked, the result contains only email=a@example.com. The disabled control and unchecked checkbox are omitted. A readonly text control remains successful and can be submitted. This difference matters: readonly prevents editing, while disabled removes the control from interaction and ordinary submission.

Do not infer that an omitted checkbox is an attack or a browser error. Define a server-side default such as false when the key is absent.

5. GET, POST and encoding

ChoiceData locationTypical purpose
GET formURL querySearch, filtering, bookmarkable retrieval
POST formRequest bodyCreation, login, upload or state-changing processing

GET values appear in browser history, logs, copied URLs and bookmarks. It is inappropriate for passwords or destructive actions. POST moves fields into the body but does not encrypt them. HTTPS provides transport encryption.

The default POST encoding is application/x-www-form-urlencoded. Use multipart/form-data when uploading files:

<form action="/profile/photo" method="post" enctype="multipart/form-data">
  <label for="photo">Profile photograph</label>
  <input id="photo" name="photo" type="file" accept="image/png,image/jpeg">
  <button type="submit">Upload</button>
</form>

accept helps the file picker but is not a security boundary. The server must verify size, media type, contents, extension policy, storage name and authorization.

6. Native HTML validation

HTML constraint attributes provide immediate feedback without requiring JavaScript:

ConstraintApplies toExample
requiredMany controlsA value or selection must be supplied
minlength, maxlengthText valuesPassword length limits
min, max, stepNumeric or date-like valuesQuantity from 1 to 10
patternSupported text inputsApplication-specific format
Semantic input typeEmail, URL, number and othersType-specific parsing or validation
<label for="age">Age</label>
<input id="age" name="age" type="number" min="18" max="100" required>

<label for="code">Employee code</label>
<input id="code" name="code" pattern="[A-Z]{2}[0-9]{4}"
       aria-describedby="code-help" required>
<small id="code-help">Two capital letters followed by four digits.</small>

Native validation catches missing or badly shaped values. It cannot determine whether an account exists, inventory is available or the current user may perform an operation. Those checks need application and server knowledge.

7. Constraint Validation API

JavaScript can inspect and extend native constraints:

  • checkValidity() returns whether constraints pass and may fire invalid events;
  • reportValidity() also asks the browser to display validation feedback;
  • validity exposes conditions such as valueMissing, typeMismatch and patternMismatch;
  • validationMessage contains the current browser-generated message;
  • setCustomValidity(message) creates a custom failure; an empty string clears it.
const form = document.querySelector('#register');
const password = document.querySelector('#password');
const confirmation = document.querySelector('#confirmation');

function validateConfirmation() {
  confirmation.setCustomValidity(
    confirmation.value === password.value ? '' : 'Passwords do not match.'
  );
}

password.addEventListener('input', validateConfirmation);
confirmation.addEventListener('input', validateConfirmation);

form.addEventListener('submit', (event) => {
  validateConfirmation();
  if (!form.checkValidity()) {
    event.preventDefault();
    form.reportValidity();
  }
});

A frequent bug is setting a custom error and never clearing it. Once a nonempty custom message exists, the field remains invalid until setCustomValidity('') is called.

8. Accessible validation and error recovery

Good error handling tells the user what failed, where it failed and how to correct it. Color alone is insufficient.

<label for="username">Username <span aria-hidden="true">*</span></label>
<input id="username" name="username" required
       aria-describedby="username-help username-error"
       aria-invalid="true">
<small id="username-help">Use 4–20 letters or digits.</small>
<p id="username-error" class="error">Enter at least four characters.</p>

For a failed submission:

  1. Preserve values that are safe to redisplay.
  2. Show a text error summary near the beginning of the form.
  3. Link summary items to their controls.
  4. Place a specific message beside each invalid control.
  5. Mark invalid state programmatically where custom handling requires it.
  6. Move focus deliberately to the summary or first invalid field.
  7. Never erase every value and force the user to start again.

Use native HTML controls whenever possible because browsers already provide keyboard interaction, focus behavior and accessibility semantics. ARIA can describe relationships, but it does not supply missing keyboard behavior or validation logic.

9. Client validation and server validation

Client-side validation improves speed and usability, but it can be bypassed by disabling scripts, altering HTML or sending a request directly. The server is the authority.

Client responsibilityServer responsibility
Give immediate guidanceEnforce every business rule
Detect simple format errorsTreat all received data as untrusted
Reduce avoidable requestsCheck authorization and database state
Preserve and highlight fieldsNormalize, validate and safely process data

Validation asks whether data follows rules. Sanitization or output encoding addresses how data is safely used in a particular context. A value can be valid input and still require safe parameter binding in SQL or output encoding in HTML.

10. Complete registration form

<form id="register" action="/accounts" method="post">
  <p>All fields marked required must be completed.</p>

  <label for="full-name">Full name</label>
  <input id="full-name" name="fullName" autocomplete="name" required>

  <label for="register-email">Email</label>
  <input id="register-email" name="email" type="email"
         autocomplete="email" required>

  <label for="password">Password</label>
  <input id="password" name="password" type="password"
         minlength="8" autocomplete="new-password" required>

  <label for="confirmation">Confirm password</label>
  <input id="confirmation" name="confirmation" type="password"
         autocomplete="new-password" required>

  <fieldset>
    <legend>Communication preferences</legend>
    <label><input name="updates" value="product" type="checkbox"> Product updates</label>
    <label><input name="updates" value="events" type="checkbox"> Event notices</label>
  </fieldset>

  <button type="submit">Create account</button>
</form>

The form has persistent labels, purpose-specific autocomplete tokens, a semantic group for related checkboxes, explicit submission behavior and browser constraints. The server must still reject duplicate emails, enforce its password policy, ignore unauthorized fields, protect against cross-site request forgery where applicable and return accessible errors.

11. Practical considerations

  1. id does not replace name during submission.
  2. Unchecked checkboxes and disabled controls are normally omitted.
  3. Readonly controls can still be submitted.
  4. POST does not imply encryption; HTTPS supplies transport protection.
  5. multipart/form-data is required for conventional file upload.
  6. A button inside a form defaults to submission unless its type changes that behavior.
  7. Placeholder text is not a persistent accessible label.
  8. preventDefault() cancels the browser's default submission; it does not validate or send data itself.
  9. A custom validity error must be cleared when corrected.
  10. Browser validation never replaces server-side enforcement.

Continue learning

Related notes

Put this topic into timed practice

Open mock tests when you want full-exam pacing, or keep drilling in practice mode.