Formedible provides advanced validation capabilities including cross-field validation, async validation with loading states, and seamless integration with Zod schemas.
Validate fields based on the values of other fields for complex validation scenarios.
Cross-field validation allows you to validate fields based on the values of other fields. This is useful for scenarios like password confirmation, date range validation, or conditional requirements.
const { Form } = useFormedible({fields: [{ name: 'password', type: 'password', label: 'Password' },{ name: 'confirmPassword', type: 'password', label: 'Confirm Password' },],crossFieldValidation: [{fields: ['password', 'confirmPassword'],validator: (values) => {if (values.password !== values.confirmPassword) {return 'Passwords must match';}return null;},message: 'Passwords must match'}]});
crossFieldValidation: [{fields: ['startDate', 'endDate'],validator: (values) => {if (values.startDate && values.endDate) {const start = new Date(values.startDate);const end = new Date(values.endDate);if (start >= end) {return 'End date must be after start date';}}return null;},message: 'Invalid date range'}]
Server-side validation with debouncing and loading states for better UX.
Async validation enables server-side validation, such as checking username availability or validating email addresses. It includes debouncing and loading states for better UX.
const { Form } = useFormedible({fields: [{ name: 'username', type: 'text', label: 'Username' },],asyncValidation: {username: {validator: async (value) => {if (!value) return null;// Simulate API callconst response = await fetch(`/api/check-username?username=${value}`);const data = await response.json();return data.available ? null : 'Username is already taken';},debounceMs: 500,loadingMessage: 'Checking availability...'}}});
asyncValidation: {email: {validator: async (value) => {if (!value) return null;try {const response = await fetch('/api/validate-email', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ email: value })});const result = await response.json();return result.valid ? null : result.message;} catch (error) {return 'Unable to validate email';}},debounceMs: 300,loadingMessage: 'Validating email...'}}
Access validation states and errors through the hook's return values.
const {Form,crossFieldErrors,asyncValidationStates} = useFormedible({// ... configuration});// Cross-field errorsconsole.log(crossFieldErrors); // { password: 'Passwords must match' }// Async validation statesconsole.log(asyncValidationStates);// {// username: {// loading: false,// error: 'Username is already taken'// }// }
Guidelines for effective validation implementation and user experience.
Use appropriate debounce times for async validation (300-500ms) to avoid excessive API calls.
Provide clear, actionable error messages that help users understand how to fix validation issues.
Cross-field validation runs on every form change, so keep validators lightweight and efficient.
Always handle async validation errors gracefully and provide fallback messages.
Start building forms with powerful validation patterns. Create robust, user-friendly validation that enhances the form experience.