Fixxed bugs Form Validation

This commit is contained in:
2025-08-16 14:29:39 +05:30
parent 34a972ddfd
commit 2cc07951cf
+40 -11
View File
@@ -83,7 +83,8 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
</form> </form>
<!-- Client validation & submit hook (no zod import here) --> <!-- Client validation & submit hook (no zod import here) -->
<script type="module" define:vars={{ formId, showSuccesInput }}> <script type="module" is:inline define:vars={{ formId, showSuccesInput }}>
const start = () => {
const INVALID_KLS = ["!border-danger", "focus-visible:ring-danger/40"]; const INVALID_KLS = ["!border-danger", "focus-visible:ring-danger/40"];
const VALID_KLS = ["!border-success", "focus-visible:ring-success/40"]; const VALID_KLS = ["!border-success", "focus-visible:ring-success/40"];
@@ -115,7 +116,8 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
(el) => el instanceof HTMLInputElement && el.type === "radio", (el) => el instanceof HTMLInputElement && el.type === "radio",
); );
const checks = all.filter( const checks = all.filter(
(el) => el instanceof HTMLInputElement && el.type === "checkbox", (el) =>
el instanceof HTMLInputElement && el.type === "checkbox",
); );
const err = root.querySelector('[id$="-err"]'); const err = root.querySelector('[id$="-err"]');
@@ -157,7 +159,9 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
function clearState(root) { function clearState(root) {
const { ctrls, err } = fieldControls(root); const { ctrls, err } = fieldControls(root);
ctrls.forEach((c) => c.classList.remove(...INVALID_KLS, ...VALID_KLS)); ctrls.forEach((c) =>
c.classList.remove(...INVALID_KLS, ...VALID_KLS),
);
ctrls[0]?.removeAttribute("aria-invalid"); ctrls[0]?.removeAttribute("aria-invalid");
if (err) { if (err) {
err.textContent = ""; err.textContent = "";
@@ -183,11 +187,13 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
formEl.querySelectorAll(`[name="${CSS.escape(name)}"]`), formEl.querySelectorAll(`[name="${CSS.escape(name)}"]`),
); );
const radios = els.filter( const radios = els.filter(
(el) => el instanceof HTMLInputElement && el.type === "radio", (el) =>
el instanceof HTMLInputElement && el.type === "radio",
); );
const checks = els.filter( const checks = els.filter(
(el) => (el) =>
el instanceof HTMLInputElement && el.type === "checkbox", el instanceof HTMLInputElement &&
el.type === "checkbox",
); );
if (radios.length) { if (radios.length) {
@@ -210,8 +216,13 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
const el = els[0]; const el = els[0];
if (el instanceof HTMLSelectElement && el.multiple) { if (el instanceof HTMLSelectElement && el.multiple) {
data[name] = Array.from(el.selectedOptions).map((o) => o.value); data[name] = Array.from(el.selectedOptions).map(
} else if (el instanceof HTMLInputElement && el.type === "file") { (o) => o.value,
);
} else if (
el instanceof HTMLInputElement &&
el.type === "file"
) {
data[name] = el.multiple data[name] = el.multiple
? Array.from(el.files || []) ? Array.from(el.files || [])
: (el.files?.[0] ?? null); : (el.files?.[0] ?? null);
@@ -249,7 +260,9 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
const schema = getSchema(); const schema = getSchema();
if (!schema || !schema.shape || !schema.shape[name]) return; if (!schema || !schema.shape || !schema.shape[name]) return;
const root = form.querySelector(`[data-field="${CSS.escape(name)}"]`); const root = form.querySelector(
`[data-field="${CSS.escape(name)}"]`,
);
if (!root) return; if (!root) return;
const { ctrls, isRadioGroup, isMultiCheckbox, checkboxes } = const { ctrls, isRadioGroup, isMultiCheckbox, checkboxes } =
@@ -275,7 +288,10 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
} else { } else {
// single control // single control
const ctrl = ctrls[0]; const ctrl = ctrls[0];
if (ctrl instanceof HTMLInputElement && ctrl.type === "checkbox") { if (
ctrl instanceof HTMLInputElement &&
ctrl.type === "checkbox"
) {
value = ctrl.checked; value = ctrl.checked;
} else if ( } else if (
ctrl instanceof HTMLInputElement && ctrl instanceof HTMLInputElement &&
@@ -285,7 +301,9 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
? Array.from(ctrl.files || []) ? Array.from(ctrl.files || [])
: (ctrl.files?.[0] ?? null); : (ctrl.files?.[0] ?? null);
} else if (ctrl instanceof HTMLSelectElement && ctrl.multiple) { } else if (ctrl instanceof HTMLSelectElement && ctrl.multiple) {
value = Array.from(ctrl.selectedOptions).map((o) => o.value); value = Array.from(ctrl.selectedOptions).map(
(o) => o.value,
);
} else { } else {
value = ctrl.value; value = ctrl.value;
} }
@@ -294,7 +312,9 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
const res = schema.shape[name].safeParse(value); const res = schema.shape[name].safeParse(value);
setError( setError(
root, root,
res.success ? "" : res.error.issues[0]?.message || "Invalid value", res.success
? ""
: res.error.issues[0]?.message || "Invalid value",
); );
} }
@@ -387,4 +407,13 @@ const formId = `f-${Math.random().toString(36).slice(2)}`;
t.value = t.getAttribute("data-initial") || ""; t.value = t.getAttribute("data-initial") || "";
t.removeAttribute("data-initial"); t.removeAttribute("data-initial");
}); });
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", start, { once: true });
} else {
start();
}
// For Astro client routing / view transitions
document.addEventListener("astro:page-load", start);
</script> </script>