New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto touch on submit #445
Comments
I agree. I just ran into this as well. I would categorize this as a bug unless there is some flag that needs to be set to make this happen. When we are submitting, we want the invalid fields to display their errors, so they should automatically be touched. |
Seems like even if I manually have called setFieldsTouched on the fields, then when handleSubmit is called it is clearing out the touched object so then the errors don't show. |
It looks like the problem occurs when initialValues are not specified. So when handleSubmit calls setNestedObjectValues with the values, they are {} and so does an Object.keys(values) and comes up with none. So touched is returned as {} When using yup schema it should get the fields to touch from the schema rather than the initialValues object. |
I think solutions could be as follow:
All 4 solutions would fix this issue. The last one is probably the easiest to implement. |
This behavior exists in formik. All fields are set to touched before submit. |
@jaredpalmer like @jeffbski says it does not work without initializing the form with data. |
initialValues are required and should always be specified |
It cannot depend on schema because not al users use schema validation |
@jaredpalmer when a developer does use validationSchema then obviously that can allow formik to know the fields, so if that is supplied it could be used by formik. No it is not required, but frankly I appreciate the value of yup and even the special optional support by formik, so it wouldn't be wrong to use the schema if it is provided. formik + yup = fantastic The fact that you provide this as an option gives it an advantage over the other competitors. |
@jaredpalmer The documentation only states that |
The |
I'm using the |
Well, after using
Given that, it seems that the touched logic is quite misleading or wrong? |
After digging into this one for a little bit I think the main reason this is an issue is because Formik doesn't know about the field to set as touched unless you set it on initialValues. The only partial solution I can think of is to have I'm just doing |
Yeah this is super confusing. I spent a good while wondering why validation on submit wasn't working before finding this thread. |
See #691 as well. |
Any updates regarding this issue? |
initialValues are required. |
@jaredpalmer Thank you for the reply, after reading into it more, the behavior that I want given my situation can be achieved by checking the submitCount. |
I've been using this to set my fields to touched const getTouchedObj = (errors: any) => {
const touched: any = {}
Object.keys(errors).map(key => {
if (Array.isArray(errors[key])) {
errors[key].map((val: any, index: any) => {
if(index == 0) touched[key] = [];
touched[key].push(getTouchedObj(val));
});
} else {
touched[key] = true;
}
});
return touched;
}; so in my submit I just call setTouched(getTouchedObj(errors)) I'm pretty new to this so feedback or better ideas are very appreciated 👍 |
Fields that aren't in the initialValues (for exp dynamic fields) object won't be present in "touched" object, when you click submit the touched field will only contain fields that are present in initialValues, for example: but in this next example let's assume you will push fields into an array you don't know what fields will be in so the array is initially empty: after pushing fields for example name and email into myFields and click submit the fields won't be present in initial values and nor in touched that's why you won't see errors. |
Is there any way I can overwrite this behavior ... I have a case where I must validate only fields that are actually touched on submitting ... NOTE:- I am using yup validation object |
So, where you get error object? As I understand you call setTouched into function onSubmit, but I don't know where get this? |
@DinAlla <Formik
initialValues={yourInitialValues}
onSubmit={yourHandleSubmitMethod}
>
{({ errors, ...andLotsOfOtherStuff }) => (
//form markup goes here
)
}
</Formik>
Hope this helps! |
@DinAlla I guess what you perhaps can do is save the error in state, and then use it in that handler (haven't tested it but this should be the gist): const getTouchedObj = (errors) => { ... }
const MyForm = () => {
const [validationErrors, setValidationErrors] = useState();
return (
<Formik
onSubmit={(values, formikBag) => {
if (validationErrors) {
formikBag.setTouched(getTouchedObj(validationErrors));
}
handleSubmit(values);
}}
>
{(formik) => {
const { errors } = formik;
// set the errors here
setValidationErrors(errors);
}
);
};
>
) But this is getting messy... |
I am having the same issue as well. Anyone managed to get it to work while using |
I just hit this 'issue' as well. To be honest, making initial values mandatory is a bit error-prone. You can forget to do it and no error is thrown to indicate your fault. I have written my own validation library (without knowing I have also hit the same problem - I did not know which fields the form has during Next the |
Here's a patch that seems to achieve it:
|
@konrad-garus Your solution seems to work for me also |
This is a great "fix it all" solution. If you want to be a bit more targeted and only patch the fields without an initial value (e.g. dynamically added fields from a |
If so it would be nice to update Formik docs, it's still marked as optional there |
I try this code, and I encountered some error.
I fix const getTouchedObj = (errors: any) => {
+ if (Array.isArray(errors)) {
+ const touched: any = []
+ errors.map((val: any) => {
+ touched.push(getTouchedObj(val))
+ })
+ return touched
+ }
const touched: any = {}
Object.keys(errors).map(key => {
if (Array.isArray(errors[key])) {
errors[key].map((val: any, index: any) => {
if (index == 0) touched[key] = []
const ret = getTouchedObj(val)
touched[key].push(ret)
})
+ } else if (typeof errors[key] !== 'string') {
+ touched[key] = getTouchedObj(errors[key])
} else {
touched[key] = true
}
})
return touched
} |
If you are using required attribute or any default browser validation on an input, you have to add noValidate on the form tag, this actually solved my problem, when I submit without touching any input it validate and mark input as touched. @fkrauthan |
If you're wondering why validations are not working on submit, then you might be setting formik values to null or empty object |
You can add this to your abstracted form components. Make sure that it does not kill your form performance during the first submit
you can make it a bit less spammy by wrapping it in touch check
You can get both To my surprise, the "auto-submit" touching in our case was based on |
Maybe it will help someone. In my case (using yup for validation), I needed to define const initialValues = {
name: null,
surname: null,
phone: null
}; And then it worked as I wanted. I needed to automatically set all fields as touched when I tried to send field without required fields (to show required fields errors only when submitting without it or after blur on specific field). Input looked something like that:
|
Hey guys I found the source of this problem. When you push new arguments to array you should use for example (Use the |
Thanks @kanonirbrest It's working |
In my case, the problem is that I not call the formik.submitForm() method |
Bug, Feature, or Question?
Feature/Question
Current Behavior
I only show error messages when a field is touched and has a error message. The problem when clicking submit it should show error messages for all fields but since they are not getting marked as touched no error shows up
Desired Behavior
When emitting the handleSubmit event all fields in the form should be touched/there should be a flag that indicates if the form was submitted and not reseted.
The text was updated successfully, but these errors were encountered: