useStepForm: display custom field error based on form submit to previous step
When we hit form submit, we get the list of field errors, we need to put the errors to previous step and go to step, that have the issue
11 Replies
Hi @viveksingh0143. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To handle custom field errors and navigate to the step that has the issue when using
import { useStepsForm } from "@refinedev/react-hook-form";
const PostCreate = () => {
const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
steps: { currentStep, gotoStep },
} = useStepsForm<IPost, HttpError, IPost>();
const { options } = useSelect<ICategory, HttpError>({
resource: "categories",
}); const renderFormByStep = (step: number) => {
switch (step) {
case 0:
return (
<>
<label>Title: </label>
<input
{...register("title", {
required: "This field is required",
})}
/>
{errors.title && <span>{errors.title.message}</span>}
</>
);
case 1:
return (
<>
<label>Status: </label>
<select {...register("status")}>
<option value="published">published</option>
<option value="draft">draft</option>
<option value="rejected">rejected</option>
</select>
</>
);
case 2:
return (
<>
<label>Category: </label>
<select
{...register("category.id", {
required: "This field is required",
})}
<option key={category.value} value={category.value}>
{category.label}
</option>
))}
</select>
{errors.category && <span>{errors.category.message}</span>}
<br />
<br />
<label>Content: </label>
<textarea
{...register("content", {
required: "This field is required",
})}
rows={10}
cols={50}
/>
{errors.content && <span>{errors.content.message}</span>}
</>
);
}
}; const handleFormSubmit = async (data: IPost) => { try { await handleSubmit(onFinish)(data); } catch (error) { // Navigate to the step with the first error const firstErrorField = Object.keys(errors)[0]; if (firstErrorField) { const stepWithError = getStepWithError(firstErrorField); gotoStep(stepWithError); } } }; const getStepWithError = (field: string) => { switch (field) { case "title": return 0; case "status": return 1; case "category.id": case "content": return 2; default: return 0; } }; if (formLoading) { ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
useStepsForm
, you can follow these steps:
1. Validate Fields on Submit: Use the validateFields
method to validate the form fields when the form is submitted.
2. Navigate to the Step with Errors: If there are validation errors, navigate to the step that contains the erroneous field.
Here's an example of how you can achieve this:
```tsx
import { HttpError, useSelect } from "@refinedev/core";import { useStepsForm } from "@refinedev/react-hook-form";
const PostCreate = () => {
const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
steps: { currentStep, gotoStep },
} = useStepsForm<IPost, HttpError, IPost>();
const { options } = useSelect<ICategory, HttpError>({
resource: "categories",
}); const renderFormByStep = (step: number) => {
switch (step) {
case 0:
return (
<>
<label>Title: </label>
<input
{...register("title", {
required: "This field is required",
})}
/>
{errors.title && <span>{errors.title.message}</span>}
</>
);
case 1:
return (
<>
<label>Status: </label>
<select {...register("status")}>
<option value="published">published</option>
<option value="draft">draft</option>
<option value="rejected">rejected</option>
</select>
</>
);
case 2:
return (
<>
<label>Category: </label>
<select
{...register("category.id", {
required: "This field is required",
})}
{options?.map((category) => (
<option key={category.value} value={category.value}>
{category.label}
</option>
))}
</select>
{errors.category && <span>{errors.category.message}</span>}
<br />
<br />
<label>Content: </label>
<textarea
{...register("content", {
required: "This field is required",
})}
rows={10}
cols={50}
/>
{errors.content && <span>{errors.content.message}</span>}
</>
);
}
}; const handleFormSubmit = async (data: IPost) => { try { await handleSubmit(onFinish)(data); } catch (error) { // Navigate to the step with the first error const firstErrorField = Object.keys(errors)[0]; if (firstErrorField) { const stepWithError = getStepWithError(firstErrorField); gotoStep(stepWithError); } } }; const getStepWithError = (field: string) => { switch (field) { case "title": return 0; case "status": return 1; case "category.id": case "content": return 2; default: return 0; } }; if (formLoading) { ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@940119979334967366> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire•4w ago
@kapa.ai get the formState: { errors } inside useStepForm provided by antd
Let me check the knowledge base for you. One moment! :books:
----------------------
To get the
import { useStepsForm } from "@refinedev/react-hook-form";
const PostCreate = () => {
const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
steps: { currentStep, gotoStep },
} = useStepsForm<IPost, HttpError, IPost>();
const { options } = useSelect<ICategory, HttpError>({
resource: "categories",
}); const renderFormByStep = (step: number) => {
switch (step) {
case 0:
return (
<>
<label>Title: </label>
<input
{...register("title", {
required: "This field is required",
})}
/>
{errors.title && <span>{errors.title.message}</span>}
</>
);
case 1:
return (
<>
<label>Status: </label>
<select {...register("status")}>
<option value="published">published</option>
<option value="draft">draft</option>
<option value="rejected">rejected</option>
</select>
</>
);
case 2:
return (
<>
<label>Category: </label>
<select
{...register("category.id", {
required: "This field is required",
})}
<option key={category.value} value={category.value}>
{category.label}
</option>
))}
</select>
{errors.category && <span>{errors.category.message}</span>}
<br />
<br />
<label>Content: </label>
<textarea
{...register("content", {
required: "This field is required",
})}
rows={10}
cols={50}
/>
{errors.content && <span>{errors.content.message}</span>}
</>
);
}
}; const handleFormSubmit = async (data: IPost) => { try { await handleSubmit(onFinish)(data); } catch (error) { // Navigate to the step with the first error const firstErrorField = Object.keys(errors)[0]; if (firstErrorField) { const stepWithError = getStepWithError(firstErrorField); gotoStep(stepWithError); } } }; const getStepWithError = (field: string) => { switch (field) { case "title": return 0; case "status": return 1; case "category.id": case "content": return 2; default: return 0; } }; if (formLoading) { return <div>Loading...</div>; ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
formState: { errors }
inside useStepsForm
provided by Ant Design, you can use the useStepsForm
hook which extends the functionalities of useForm
. This means you can access the errors
object directly from the formState
.
Here is an example of how you can access and use the errors
object within useStepsForm
:
```tsx
import { HttpError, useSelect } from "@refinedev/core";import { useStepsForm } from "@refinedev/react-hook-form";
const PostCreate = () => {
const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
steps: { currentStep, gotoStep },
} = useStepsForm<IPost, HttpError, IPost>();
const { options } = useSelect<ICategory, HttpError>({
resource: "categories",
}); const renderFormByStep = (step: number) => {
switch (step) {
case 0:
return (
<>
<label>Title: </label>
<input
{...register("title", {
required: "This field is required",
})}
/>
{errors.title && <span>{errors.title.message}</span>}
</>
);
case 1:
return (
<>
<label>Status: </label>
<select {...register("status")}>
<option value="published">published</option>
<option value="draft">draft</option>
<option value="rejected">rejected</option>
</select>
</>
);
case 2:
return (
<>
<label>Category: </label>
<select
{...register("category.id", {
required: "This field is required",
})}
{options?.map((category) => (
<option key={category.value} value={category.value}>
{category.label}
</option>
))}
</select>
{errors.category && <span>{errors.category.message}</span>}
<br />
<br />
<label>Content: </label>
<textarea
{...register("content", {
required: "This field is required",
})}
rows={10}
cols={50}
/>
{errors.content && <span>{errors.content.message}</span>}
</>
);
}
}; const handleFormSubmit = async (data: IPost) => { try { await handleSubmit(onFinish)(data); } catch (error) { // Navigate to the step with the first error const firstErrorField = Object.keys(errors)[0]; if (firstErrorField) { const stepWithError = getStepWithError(firstErrorField); gotoStep(stepWithError); } } }; const getStepWithError = (field: string) => { switch (field) { case "title": return 0; case "status": return 1; case "category.id": case "content": return 2; default: return 0; } }; if (formLoading) { return <div>Loading...</div>; ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@940119979334967366> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire•4w ago
@kapa.ai there are no formState in useStepForm
Let me check the knowledge base for you. One moment! :books:
----------------------
You're correct that
useStepsForm
does not directly expose formState
. However, you can still access the errors
object from the formState
by using the useForm
hook, which useStepsForm
extends.
Here is an example of how you can handle form submission, validate fields, and navigate to the step with errors using useStepsForm
with Ant Design:
In this example:
- The errors
object is accessed from formState
.
- The handleFormSubmit
function handles form submission and navigates to the step with the first error if validation fails.
For more details, you can refer to the [useStepsForm documentation](https://refine.dev/docs/ui-integrations/ant-design/hooks/use
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@940119979334967366> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire•4w ago
@kapa.ai documentation url is https://refine.dev/docs/ui-integrations/ant-design/hooks/use-steps-form/
and no formState
useStepsForm | Refine
The 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.
Let me check the knowledge base for you. One moment! :books:
----------------------
To handle custom field errors and navigate to the step that has the issue when using
useStepsForm
with Ant Design, you can follow these steps:
1. Validate Fields on Submit: Use the validateFields
method to validate the form fields when the form is submitted.
2. Navigate to the Step with Errors: If there are validation errors, navigate to the step that contains the erroneous field.
Here is an example of how you can achieve this:
In this example:
- The validateFields
method is used to validate the form fields.
- The handleFormSubmit
function handles form submission and navigates to the step with the first error if validation fails.
For more details, you can refer to the useStepsForm documentation (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-steps-form/).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@940119979334967366> kapa.ai is still learning and improving, please let us know how it did by reacting below