A lightweight and flexible form validation library for Solid.js. It provides a simple API to validate form inputs, handle submission state, and manage error messages.
npm install @sparkstone/solid-validation
or
pnpm add @sparkstone/solid-validation
- Usage
- Basic Example
- API
useForm(options?: { errorClass?: string })
validate
formSubmit
errors
isSubmitting
isSubmitted
validateRef
validateField
getFieldValue
- Custom Validation
- Example Validator
- PocketBase Integration
prepareFormDataForPocketbase
parsePocketbaseError
import { createSignal } from 'solid-js';
import { useForm } from '@sparkstone/solid-validation';
function min5Characters(el: HTMLInputElement) {
if (el.value.length < 5) {
return 'must be at least 5 characters long';
}
}
function MyForm() {
const { formSubmit, validate, errors, isSubmitting, isSubmitted } = useForm();
async function onSubmit(form: HTMLFormElement) {
const formData = new FormData(form);
try {
// Submit form data here
} catch (e) {
return {
myCustomFormError: e.message,
};
}
}
return (
<form use:formSubmit={onSubmit}>
<input type='text' name='username' placeholder='Enter username' required use:validate />
<span>{errors.username}</span>
<input
type='text'
name='message'
placeholder='Enter message'
required
use:validate={[min5Characters]}
/>
<span>{errors.message}</span>
<span>{errors.myCustomFormError}</span>
<button type='submit' disabled={isSubmitting()}>
{isSubmitting() ? 'Submitting...' : 'Submit'}
</button>
{isSubmitted() && <p>Form successfully submitted!</p>}
</form>
);
}
function required(el: HTMLInputElement) {
return el.value.trim() ? false : 'This field is required';
}
Creates a form validation context.
-
validate(ref: HTMLInputElement, validators?: Validator[])
Registers an input for validation. -
formSubmit(ref: HTMLFormElement, callback: OnFormSubmit)
Handles form submission, running all validations. -
errors: Partial<Record<string, string>>
Reactive store of validation errors. -
isSubmitting: () => boolean
Tracks whether the form is currently submitting. -
isSubmitted: () => boolean
Tracks whether the form was successfully submitted. -
validateRef: (...args: Parameters<typeof validate>) => (ref: HTMLInputElement) => void
If you're validating a custom element, you can pass this in withref={validateRef()}
. -
validateField(fieldName: keyof ErrorFields): Promise<boolean>
Validates a field based on its name. It returnstrue
if the field is valid. If the field fails validation, it automatically focuses the field and updates the error state. -
getFieldValue(fieldName: keyof ErrorFields)
Retrieves the current value of the specified field. This is useful when you need to access a field’s value programmatically during form interactions.
A validator function receives an HTMLInputElement
and returns:
false | "" | null | undefined
for valid inputs.- A
string
error message for invalid inputs. - A
Promise<string | Falsy>
for async validation.
Example:
function minLength(el: HTMLInputElement) {
return el.value.length < 5 && 'Must be at least 5 characters';
}
For integrating form validation with PocketBase, this package provides helper functions to prepare form data and handle errors from PocketBase responses.
PocketBase does not include unchecked checkboxes in FormData
submissions. This function ensures that all checkbox fields are included, defaulting to "false"
if unchecked.
import { prepareFormDataForPocketbase } from '@sparkstone/solid-validation/pocketbase';
function handleSubmit(event: Event) {
event.preventDefault();
const form = event.currentTarget as HTMLFormElement;
const formData = new FormData(form);
prepareFormDataForPocketbase(formData, form);
// Now formData is ready to be sent to PocketBase
}
PocketBase API errors return a structured data
object. This function extracts error messages and formats them for easy use in your validation logic.
import { parsePocketbaseError } from '@sparkstone/solid-validation/pocketbase';
async function handleSubmit(event: Event) {
event.preventDefault();
const form = event.currentTarget as HTMLFormElement;
const formData = new FormData(form);
try {
// Replace with your PocketBase API call
await pocketbase.collection('users').create(formData);
} catch (e) {
const errors = parsePocketbaseError(e);
console.log(errors); // { email: "Invalid email", password: "Too short", form: "Something went wrong" }
}
}
This allows for easy mapping of errors to form fields and a general error message under the "form"
key.
These functions help streamline form submissions and error handling when using PocketBase as your backend.