Validation
Ez Form has a built-in validation system to handle form validation. It is not dependent on specific libraries and very easy to customize.
- You can add validation schema at field level or form level or both.
- Create your own validator.
- Decide when to trigger validation (submit, change, blur).
Ez Form comes with a set of built-in validators. But, in this page, we will use ZodValidator.
npm i --save-dev @ez-kits/form-zod-validator zod
Field Level
You can pass your field's validation schema to Field using prop validationSchema
.
You can pass a single schema or an array of schema. And decide when to trigger validate with that schema.
onChange
onBlur
onSubmit
import { useForm, BindingFieldInput } from "@ez-kits/form-react";
import { zodValidator } from "@ez-kits/form-zod-validator";
import { z } from "zod";
export interface SignInFormValues {
username: string; // Or email: string;
password: string;
}
export function SignInForm() {
const signInForm = useForm<SignInFormValues, z.Schema>({
validator: zodValidator,
onSubmit(values) {
console.log(values);
},
onErrors(errors) {
console.log(errors);
}
});
return <signInForm.Form>
<form {...signInForm.getFormProps()}>
<signInForm.Field
name="username"
validationSchema={{
onChange: z.string().trim().min(1, "Username is required."),
}}
>
<label>
Username:
<BindingFieldInput>
<input />
</BindingFieldInput>
</label>
</signInForm.Field>
<signInForm.Field
name="password"
validationSchema={
z.string().trim().min(1, "Password is required.")
}
>
<label>
Password:
<BindingFieldInput>
<input type="password" />
</BindingFieldInput>
</label>
</signInForm.Field>
<button type="submit">
Submit
</button>
</form>
</signInForm.Form>
}
Form Level
You can also pass your form's validation schema to Form using prop validationSchema
. Like Field
, you can also pass a single schema or an array of schema. And decide when to trigger validate with that schema.
onChange
onBlur
onSubmit
import { useForm, BindingFieldInput } from "@ez-kits/form-react";
import { zodValidator } from "@ez-kits/form-zod-validator";
import { z } from "zod";
export interface SignInFormValues {
username: string; // Or email: string;
password: string;
}
export function SignInForm() {
const signInForm = useForm<SignInFormValues, z.Schema>({
validator: zodValidator,
validationSchema: validationSchema: {
onChange: z.object({
username: z.string().trim().min(1, "Username is required."),
password: z.string().trim().min(1, "Password is required.")
}),
},
onSubmit(values) {
console.log(values);
},
onErrors(errors) {
console.log(errors);
}
});
return <signInForm.Form>
<form {...signInForm.getFormProps()}>
<signInForm.Field name="username">
<label>
Username:
<BindingFieldInput>
<input />
</BindingFieldInput>
</label>
</signInForm.Field>
<signInForm.Field name="password">
<label>
Password:
<BindingFieldInput>
<input type="password" />
</BindingFieldInput>
</label>
</signInForm.Field>
<button type="submit">
Submit
</button>
</form>
</signInForm.Form>
}
Display Error
Validation errors in FormInstance
or FieldInstance
will be synchronously. Ez Form provides component FieldErrors
to display validation errors.
import { useForm, FieldErrors, BindingFieldInput } from "@ez-kits/form-react";
import { zodValidator } from "@ez-kits/form-zod-validator";
import { z } from "zod";
export interface SignInFormValues {
username: string; // Or email: string;
password: string;
}
export function SignInForm() {
const signInForm = useForm<SignInFormValues, z.Schema>({
validator: zodValidator,
validationSchema: {
onChange: z.object({
username: z.string().trim().min(1, "Username is required."),
password: z.string().trim().min(1, "Password is required.")
}),
},
onSubmit(values) {
console.log(values);
},
onErrors(errors) {
console.log(errors);
}
});
return <signInForm.Form>
<form {...signInForm.getFormProps()}>
<signInForm.Field name="username">
<label>
Username:
<BindingFieldInput>
<input />
</BindingFieldInput>
</label>
<FieldErrors>
{(errors) => errors
.flatMap(
({messages}) => messages
)
.map((errorMessage) =>
<span>{errorMessage}</span>
)}
</FieldErrors>
</signInForm.Field>
<signInForm.Field name="password">
<label>
Password:
<BindingFieldInput>
<input type="password" />
</BindingFieldInput>
</label>
<FieldErrors>
{(errors) => errors
.flatMap(
({messages}) => messages
)
.map((errorMessage) =>
<span>{errorMessage}</span>
)}
</FieldErrors>
</signInForm.Field>
<button type="submit">
Submit
</button>
</form>
</signInForm.Form>
}