Form schema
Condition
Learn how the condition element is used in the schema.
Usage
The condition element is used to define a condition.
To understand how it is used let's look at this example.
import type { Schema, Form, Return, Cond, Variables } from "@formity/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
FormStep,
FormStepContent,
FormStepHeading,
FormStepInputs,
FormStepRow,
} from "./components/form-step";
import { Select } from "./components/input/select";
import { TextInput } from "./components/input/text-input";
import { NextButton } from "./components/buttons/next-button";
import { BackButton } from "./components/buttons/back-button";
import { MultiStep } from "./multi-step";
export type Values = [
Form<{ working: string }>,
Variables<{ company: string | null }>,
Cond<{
then: [Form<{ company: string }>];
else: [];
}>,
Form<{ study: string }>,
Return<{
working: string;
company: string | null;
study: string;
}>,
];
export const schema: Schema<Values> = [
{
form: {
values: () => ({
working: ["yes", []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<FormStep
key="working"
defaultValues={values}
resolver={zodResolver(
z.object({
working: z.string(),
}),
)}
>
<FormStepContent>
<FormStepHeading>Are you working?</FormStepHeading>
<FormStepInputs>
<Select
name="working"
label="Working"
options={[
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" },
]}
/>
</FormStepInputs>
<NextButton>Next</NextButton>
</FormStepContent>
</FormStep>
</MultiStep>
),
},
},
{
variables: () => ({
company: null,
}),
},
{
cond: {
if: ({ working }) => working === "yes",
then: [
{
form: {
values: () => ({
company: ["", []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<FormStep
key="company"
defaultValues={values}
resolver={zodResolver(
z.object({
company: z.string().min(1, "Required"),
}),
)}
>
<FormStepContent>
<FormStepHeading>At what company?</FormStepHeading>
<FormStepInputs>
<TextInput
name="company"
label="Company"
placeholder="Company name"
/>
</FormStepInputs>
<FormStepRow>
<BackButton>Back</BackButton>
<NextButton>Next</NextButton>
</FormStepRow>
</FormStepContent>
</FormStep>
</MultiStep>
),
},
},
],
else: [],
},
},
{
form: {
values: () => ({
study: ["business", []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<FormStep
key="study"
defaultValues={values}
resolver={zodResolver(
z.object({
study: z.string(),
}),
)}
>
<FormStepContent>
<FormStepHeading>What did you study?</FormStepHeading>
<FormStepInputs>
<Select
name="study"
label="Study"
options={[
{ value: "business", label: "Business" },
{ value: "health", label: "Health" },
{ value: "technology", label: "Technology" },
{ value: "education", label: "Education" },
]}
/>
</FormStepInputs>
<FormStepRow>
<BackButton>Back</BackButton>
<NextButton>Submit</NextButton>
</FormStepRow>
</FormStepContent>
</FormStep>
</MultiStep>
),
},
},
{
return: ({ working, company, study }) => ({
working,
company,
study,
}),
},
];
We need to use the Cond
type with the corresponding types.
export type Values = [
// ...
Cond<{
then: [Form<{ company: string }>];
else: [];
}>,
// ...
];
Then, in the schema we need to create an object with the following structure.
export const schema: Schema<Values> = [
// ...
{
cond: {
if: ({ working }) => working === "yes",
then: [
{
form: {
values: () => ({
company: ["", []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<FormStep
key="company"
defaultValues={values}
resolver={zodResolver(
z.object({
company: z.string().min(1, "Required"),
}),
)}
>
<FormStepContent>
<FormStepHeading>At what company?</FormStepHeading>
<FormStepInputs>
<TextInput
name="company"
label="Company"
placeholder="Company name"
/>
</FormStepInputs>
<FormStepRow>
<BackButton>Back</BackButton>
<NextButton>Next</NextButton>
</FormStepRow>
</FormStepContent>
</FormStep>
</MultiStep>
),
},
},
],
else: [],
},
},
// ...
];
The if
property is a function that takes the input values and returns a boolean value. If it is true, the elements in then
are used. Otherwise, the elements in else
are used.