Reputation: 3221
I have a formik form in react native code as follow. Full runnable link can be view at: here
Current behaviour:
Validation can only be done with handleSubmit
, with cannot be use for handle further action. Note than onSubmit
will not be trigger if handleSubmit
detects there is any validation error.
<Button onPress={handleSubmit} style={styles.button}>
Submit
</Button>
Expected solution:
A lifecycle event called when validation fails after an attempted submit (eg: onValidationError
), where i can access all the input validation error props for further action.
Eg: I would like to handle something (like pop up an alert or scroll to first error message when validation fail)
The code is expected to be something like follow, or any other way of doing it can also be accepted. As long as i can handle event when validation error occurs.
<Formik
onSubmit={values => {
alert(JSON.stringify(values, null, 2));
Keyboard.dismiss();
}}
onValidationError={errorValues => {
// any action here
// note that onValidationError is not a built in function
// but it would be best if it can be achieved this way
// else any other equivalent solution also can be accepted
}}
validationSchema={validationSchema}>
What have tried?
I have tried to integrated 2 solution here. But failed to get it work.
https://github.com/jaredpalmer/formik/issues/1019
https://github.com/jaredpalmer/formik/issues/1484
Upvotes: 12
Views: 23983
Reputation: 1645
If you are using Formik via useFormik
hook you have a formik instance object you can access inside your component. This way you can put a useEffect
to listen to formik.isValid
change. Serves a callback role very nicely:
const formik = useFormik({
initialValues: {}
})
useEffect(() => {
onValidationChange(formik.isValid)
}, [formik.isValid, onValidationChange])
Upvotes: 0
Reputation: 41
Try this, Worked Well For me
<Formik
initialValues={params}
onSubmit={formHandler}
validationSchema={validationSchema}
innerRef={checkOutDetails}
enableReinitialize
>
{({ submitCount, errors, values, isValidating, isSubmitting, isValid }) => (
<>
{!isValid &&
!isValidating &&
isSubmitting &&
setTimeout(() => {
toast.error(
'The information is incomplete; please review all red fields and re-submit.'
);
}, 300)}
<Form>
//Your form fields
</Form>
</>
)}
</Formik>
Upvotes: 0
Reputation: 4021
If you did not use <Formik>
component and instead you used a component such as <Form>
from reactstrap
library with useFormik
hook, you can check it out where you call formik's handleSubmit event like that
const formik = useFormik({
initialValues : initialValues,
onSubmit: (values) => {
},
validationSchema: validationSchema
});
if (formik.isValid)
formik.handleSubmit()
else alert('Please fill in all fields!')
Upvotes: 0
Reputation:
Showing a notification on failed form submission can be achieved with a custom component using useFormikContext:
import { useFormikContext } from 'formik'
import { useEffect } from 'react'
const FormErrorNotification = () => {
const { isValid, isValidating, isSubmitting } = useFormikContext()
useEffect(() => {
if (!isValid && !isValidating && isSubmitting) {
alert('Fix your form errors!')
}
}, [isSubmitting, isValid, isValidating])
return null
}
export default FormErrorNotification
And use it like so:
<Formik ...>
<FormErrorNotification />
...
</Formik>
Upvotes: 4
Reputation: 21
there was pretty simple way to do that.
On your submit buttons onClick Method you can define a method like this;
<button onClick={() => scrollToErrors(errors)} > //errors param is formik's errors param.
https://formik.org/docs/guides/validation#validationschema
const scrollToErrors = (errors) => {
const errorKeys = Object.keys(errors);
if (errorKeys.length > 0) {
document.getElementsByName(errorKeys[0])[0].focus();
}
}
Upvotes: 1
Reputation: 1107
You can use the validate
method to accomplish this. Just make sure you return the error object, so the form can handle the validation.
<Formik
onSubmit={async values => {
console.log('submit', values)
}}
validate={values => {
const errors = {}
// Check the values object, and add custom validation
return errors
}}
></Formik>
Upvotes: 0
Reputation: 417
I guess the above answer can solve your issue, recenlty I have created few forms (some complex ones too), using the react hook forms
library. This is better than formik and redux forms. I would suggest to try it once, easy to plug and play with lots of dynamic features and validations (including patterns as well). https://react-hook-form.com/
Upvotes: -2
Reputation: 3059
You can use isValid
prop(from <Formik>
's render props) on <form>
's onsubmit
event by bypassing your logic there as (Documentation)
<form
onSubmit={e => {
console.log("isValid", isValid);
isValid
? handleSubmit(e)
: alert("Handle your custom method instead here");
}}
>
You can access isValid
prop from render props on formik's
{props => {
const {
values,
touched,
errors,
dirty,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
handleReset,
isValid // add this to your code
} = props;
return ( ... your code );
}}
I have also made codesandbox, you can view working example here - https://codesandbox.io/s/trusting-jennings-7wq0f
Note : This is not officially mentioned on any issues on formik repository or anywhere, but this is custom way intercept submit
action on <form>
's onsubmit
event
Hope this was helpful!
Upvotes: 16