Synkronisér fejlens visuelle og programmatiske state

Opgavebeskrivelse

CSS viser allerede de vedvarende fejl, når browseren matcher et felt med :user-invalid. Nu skal den samme timing eksponeres programmatisk.

  1. Tilføj aria-errormessage="email-error" til e-mailfeltet.
  2. Tilføj aria-errormessage="password-error" til adgangskodefeltet. Bevar aria-describedby="password-instruction" som den separate, permanente instruktion.
  3. Implementér syncAriaInvalid(field):
    • matcher feltet :user-invalid, sættes field.ariaInvalid = "true";
    • ellers fjernes aria-invalid helt.
  4. Ved invalid skal det aktuelle felt markeres programmatisk ugyldigt. Eventet kræver capture-fasen.
  5. Ved focusout synkroniseres det felt, brugeren har forladt.
  6. Ved input må en eksisterende fejl fjernes, så snart feltet ikke længere matcher :user-invalid. Opret ikke nye fejl, mens brugeren skriver.
  7. Fastgør et felt under Fejlrelationer, og følg invalid, describedby og errormessage, mens du interagerer med formularen.

aria-errormessage beskriver intentionen bedre end at blande fejl og instruktioner i samme aria-describedby. Understøttelsen i kombinationer af browser og skærmlæser er dog fortsat mindre robust. Test derfor relationen i Chrome Accessibility og om muligt med en skærmlæser. Som sammenligning kan du midlertidigt føje fejl-id’et til aria-describedby og lytte efter forskellen.

const form = document.querySelector("form")
const status = document.querySelector(".status")

function isField(element) {
  return element.matches("input, textarea, select")
}

function syncAriaInvalid(field) {
  // 1. Matcher feltet :user-invalid?
  // 2. Sæt aria-invalid til "true", eller fjern attributten.
}

form.addEventListener("invalid", event => {
  // Native validation udløser invalid ved et mislykket submit.
}, true)

form.addEventListener("focusout", event => {
  // Synkronisér feltet, når brugeren forlader det.
})

form.addEventListener("input", event => {
  // Ryd kun en allerede vist fejl, når feltet bliver gyldigt.
})

form.addEventListener("submit", event => {
  event.preventDefault()
  status.textContent = "Formularen er gyldig."
})
Preview

Syntaks

<input
  aria-describedby="password-instruction"
  aria-errormessage="password-error"
>