Advanced Validation

Powerful Validation Patterns

Formedible provides advanced validation capabilities including cross-field validation, async validation with loading states, and seamless integration with Zod schemas.

Cross-Field
Async Validation
Debouncing

Cross-Field Validation

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.

Password Confirmation Example

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'
}
]
});

Date Range Validation Example

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'
}
]

Async Validation

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.

Username Availability Example

const { Form } = useFormedible({
fields: [
{ name: 'username', type: 'text', label: 'Username' },
],
asyncValidation: {
username: {
validator: async (value) => {
if (!value) return null;
// Simulate API call
const 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...'
}
}
});

Email Validation Example

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...'
}
}

Validation States

Access validation states and errors through the hook's return values.

const {
Form,
crossFieldErrors,
asyncValidationStates
} = useFormedible({
// ... configuration
});
// Cross-field errors
console.log(crossFieldErrors); // { password: 'Passwords must match' }
// Async validation states
console.log(asyncValidationStates);
// {
// username: {
// loading: false,
// error: 'Username is already taken'
// }
// }

Best Practices

Guidelines for effective validation implementation and user experience.

Debouncing

Use appropriate debounce times for async validation (300-500ms) to avoid excessive API calls.

Error Messages

Provide clear, actionable error messages that help users understand how to fix validation issues.

Performance

Cross-field validation runs on every form change, so keep validators lightweight and efficient.

Error Handling

Always handle async validation errors gracefully and provide fallback messages.

Ready to Implement Advanced Validation?

Start building forms with powerful validation patterns. Create robust, user-friendly validation that enhances the form experience.