I am currently working on a form that consists of multiple inputs, including 'hours' and 'price'. The technology stack I am using is NextJS along with server-side actions. When a user clicks the submit button, here's what happens:
- The entire form is validated on the client side using Zod.
- If the validation is successful, the data is sent to the server for further validation and database mutation.
Specifically, the 'hours' input should be between 10 and 100. Here's an example scenario that illustrates the current functionality:
- User enters 5 in the 'hours' field
- Clicks submit
- Zod validates and displays the error message: 'Hours should be between 10 and 100'
While this works fine, there's an improvement I'd like to implement. I want the validation to trigger onBlur when the user enters a valid value (e.g., 50) after seeing an error message. This will prevent confusion where the input is correct but the error message persists.
My question is, how can I achieve this? Would I need to create separate schemas for each field and call onBlur?
Here is a snippet of the form implementation:
<form
ref={formRef}
action={async (formData) => {
const validatedFields = validateFields(formData)
const state = await createCard(validatedFields)
if (state.status === 'success') {
formRef.current?.reset()
setOpen(false)
setClientErrorMessage(undefined)
} else if (state.status === 'error') {
console.log(state)
setserverErrorMessage(state.message)
}
}}
>
// Form content goes here
</form>
And here is the function used for validating fields:
const validateFields = (formData: FormData) => {
const validatedFields = createSchema.safeParse({
client_id: formData.get('client_id'),
hours: Number(formData.get('hours')),
hours_left: Number(formData.get('hours')),
price: Number(formData.get('price')),
ends_at: formData.get('ends_at'),
})
if (!validatedFields.success) {
return setClientErrorMessage(validatedFields.error.flatten().fieldErrors)
}
return validateFields
}
I would appreciate any insights on how to tackle this challenge effectively.