Question
The project I am currently working on requires 2 different validation steps for the same form using 2 different submit mechanisms.
Is something like this possible using formik and if yes - what approuch should I use? I guess it is not possible using Yup, because then you only have 1 validationSchema.
Not sure about this. But if validation is set up according to the following, I think it allows any custom logic like yours to be implemented.
mapPropsToValues: props => ({ email: '', password: '' }),
// Add a custom validation function (this can be async too!)
validate: (values, props) => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
},
Maybe it allows for manually keeping track whether it's the first or second attempt and running different validation accordingly?
What I would do to solve this problem is have two separate validationSchema's and put them behind a flag that you set when you submit using each button.
import React, { Component } from 'react';
import { Formik } from 'formik';
const validationSchema1 = { ... };
const validationSchema2 = { ...validationSchema1, ... };
class MyComponent extends Component {
state = { button1: true };
render () {
const { button1 } = this.state;
return (
<Formik
validationSchema={button1 ? validationSchema1 : validationSchema2}
>
{({ submitForm }) => {
{/* Fields etc. */}
<button onClick={() => {
this.setState({ button1: true }, () => { submitForm(); });
}}>Button 1</button>
<button onClick={() => {
this.setState({ button1: false }, () => { submitForm(); });
}}>Button 2</button>
}}
</Formik>
);
}
}
Variable names are contrived but hopefully you get the idea.
You could also just use yup inside your custom validation function without using the validationSchema helper built into formik, maybe using setStatus in the button click to determine which button was pressed before submitting the form.
If there isn't two distinct buttons you could still use the same logic just split up in the same handleSubmit function used to determine the current submit mechanism.
Yep, this looks like a solution. Of course ideally I'd like to submit form by passing different parameters to handleSubmit without changing the state of the form, but I guess it's not possible.
I ended up having to do the same thing, and used aaronnuu's idea, and have a working example. Note, my example uses @availity/form and @availity/yup which kind of hook in to formik, but they are available for anyone to use, and you can use the same code with formik and yup.
here is the codesandbox: https://codesandbox.io/s/formik-two-submits-and-validations-one-form-7vnoh?file=/src/App.js
Most helpful comment
What I would do to solve this problem is have two separate validationSchema's and put them behind a flag that you set when you submit using each button.
Variable names are contrived but hopefully you get the idea.
You could also just use yup inside your custom validation function without using the validationSchema helper built into formik, maybe using setStatus in the button click to determine which button was pressed before submitting the form.
If there isn't two distinct buttons you could still use the same logic just split up in the same handleSubmit function used to determine the current submit mechanism.