Formik: Multiple validation types

Created on 27 Feb 2018  路  4Comments  路  Source: formium/formik

Bug, Feature, or Question?

Question

Desired Behavior

The project I am currently working on requires 2 different validation steps for the same form using 2 different submit mechanisms.

  • The 1st submit should only validate the correctness of filled inputs, for example invalid emails.
  • The 2nd submit should do everything 1st submit does _plus_ check all the required fields.

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.

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.

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.

All 4 comments

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

Was this page helpful?
0 / 5 - 0 ratings