astro-reactive-form/packages/validator/Validator.astro
2022-10-28 12:41:32 +02:00

61 lines
1.9 KiB
Text

---
import type { HookType } from '@astro-reactive/common';
export interface Props {
hook?: HookType;
displayErrorMessages?: boolean;
}
const { hook = 'all', displayErrorMessages = false } = Astro.props;
---
<input hidden name="hook" id="hook" value={hook} />
<input
hidden
name="displayErrorMessages"
id="displayErrorMessages"
value={displayErrorMessages.toString()}
/>
<script>
// TODO: selectors should by unique IDs generated by our library
// TODO: implement type guards pls 😱
// TODO: create deserializer util
// TODO: handle hooks / when to attach event listeners
// const form = document.querySelector('form');
import { clearErrors, validate } from './core';
// const hook: HookType = (document.getElementById('hook') as HTMLInputElement).value as HookType;
const inputs = [...document.querySelectorAll('form input')] as HTMLInputElement[];
inputs?.forEach((input) => {
input.addEventListener('blur', (e: Event) => {
// NOTE: event target attribute names are converted to lowercase
const element = e.target as HTMLInputElement;
const attributeNames = element?.getAttributeNames() || [];
const validators = attributeNames
.filter((attribute) => attribute.includes('data-validator-'))
.map((attribute) => {
const limit = element.getAttribute(attribute);
return `${attribute}:${limit}`;
});
const value = element.value;
const errors = validate(value, validators);
// set element hasErrors
if (errors.length) {
element.parentElement?.setAttribute('data-validator-haserrors', 'true');
element.setAttribute('data-validator-haserrors', 'true');
element.classList.add('has-errors');
// TODO: display error messages
} else {
element.parentElement?.removeAttribute('data-validator-haserrors');
element.removeAttribute('data-validator-haserrors');
element.classList.remove('has-errors');
}
});
input.addEventListener('input', clearErrors);
});
</script>