Forms
createPal({ watch: 'form#signup' }); // at creationpal.watch('form#checkout'); // or later; returns an unwatch functionwatch accepts a selector or an element, and the element can be a form or any container of forms. A selector also matches forms rendered after you call watch(), which suits single-page apps. To watch several, pass an array: watch: ['#signup', '#newsletter'].
What it reacts to
Section titled “What it reacts to”| Situation | Reaction |
|---|---|
A field fails native validation (invalid event) | wince, and it turns to look at the first bad field |
A field gets aria-invalid="true" | wince and look at it |
| Required fields become valid | cheeks warm up; wink when they’re all valid |
| The form is submitted with no invalid fields | cheer |
Submitted with an invalid field (e.g. novalidate forms) | wince instead |
Try both kinds of validation. Mood: neutral
Form libraries
Section titled “Form libraries”Native validation works as-is. For JavaScript validation, pagepal watches aria-invalid, which accessible forms set on invalid fields anyway:
- MUI, Chakra UI, Mantine and most component libraries set it for you.
- React Hook Form, Formik: pass it yourself, which also helps screen reader users:
<input {...register('email')} aria-invalid={errors.email ? 'true' : 'false'} />Cheering only after the server says OK
Section titled “Cheering only after the server says OK”A successful submit isn’t always a successful save. Turn the automatic cheer off and cheer yourself:
pal.watch('form#checkout', { cheer: false });
const res = await fetch('/api/orders', { method: 'POST', body });if (res.ok) pal.react('cheer');Options
Section titled “Options”pal.watch(target, { cheer: true, // cheer on a valid submit wince: true, // wince (and look) on validation errors progress: true, // warm up as required fields fill in; wink when complete});Looking at the bad field is controlled by the pal-level gaze option: gaze: false turns it off, and gaze: { duration: 2500 } sets how long it looks.
Events
Section titled “Events”Forms emit events you can use directly or feed to analytics:
pal.on('formError', ({ form, field, source, validity }) => {}); // validity: 'valueMissing', 'typeMismatch', …pal.on('formSubmit', ({ form, success }) => {});pal.on('formProgress', ({ form, field, progress }) => {}); // progress: 0..1, or null without required fieldsThe pal in the corner is pagepal itself.