jotai-form
jotai-form copied to clipboard
Expose validate all atoms method for atomWithFormControls
Hello,
Is it possible to expose onSubmit button for atomWithFormControls? Because we want to trigger validation for all form fields. Right now we are passing through all form fields and we set touched to true. Because if the field is not touched, it will not be validated.
Can this be implemented? Or do you maybe have a suggestion how to approach this?
Thanks
I don't think I understand the requirement completely.
You want the atomWithFormControls to expose a handleOnSubmit function so that you can trigger validation for all the fields?
A few questions so I understand the requirement more.
- You wish to have validations run as soon as the form mounts?
- You are currently using the
handleFocusfunction to trigger the validations?
Is that the right understanding ?
Hello barelyhuman,
Yes, I would like to have an onSubmit function for triggering validation of all the fields.
- No, it is only necessary when the "onSubmit" is triggered.
- Right now we are using a "custom" onSubmit method which is going through all of the form items and using "setTouched" we are triggering validation inside items.
Oh okay, I'm assuming that you wish to do one of 2 things and i've created examples for the same.
https://github.com/barelyhuman/jotai-form-control-example
Please check them out and let me know if that is the result you wish to achieve or not.
@Marko-Matijevic Please close the issue if the above solves for your use case
Hello again, sorry for the late response. I have created a repo where I show the example https://github.com/Marko-Matijevic/jotai-form-control-example.
So we have validation:
- when item inside the form is changed we are triggering the validation
- when we press "submit" button we are triggering the validation for all fields.
The errors should not appear when we are mounting the component. Only in above cases mentioned.
Any specific reason why you aren't using the onFocus and onBlur event handlers?
Cause the change's you've made can be handled with the handlers provided by atom and you need to only maintain the state of submission for the errors to show up, here's the code for it and a screencast of it handling cases mentioned by you.
import { useAtom, useAtomValue, atom } from "jotai";
import { atomWithFormControls, atomWithValidate } from "jotai-form";
import { useState } from "react";
import { z } from "zod";
const name = atomWithValidate("", {
validate: (v) =>
z.string().min(1, { message: "Name cannot be empty" }).parse(v),
});
const age = atomWithValidate(17, {
validate: (v) => z.coerce.number(v).min(18).parse(v),
});
const form = atomWithFormControls(
{ name, age },
{
validate: (v) => {
z.object({
name: z.string().optional(),
}).parse(v);
},
}
);
export const FormTwo = () => {
const {
isValid,
handleOnChange,
values,
touched,
handleOnFocus,
handleOnBlur,
fieldErrors,
} = useAtomValue(form);
const [submitted, setSubmitted] = useState(false);
const onSubmit = (e) => {
e.preventDefault();
setSubmitted(true);
if (!isValid) return;
};
return (
<>
<h2>
Default values might not exist and need changes and touched state before
submitting
</h2>
<form onSubmit={onSubmit}>
<div>
<label>
<input
name="name"
placeholder="name"
value={values.email}
onChange={(e) => handleOnChange("name")(e.target.value)}
onFocus={(e) => handleOnFocus("name")()}
onBlur={(e) => handleOnBlur("name")()}
/>
<small>
{(submitted || touched.name) && fieldErrors?.name?.message}
</small>
</label>
</div>
<div>
<label>
<input
type="number"
name="age"
placeholder="age"
value={values.age}
onChange={(e) => handleOnChange("age")(e.target.value)}
onFocus={(e) => handleOnFocus("age")()}
onBlur={(e) => handleOnBlur("age")()}
/>
<small>
{(submitted || touched.age) && fieldErrors?.age?.message}
</small>
</label>
</div>
<button onClick={onSubmit}>Submit</button>
</form>
</>
);
};
https://github.com/user-attachments/assets/74f6a5b3-2043-4426-b01f-b888ffc4d2f1