I have a form created with zod. Both are optional inputs, but I want to make sure that both are input if one is input. And I want to display the error message on both sides.
So I wrote the code as below.
const schema = z.object({
samplea: z.string().optional(),
sampleb: z.string().optional(),
}).refine(
(args) => {
if (args.samplea || args.sampleb) {
return args.samplea && args.sampleb ? true : false;
}
return true;
},
{
message: "If you enter, please enter both",
path: ["samplea", "sampleb"],
}
);
...
<Box>
<FormLabel>samplea</FormLabel>
<TextField
type="text"
{...register("samplea")}
error={!!errors.samplea}
helperText={errors.samplea?.message}
/>
</Box>
<Box>
<FormLabel>sampleb</FormLabel>
<TextField
type="text"
{...register("sampleb")}
error={!!errors.sampleb}
helperText={errors.sampleb?.message}
/>
</Box>
There is a problem that the error message can only be displayed for "sampleb". I would like to know how to make both "samplea" and "sampleb" error and display error messages for both.
To solve this use superRefine
. It can be used for creating multiple issues and customizing error codes.
const schema = z
.object({
samplea: z.string().optional(),
sampleb: z.string().optional(),
})
.superRefine((args, ctx) => {
if (!args.samplea && !args.sampleb) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["samplea"],
fatal: true,
message: "If you enter, please enter both",
});
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["sampleb"],
fatal: true,
message: "If you enter, please enter both",
});
}
});
In the above code block, superRefine
has two params args
(can be named anything), which represents the values of the object and we also have ctx
which contains methods from superRefine
.
Next, using an if
statement, we determine if both fields contain any value. In the event that the condition !args.samplea && !args.sampleb
evaluates to is true, ctx.addIssue
is triggered. This allows us to define the following:
code
: Enables you to customize your issue.path
: The desired field.fatal
: Used to abort early, preventing other refinements from executing.message
: Enter a validation message.