Updated Form Error
This commit is contained in:
@@ -15,6 +15,7 @@ interface Props extends HTMLAttributes<"form"> {
|
||||
resetOnSubmit?: boolean;
|
||||
validateOn?: string;
|
||||
showSuccesInput?: boolean;
|
||||
formError?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -30,6 +31,7 @@ const {
|
||||
resetOnSubmit = false,
|
||||
validateOn = "input,blur,change",
|
||||
showSuccesInput = false,
|
||||
formError = "",
|
||||
...rest
|
||||
}: Props = Astro.props;
|
||||
|
||||
@@ -57,6 +59,17 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
|
||||
data-validateon={validateOn}
|
||||
novalidate
|
||||
>
|
||||
<div
|
||||
data-form-error
|
||||
id={`${formId}-formerr`}
|
||||
role="alert"
|
||||
aria-live="polite"
|
||||
class="wr:mt-2 wr:bg-red-100 wr:border wr:border-red-200 wr:text-sm wr:text-red-800 wr:rounded-lg wr:p-4 wr:dark:bg-red-800/10 wr:dark:border-red-900 wr:dark:text-red-500"
|
||||
hidden={!formError}
|
||||
>
|
||||
{formError ?? ""}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{
|
||||
title && (
|
||||
@@ -98,6 +111,7 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
|
||||
];
|
||||
|
||||
const form = document.getElementById(formId);
|
||||
|
||||
if (!form || form.dataset.__afInit) return;
|
||||
form.dataset.__afInit = "1";
|
||||
|
||||
@@ -332,6 +346,12 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
|
||||
setError(root, issue.message);
|
||||
if (!firstRoot) firstRoot = root;
|
||||
}
|
||||
|
||||
const globalIssue = (zodError.issues ?? []).find(
|
||||
(i) => !i.path || i.path.length === 0,
|
||||
);
|
||||
setFormError(globalIssue?.message || "");
|
||||
|
||||
if (firstRoot) fieldControls(firstRoot).ctrls[0]?.focus();
|
||||
}
|
||||
|
||||
@@ -374,6 +394,7 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
|
||||
showErrors(form, result.error);
|
||||
return;
|
||||
}
|
||||
setFormError("");
|
||||
form.querySelectorAll("[data-field]").forEach(clearState);
|
||||
if (!onSubmitName) {
|
||||
form.submit();
|
||||
@@ -415,13 +436,40 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
|
||||
|
||||
form.addEventListener("wr:set-errors", (e) => {
|
||||
const map = e.detail || {};
|
||||
Object.entries(map).forEach(([name, message]) => {
|
||||
if ("_form" in map) setFormError(map._form);
|
||||
|
||||
for (const [key, val] of Object.entries(map)) {
|
||||
if (key === "_form") continue;
|
||||
const root = form.querySelector(
|
||||
`[data-field="${CSS.escape(name)}"]`,
|
||||
`[data-field="${CSS.escape(key)}"]`,
|
||||
);
|
||||
if (root) setError(root, message || "Invalid value");
|
||||
});
|
||||
if (root) {
|
||||
setError(root, val);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const formErrEl = form.querySelector("[data-form-error]");
|
||||
|
||||
function setFormError(msg) {
|
||||
if (!formErrEl) return;
|
||||
if (msg && String(msg).trim()) {
|
||||
formErrEl.textContent = String(msg);
|
||||
formErrEl.hidden = false;
|
||||
} else {
|
||||
formErrEl.textContent = "";
|
||||
formErrEl.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
form.addEventListener("input", () => setFormError(""));
|
||||
|
||||
form.addEventListener("wr:set-form-error", (e) => {
|
||||
const msg = e.detail;
|
||||
setFormError(msg);
|
||||
});
|
||||
|
||||
form.addEventListener("wr:clear-form-error", () => setFormError(""));
|
||||
};
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
|
||||
Reference in New Issue
Block a user