@modular-forms/solid
Version:
The modular and type-safe form library for SolidJS
66 lines (65 loc) • 2.71 kB
JSX
import { batch, splitProps } from 'solid-js';
import { FormError } from '../exceptions';
import { getValues, setError, setResponse, validate } from '../methods';
/**
* HTML form element that simplifies form submission and disables the browser's
* default form validation.
*/
export function Form(props) {
// Split props between local, options and other
const [, options, other] = splitProps(props, ['of'], [
'keepResponse',
'shouldActive',
'shouldTouched',
'shouldDirty',
'shouldFocus',
]);
return (<form novalidate {...other} ref={props.of.internal.element.set} onSubmit={async (event) => {
// Prevent default behavior of browser
event.preventDefault();
// Destructure props
// eslint-disable-next-line solid/reactivity
const { of: form, onSubmit, responseDuration: duration } = props;
batch(() => {
// Reset response if it is not to be kept
if (!options.keepResponse) {
form.internal.response.set({});
}
// Increase submit count and set submitted and submitting to "true"
form.internal.submitCount.set((count) => count + 1);
form.internal.submitted.set(true);
form.internal.submitting.set(true);
});
// Try to run submit actions if form is valid
try {
if (await validate(form, options)) {
await onSubmit?.(getValues(form, options), event);
}
// If an error occurred, set error to fields and response
}
catch (error) {
batch(() => {
if (error instanceof FormError) {
Object.entries(error.errors).forEach(([name, error]) => {
if (error) {
setError(form, name, error, {
...options,
shouldFocus: false,
});
}
});
}
if (!(error instanceof FormError) || error.message) {
setResponse(form, {
status: 'error',
message: error?.message || 'An unknown error has occurred.',
}, { duration });
}
});
// Finally set submitting back to "false"
}
finally {
form.internal.submitting.set(false);
}
}}/>);
}