solid-orange
solid-orange11mo ago

Conditionally display steps based on radio group?

I'm using Refine's useStepsForm with Ant Design. https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/ I have a radio group that sets what type of user is filling out the form. Based on this selection, I want to conditionally show certain steps that are relevant to each user type. Let's say step 1 has the radio group to set the user to type A, B, or C. If user A is selected, I want to show step 2 then move onto step 5. If user B is selected, I move straight to step 3 and then step 5, missing step 2 and 4. Currently I have this the radio group setting state and if I wrap my <Step> component, it works for that, but the content of the step doesn't display correctly, only for the first option.
const [userType, setUserType] = useState(null);
const onChangeUserType = (e: RadioChangeEvent) => {
setUserType(e.target.value);
};
const formList = [
<Form.Item label='User type?' name='user_type'>
<Radio.Group onChange={onChangeUserType} value={userType}>
{userTypes.map((user) => (
<Radio key={user.id} value={user.id}>
{user.title}
</Radio>
))}
</Radio.Group>
</Form.Item>,
userType === 1 && (
<Form.Item label='Field for user 1' name='user_1_field'>
<Input />
</Form.Item>
),
userType === 2 && (
<Form.Item label='Field for user 2' name='user_2_field'>
<Input />
</Form.Item>
),
userType === 3 && (
<Form.Item label='Field for user 3' name='user_3_field'>
<Input />
</Form.Item>
),
<Form.Item label='Field for all users' name='field_all_1'>
<Input />
</Form.Item>,
];

return (
<Create saveButtonProps={saveButtonProps}>
<Steps {...stepsProps}>
<Step title='User type' />
{userType === 1 && <Step title='Step 2' />}
{userType === 2 && <Step title='Step 3' />}
{userType === 3 && <Step title='Step 4' />}
<Step title='Step 5' />
</Steps>
<Form {...formProps}>{formList[current]}</Form>
</Create>
);
const [userType, setUserType] = useState(null);
const onChangeUserType = (e: RadioChangeEvent) => {
setUserType(e.target.value);
};
const formList = [
<Form.Item label='User type?' name='user_type'>
<Radio.Group onChange={onChangeUserType} value={userType}>
{userTypes.map((user) => (
<Radio key={user.id} value={user.id}>
{user.title}
</Radio>
))}
</Radio.Group>
</Form.Item>,
userType === 1 && (
<Form.Item label='Field for user 1' name='user_1_field'>
<Input />
</Form.Item>
),
userType === 2 && (
<Form.Item label='Field for user 2' name='user_2_field'>
<Input />
</Form.Item>
),
userType === 3 && (
<Form.Item label='Field for user 3' name='user_3_field'>
<Input />
</Form.Item>
),
<Form.Item label='Field for all users' name='field_all_1'>
<Input />
</Form.Item>,
];

return (
<Create saveButtonProps={saveButtonProps}>
<Steps {...stepsProps}>
<Step title='User type' />
{userType === 1 && <Step title='Step 2' />}
{userType === 2 && <Step title='Step 3' />}
{userType === 3 && <Step title='Step 4' />}
<Step title='Step 5' />
</Steps>
<Form {...formProps}>{formList[current]}</Form>
</Create>
);
useStepsForm | refine
useStepsForm hook allows you to split your form under an Ant Design based Steps component and provides you with a few useful functionalities that will help you manage your form.
8 Replies
kapa.ai
kapa.ai11mo ago
Hi @h3rrpie. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the extracts, the useStepsForm hook from Refine allows you to manage a form with multiple steps. It provides features such as which step is currently active, the ability to go to a specific step, and validation when changing steps. However, the extracts do not provide specific information on how to conditionally show certain steps based on the selection of a radio group. The examples provided in the extracts show how to conditionally render form items based on the current step, but not how to conditionally render steps themselves based on form data. Your current approach of conditionally rendering <Step> components based on the userType state seems to be a reasonable solution. If the content of the step doesn't display correctly, it might be due to how the formList array is constructed. In your formList, you are conditionally including form items based on the userType. This might cause issues with the current index used to select the current form item from the formList. If a form item is not included in the formList due to the condition, it might cause the current index to point to the wrong form item. Unfortunately, without more specific information in the extracts, it's hard to provide a more detailed solution. I would recommend checking the Refine documentation (https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/) for more information on the useStepsForm hook and how to use it. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@204362818592440323> kapa.ai is still learning and improving, please let us how it did by reacting below
solid-orange
solid-orange11mo ago
@kapa.ai Do you have an example of how I could conditionally render the form items instead of using the current index? Or, do you have an example of how I could skip steps instead?
kapa.ai
kapa.ai11mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Based on the information provided in the extracts, the useStepsForm hook returns a current value that you can use to conditionally render your form items. However, the extracts do not provide a specific example of how to skip steps or conditionally render form items without using the current index. Here's a basic example of how you could conditionally render form items based on the current value:
const { current, gotoStep, stepsProps, formProps } = useStepsForm();

