import {$, $a, doAfterLoad, getMetaProperty} from "./Template"; /** * Removes all validation-related information from `form`. * * @param form the form to hide validation information from */ export function clearFormValidity(form: HTMLFormElement): void { clearMessageStatus(form); $a("input", form).forEach((input: Element) => { if (!(input instanceof HTMLInputElement)) return; clearInputValidity(input); }); } /** * Shows a `type` message in `card`. * * @param card the card to show `message` in, or `form` to show the `message` in the form's status card * @param message the message to show in `card`, or `undefined` if `card` should be hidden * @param type the type of message to show in `card`, or `undefined` if `card` should be hidden */ export function showMessageType(card: HTMLElement | HTMLFormElement, message?: string, type?: "error" | "info" | "success" | "warning"): void { if (card instanceof HTMLFormElement) card = $(`article[data-status-for="${card.id}"]`)!; const output = $("output", card)!; card.classList.remove("hidden", "error", "info", "success", "warning"); if (message == null || type == null) { card.classList.add("hidden"); output.innerText = ""; } else { card.classList.add(type); output.innerText = message; } } /** * Removes the message in `card`, hiding it in the process. * * @param card the card to clear the message from */ export function clearMessageStatus(card: HTMLElement): void { showMessageType(card); } /** * Shows an error message in `card`. * * @param card the card to show `message` in * @param message the error message to show in `card` */ export function showMessageError(card: HTMLElement, message: string): void { showMessageType(card, message, "error"); } /** * Shows an information message in `card`. * * @param card the card to show `message` in * @param message the message to show in `card` */ export function showMessageInfo(card: HTMLElement, message: string): void { showMessageType(card, message, "info"); } /** * Shows a success message in `card`. * * @param card the card to show `message` in * @param message the success message to show in `card` */ export function showMessageSuccess(card: HTMLElement, message: string): void { showMessageType(card, message, "success"); } /** * Shows a warning message in `card`. * * @param card the card to show `message` in * @param message the success message to show in `card` */ export function showMessageWarning(card: HTMLElement, message: string): void { showMessageType(card, message, "warning"); } /** * Marks `input` as neither valid nor invalid. * * @param input */ export function clearInputValidity(input: HTMLInputElement): void { input.classList.remove("valid", "invalid"); input.removeAttribute("aria-invalid"); input.removeAttribute("aria-errormessage"); const label = $(`label[for="${input.id}"]`); if (label != null) label.classList.remove("valid", "invalid"); const hint = $(`*[data-hint-for="${input.id}"]`); if (hint != null) { hint.classList.remove("valid", "invalid"); hint.role = null; hint.innerText = hint.dataset["hint"] ?? ""; } } /** * Shows to the user that `input` is invalid. * * @param input the input to show as invalid * @param message the message explaining what is invalid */ export function showInputInvalid(input: HTMLInputElement, message?: string): void { clearInputValidity(input); input.classList.add("invalid"); input.setAttribute("aria-invalid", "true"); input.focus(); const label = $(`label[for="${input.id}"]`); if (label != null) label.classList.add("invalid"); const hint = $(`*[data-hint-for="${input.id}"]`); if (hint != null && message != null) { hint.classList.add("invalid"); input.setAttribute("aria-errormessage", hint.id); hint.role = "alert"; hint.innerText = message; } } /** * Shows to the user that `input` is valid. * * @param input the input to show as valid * @param message the message to show at the input */ export function showInputValid(input: HTMLInputElement, message?: string): void { clearInputValidity(input); input.classList.add("valid"); input.setAttribute("aria-invalid", "false"); const label = $(`label[for="${input.id}"]`); if (label != null) label.classList.add("valid"); const hint = $(`*[data-hint-for="${input.id}"]`); if (hint != null) { hint.classList.add("valid"); if (message != null) hint.innerText = message; } } /** * If the `fwd:validation:load-hints` meta property has been set, loads hints and implements close buttons for forms. */ doAfterLoad(() => { if (getMetaProperty("fwd:validation:load-forms") === undefined) return; $a(".status-card .close").forEach((close: Element) => { if (!(close instanceof HTMLElement)) return; close.addEventListener("click", (event: MouseEvent) => { event.preventDefault(); close.parentElement!.classList.add("hidden"); }); }); $a("input + small[data-hint]").forEach((hint: Element) => { if (!(hint instanceof HTMLElement)) return; hint.innerText = hint.dataset["hint"] ?? ""; }); });