Home > database >  Update Formik form values on checkbox change in ReactJS app
Update Formik form values on checkbox change in ReactJS app

Time:09-11

I am creating a form in a React app using Formik and Yup for validation. The page component has a section for shipping address and billing address. I have a checkbox in the form that will hide the billing address section if the details are identical. My problem is that if the checkbox is checked, and the user hits submit, the billing details are not copied over from the shipping details and thus I get an error.

My first thought was to add an onChange hook to the checkbox which copies the shipping details to the billing details. The 2 problems I found with this are 1) what if the user clicks the checkbox before filling out any shipping details and 2) Formik already has a default onChange hook. I then tried to add some code inside of the onSubmit hook to update the values, but this hook is not called if the billing details are invalid or empty.

How would I go about copying over all shipping details to billing details only if the checkbox is checked? I am new to Formik, React, and Yup so I suspect I will probably need to restructure the code? Below is my very simplified form component with only a name for each section and the checkbox:

const DetailsPage = () => {
  return (
    <Formik
      initialValues={{
        name_s: "",
        name_b: "",
        same_address_box: false,
      }}
      validationSchema={yup.object({
        name_s: yup.string().required("Required"),
        name_b: yup.string().required("Required"),
      })}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          updateOrderInfo("name_s", values.name_s); // Context hook that updates my order data once form is validated and submitted
          updateOrderInfo("name_b", values.name_b);
          setSubmitting(false);
        }, 500);
      }}
    >
      {({ values }) => (
        <Form>
          <section id="shipping-details-container"> // Shipping section
            <MyTextInput
              name="name_s"
              type="text"
              placeholder="Shipping name..."
            />
          </section>

          <section id="billing-details-container"> // Billing section
            <MyCheckbox name={"same_address_box"}>Same Address</MyCheckbox> // Checkbox
            {`${values.same_address_box}` !== "true" ? (
              <div id="hide-address-container">
                <MyTextInput
                  name="name_b"
                  type="text"
                  placeholder="Billing name..."
                />
              </div>
            ) : (
              <h1>SHOW NOTHING</h1>
            )}
          </section>

          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  );
};

CodePudding user response:

Try

setTimeout(() => {
      updateOrderInfo("name_s", values.name_s); // Context hook that updates my order data once form is validated and submitted
      if (values.same_address_box) {
         updateOrderInfo("name_b", values.name_s);
      }
      setSubmitting(false);
    }, 500);

And in Yup schema make change:

name_b: yup.string(). when("same_address_box", {
    is: true,
    then: yup.string().required("Required")
  })
  • Related