10

Pretty new with Formik, I have a simple form, which has validation. I need to have 2 buttons, Submit and a Save button which will mostly do the same thing, however, if "Save" button is clicked, I want the validation to be "disabled" or rather, all required fields will no longer be required. Any ideas how I can achieve this?

Some codes below:

const initialValues = {
    title: "",
    description: ""
};

const validationSchema = Yup.object().shape({
        title: Yup.string()
            .max(50, 'You may only enter up to 50 characters')
            .required('Required'),
        description: Yup.string()
            .max(200, 'You may only enter up to 200 characters')
            .required('Required'),
        })


const CreateForm = () => {

    const handleCancel = () => {
        alert("Cancelled!")
    }

    return (
        <div>
            <Formik initialValues={initialValues}
                validationSchema={validationSchema}
                onSubmit={(values) => {
                    setTimeout(() => {
                        alert(JSON.stringify(values, null, 2));
                    }, 3000)
                }}
            >
                {props => (
                    <Form>
                        <CustomTextInput label="Title"
                            name="title" type="input" placeholder="Enter Title" />

                        <CustomTextInput label="Description"
                            name="description" type="input" placeholder="Description" />

                        <div>
                            <Button type="submit" variant="contained" color="primary">
                                Submit
                            </Button> &nbsp;
                            <Button type="submit" variant="contained" color="secondary" >
                                Save
                            </Button>&nbsp;
                            <Button variant="contained" color="default" onClick={handleCancel}>
                                Cancel
                            </Button>
                        </div>
                    </Form>
                )}
            </Formik>
        </div>
    )
}

export default CreateForm

4 Answers 4

13

Firstly remove type="submit". Because formik will understand it like submit and will validate it. Second add onClick function:

<Button
  variant="contained"
  color="secondary"
  onClick={() => handleSave(props.values)} >Save</Button>

And:

const handleSave = (values) => {
  // do what you want like on submit
}
Sign up to request clarification or add additional context in comments.

6 Comments

Wow. I didn't realize it was that simple. Thank you so much!
How would I do the same except I have to validate only a few fields in case of save and all fields in case of submit, how would I do that?
problem with this: you might get invalid values, whereas formik won't call onSubmit with invalid form values.
Most browsers default button elements to type="submit". Add type="button"
IDK, I came here 3 years, thanks again for the answer @aturan23
|
0

To achieve this you need to have a submitButtonState and check the value of this state when submitting the form.

const [submitButtonState, setSubmitButtonState] = useState(null)

const handleSubmitButtonState = (isSubmit) => {
  setSubmitButtonState(isSubmit)
}

//...
<Formik
  initialValues={{
    //...
  }}
  onSubmit={(values) => {
 // check submitButtonState value here
  console.log(submitButtonState)
  }}
  >
  {() => (
  <Form>
  //...
    <section>
      <button type="submit"
      onClick={() => handleSubmitButtonState("skip")}
      >
      Skip for now
      </button>
      <button
        type="submit"
        onClick={() => handleSubmitButtonState("submit")}
      >
      Submit
      </button>
     </section>
    </Form>
   )}
 </Formik>

Comments

0

Add

type="button"

to your button to make it not function as submit button in the form.

Comments

-1

Create a variable

  const [btnClicked, setBtnClicked] = React.useState('');

Add the onMouseOver event to buttons setting a value

        <form onSubmit={formik.handleSubmit}>
                 <Button type="submit" onMouseOver={(event)=>{
                   setBtnClicked('save');
              }}> Save </Button>

              <Button type="submit" onMouseOver={(event)=>{
                  setBtnClicked('save_and_close');
              }}>Save and close </Button>
        </form>

On the formik submit event you can get the value of the button selected to do whatever you want

      const formik = useFormik({ 
         initialValues: { },
         validationSchema: yup.object({ }),
         onSubmit: (values) => {
            if(btnClicked == "save"){
              // option 1
            } else {
              // Option 2
            }
         }
       });

2 Comments

Very large chance the event triggers before the rerender updates the state. I'd stay away from this solution.
setstate will take time and meanwhile, onSubmit will trigger with stale state

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.