const renderFormByStep = (step) => {
switch(step) {
case 0:
return (
<Form.Item label='User type?' name='user_type'>
<Radio.Group onChange={onChangeUserType} value={userType}>
{userTypes.map((user) => (
<Radio key={user.id} value={user.id}>
{user.title}
</Radio>
))}
</Radio.Group>
</Form.Item>
);
case 1:
return userType === 1 && (
<Form.Item label='Field for user 1' name='user_1_field'>
<Input />
</Form.Item>
);
case 2:
return userType === 2 && (
<Form.Item label='Field for user 2' name='user_2_field'>
<Input />
</Form.Item>
);
case 3:
return userType === 3 && (
<Form.Item label='Field for user 3' name='user_3_field'>
<Input />
</Form.Item>
);
case 4:
return (
<Form.Item label='Field for all users' name='field_all_1'>
<Input />
</Form.Item>
);
default:
return null;
}
};
return (
<Create saveButtonProps={saveButtonProps}>
<Steps {...stepsProps}>
<Step title='User type' />
<Step title='Step 2' />
<Step title='Step 3' />
<Step title='Step 4' />
<Step title='Step 5' />
</Steps>
<Form {...formProps}>{renderFormByStep(current)}</Form>
</Create>
);
const { current, gotoStep, stepsProps, formProps } = useStepsForm();

