diff --git a/hemx-js/runtime/hemx.js b/hemx-js/runtime/hemx.js index 3f2e728..df5490d 100644 --- a/hemx-js/runtime/hemx.js +++ b/hemx-js/runtime/hemx.js @@ -513,7 +513,15 @@ function handleRuntimeEvent(scope, name, payload) { if (name === "hemx:form-reset") { const form = generatedFormTarget(scope, payload); - if (form && form.reset) form.reset(); + if (form && form.reset) { + form.reset(); + forEachElement(form, (el) => { + if (el.hasAttribute("data-hemx-error-for")) { + if (isInputControl(el)) el.setCustomValidity(""); + else el.textContent = ""; + } + }); + } } else if (name === "hemx:form-error") { const [id, field, message] = String(payload).split("\u001f"); const target = formErrorTarget(scope, id, field); diff --git a/hemx-js/tests/runtime.rs b/hemx-js/tests/runtime.rs index ff06072..32437b1 100644 --- a/hemx-js/tests/runtime.rs +++ b/hemx-js/tests/runtime.rs @@ -392,3 +392,16 @@ fn runtime_ships_typescript_definitions() { assert!(source.contains("decodeBatch(buffer: ArrayBuffer): EffectBatch")); assert!(source.contains("interface Window")); } + +#[test] +fn runtime_clears_error_for_elements_on_form_reset() { + // req: runtime/005 req: form_effects/003 + let source = hemx_js::RUNTIME_JS; + + assert!(source.contains(r#"if (name === "hemx:form-reset")"#)); + assert!(source.contains("form.reset();")); + assert!(source.contains(r#"if (el.hasAttribute("data-hemx-error-for"))"#)); + assert!(source.contains("forEachElement(form, (el) => {")); + assert!(source.contains("el.setCustomValidity(\"\")")); + assert!(source.contains("el.textContent = \"\"")); +}