Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React formik form validation: How to initially have submit button disabled

Below is my React form validation code in which I am using formik. By default when the form loads, I want to keep the submit button disabled:

import { useFormik } from "formik";
import * as Yup from "yup";

const formik = useFormik({
    initialValues: {
      firstName: "",
      lastName: "",
      email: ""
    },
    validationSchema: Yup.object({
      firstName: Yup.string()
        .max(15, "Must be 15 characters or less")
        .min(3, "Must be at least 3 characters")
        .required("Required"),
      lastName: Yup.string()
        .min(3, "Must be at least 3 characters")
        .max(20, "Must be 20 characters or less")
        .required("Required"),
      email: Yup.string()
        .email("Invalid email address")
        .required("Required")
    }),
    onSubmit: values => {
      handleSubmit(values);
    }
  });

I have tried to use this on my button:

 disabled={!formik.isValid}

But it only actually works if I try to submit the form. So, if I leave the form blank and hit submit, all the validation errors show up and then the button is disabled. But, it should be disabled already from the start. I checked the documentation but didn't see anything obvious there.

like image 592
user8463989 Avatar asked Dec 22 '19 09:12

user8463989


People also ask

How do you make a submit button disabled in React?

Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button. Copied!

How do you disable submit button until form is filled in React?

To disable a button when an input is empty with React, we can set the input's value as a state's value. Then we can use the state to conditionally disable the button when the state's value is empty. to create the name state with the useState hook.

How do I disable a form in Formik?

This can be simply done using the disabled attribute and your existing value isSubmitted . fetch(request) . then((res) => res.


3 Answers

If you want to keep the submit button disabled initially when the form loads, you can use the use the dirty : boolean property of Formik something as below:

disabled={!formik.dirty}

If you want to keep the submit button disabled until all the field values are valid then you can use isValid: boolean which works as below:

Returns true if there are no errors (i.e. the errors object is empty) and false otherwise.

So you may use it as:

disabled={!formik.isValid}

Now, if you want the submit button to be disabled until all the fields are valid and if the fields values have been changed from their initial values then you would have to use both of the above attributes in conjunction as below:

disabled={!(formik.isValid && formik.dirty)}
like image 116
Rahul Gupta Avatar answered Oct 23 '22 16:10

Rahul Gupta


To have the button initially disabled just check if the touch object is empty and keep it this way until all the fields are validated with !isValid

disabled={!isValid || (Object.keys(touched).length === 0 && touched.constructor === Object)}
like image 10
kvba Avatar answered Oct 23 '22 15:10

kvba


Formik keeps track of field values and errors however exposes them for your use, this used to be done via formProps using the render props pattern however now seems to be part of the formik variable returned by the useFormik hook.

I would recomend to start by removing the initial values to a constant. Then you need to access the formik's error object. I have not done this using the new hook syntax, however, looking at the docs I would expect "formik.errors" to work (this is exposed in formProps.errors using render props). Finally the submit buttion disabled should be a check that either formik.values is equal to the initial values OR the errors object is not empty.

like image 3
Jamie Shepherd Avatar answered Oct 23 '22 17:10

Jamie Shepherd