const renderFormByStep = (step) => {
switch(step) {
case 0:
return (
<Form.Item label='User type?' name='user_type'>
<Radio.Group onChange={onChangeUserType} value={userType}>
{userTypes.map((user) => (
<Radio key={user.id} value={user.id}>
{user.title}
</Radio>
))}
</Radio.Group>
</Form.Item>
);
case 1:
return userType === 1 && (
<Form.Item label='Field for user 1' name='user_1_field'>
<Input />
</Form.Item>
);
case 2:
return userType === 2 && (
<Form.Item label='Field for user 2' name='user_2_field'>
<Input />
</Form.Item>
);
case 3:
return userType === 3 && (
<Form.Item label='Field for user 3' name='user_3_field'>
<Input />
</Form.Item>
);
case 4:
return (
<Form.Item label='Field for all users' name='field_all_1'>
<Input />
</Form.Item>
);
default:
return null;
}
};
return (
<Create saveButtonProps={saveButtonProps}>
<Steps {...stepsProps}>
<Step title='User type' />
<Step title='Step 2' />
<Step title='Step 3' />
<Step title='Step 4' />
<Step title='Step 5' />
</Steps>
<Form {...formProps}>{renderFormByStep(current)}</Form>
</Create>
);
In this example, the renderFormByStep function is used to conditionally render form items based on the current step. This function uses a switch statement to determine which form item to render based on the current step. However, this approach does not allow you to skip steps. The useStepsForm hook provides a gotoStep function that you can use to navigate to a specific step, but the extracts do not provide an example of how to use this function to skip steps. For more detailed information and examples, I would recommend checking the Refine documentation (https://refine.dev/docs/api-reference/antd/hooks/form/useStepsForm/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@204362818592440323> kapa.ai is still learning and improving, please let us how it did by reacting below
solid-orange
solid-orange11mo ago
@kapa.ai I'm just starting out with the project so I could switch ui provider easily. Could I do conditional display if I used Mantine instead?
kapa.ai
kapa.ai11mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Based on the information provided in the extracts, the useStepsForm hook from Refine is also compatible with Mantine. It allows you to manage a form with multiple steps and provides features such as which step is currently active, the ability to go to a specific step, and validation when changing steps. However, the extracts do not provide specific information on how to conditionally show certain steps based on the selection of a radio group with Mantine. The examples provided in the extracts show how to conditionally render form items based on the current step, but not how to conditionally render steps themselves based on form data. The useStepsForm hook returns a set of useful values to render <Stepper/> and given the current value, you should have a way to render your form items conditionally with this index value. Here's a basic example of how you could conditionally render form items based on the current value with Mantine:
const {{ current, gotoStep, stepsProps, formProps }} = useStepsForm();
const renderFormByStep = (step) => {{
switch(step) {{
case 0:
return (
<RadioGroup label='User type?' onChange={{onChangeUserType}} value={{userType}}>
{{userTypes.map((user) => (
<Radio key={{user.id}} value={{user.id}}>
{{user.title}}
</Radio>
))}}
</RadioGroup>
);
case 1:
return userType === 1 && (
<Input label='Field for user 1' name='user_1_field' />
);
case 2:
return userType === 2 && (
<Input label='Field for user 2' name='user_2_field' />
);
case 3:
return userType === 3 && (
<Input label='Field for user 3' name='user_3_field' />
);
case 4:
return (
<Input label='Field for all users' name='field_all_1' />
);
default:
return null;
}}
}};

return (
<Create saveButtonProps={{saveButtonProps}}>
<Stepper {{...stepsProps}}>
<Step title='User type' />
<Step title='Step 2' />
<Step title='Step 3' />
<Step title='Step 4' />
<Step title='Step 5' />
</Stepper>
<Form {{...formProps}}>{{renderFormByStep(current)}}</Form>
</Create>
);
const {{ current, gotoStep, stepsProps, formProps }} = useStepsForm();
const renderFormByStep = (step) => {{
switch(step) {{
case 0:
return (
<RadioGroup label='User type?' onChange={{onChangeUserType}} value={{userType}}>
{{userTypes.map((user) => (
<Radio key={{user.id}} value={{user.id}}>
{{user.title}}
</Radio>
))}}
</RadioGroup>
);
case 1:
return userType === 1 && (
<Input label='Field for user 1' name='user_1_field' />
);
case 2:
return userType === 2 && (
<Input label='Field for user 2' name='user_2_field' />
);
case 3:
return userType === 3 && (
<Input label='Field for user 3' name='user_3_field' />
);
case 4:
return (
<Input label='Field for all users' name='field_all_1' />
);
default:
return null;
}}
}};

return (
<Create saveButtonProps={{saveButtonProps}}>
<Stepper {{...stepsProps}}>
<Step title='User type' />
<Step title='Step 2' />
<Step title='Step 3' />
<Step title='Step 4' />
<Step title='Step 5' />
</Stepper>
<Form {{...formProps}}>{{renderFormByStep(current)}}</Form>
</Create>
);
In this example, the renderFormByStep function is used to conditionally render form items based on the current step. This function uses a switch statement to determine which form item to render based on the current step. However, this approach does not allow you to skip steps. The useStepsForm hook provides a gotoStep function that you can use to navigate to a specific step, but the extracts do not provide an example of how to use this function to skip steps. For more detailed information and examples, I would recommend checking the Refine documentation (https://refine.dev/docs/api-reference/mantine/hooks/form/useStepsForm/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@204362818592440323> kapa.ai is still learning and improving, please let us how it did by reacting below