Kiran Kumar
Kiran Kumar

Reputation: 381

React JS Multiple submit Buttons react-hook-form

im using react-hook-form for form validation and submission ,everything work's fine with single submit type button, now i need to have three buttons , "Save Draft" ,"Preview Data Values in Page" ,and "Submit for approval " ,i can opt-out for a Mode Selection radio Buttons ,But wanted to have three button submit function, which needs form data . adding onchnage for input fields will work ,but form validation needs to write again .

  const { register, handleSubmit } = useForm();
  const onSubmit = (data) => alert(JSON.stringify(data));
  function NeedTohaveFormDataHere1(Data) {

   } function NeedTohaveFormDataHere2(Data) {

   }
    return (  <form onSubmit={handleSubmit(onSubmit)}>
     <Headers />

  <input name="firstName" ref={register} placeholder="First name" />

  <input name="lastName" ref={register} placeholder="Last name" />

  <select name="category" ref={register}>
    <option value="">Select...</option>
    <option value="A">Category A</option>
    <option value="B">Category B</option>
  </select>
  <button onClick={NeedTohaveFormDataHere1}>
   Save Draft
  </button > 
  <button onClick={NeedTohaveFormDataHere2}>
    Preview
  </button>  
  <input type="submit" />
</form>
 );
 }
 

onSubmit function will get form data ,how to get form data in other two button functions ?

sloved .. with

  <button onClick={handleSubmit(NeedTohaveFormDataHere1)}>
   Save Draft
  </button > 
  <button onClick={handleSubmit(NeedTohaveFormDataHere2)}>
    Preview
  </button> 

Upvotes: 27

Views: 48385

Answers (9)

Michelle trujillo
Michelle trujillo

Reputation: 331

I had the same problem and I resolved it the following way:

I have two buttons. The first button validates and submits the form normally. The second button only validates and calls a custom function.

I'm assuming you have the situation. One button is to save and the other one is to store a draft.

<form id="example-form" onSubmit={handleSubmit(handleOnSave)}>
  <IconButtonTooltip
    form="example-form"
    title="Only save"
  >
    <SaveIcon className={classes.icon} />
  </IconButtonTooltip>

  <IconButtonTooltip
    form="example-form"
    title="Save and sign"
    onClick={handleSubmit(handleOnSingAndSave)}
  >
    <SignatureIcon className={classes.icon} />
  </IconButtonTooltip>
</form>

const handleOnSingAndSave  = () => {
  // Handle things...
}

It works for me!

Upvotes: 23

corbacho
corbacho

Reputation: 9042

Add a name attribute to your button. Then:

JavaScript

  async function onSubmit(values, e) {

    const submitter = e?.nativeEvent?.submitter;
    console.log(submitter?.name);

TypeScript

  async function onSubmit(
    values: z.infer<typeof formSchema>,
    e: React.FormEvent<HTMLFormElement>,
  ) {
    if (!(e.nativeEvent instanceof SubmitEvent)) return;
    const submitter = e?.nativeEvent?.submitter as HTMLButtonElement;
    if (!(submitter instanceof HTMLInputElement)) return;
    console.log(submitter?.name);

CanIuse SubmitEvent is safe: https://caniuse.com/?search=SubmitEvent

Upvotes: 8

Prasun Das
Prasun Das

Reputation: 101

You Can add name or id to your button and check the button type as in modern browsers button type is submit by default

<button  name="submit">Submit</button> 
    
    <button  name="draft">Draft</button> 

    <form onSubmit={handleSubmit} > ...

function handleSubmit(event) {
            event.preventDefault(); // Prevent form submission

            const buttonType = event.submitter.getAttribute("name");

            switch (buttonType) {
                case "submit":
                    // Handle submit button click
                    alert("Submit button clicked");
                    break;
                case "draft":
                    // Handle draft button click
                    alert("Save Draft button clicked");
                    break;
                default:
                    // Handle other cases if needed
                    break;
            }
        }

Upvotes: 1

szymmy
szymmy

Reputation: 1

I stumbled across the same problem, I solved it by adding an onClick event to each submit button with a setValue() function. Example:

import { useForm } from 'react-hook-form';

const { register, handleSubmit, setValue } = useForm();

const onSubmit = (data) => {
    console.log(data.method)
}

<form onSubmit={handleSubmit(onSubmit)}>
    <button type='submit' name='A' {...register('method')} onClick={() => setValue('method', 'A')}>A button</button>
    <button type='submit' name='B' {...register('method')} onClick={() => setValue('method', 'B')}>B button</button>
</form>

Upvotes: 0

AlCapwn351
AlCapwn351

Reputation: 31

I used yup with resolver for validation so my answer might differ. I also used trigger to validate without submitting. I also reset the form so that it won't be marked 'dirty' after saving.

export default function MyForm(props) {
  const {
    control,
    reset,
    trigger,
    handleSubmit,
    getValues,
    formState: { isDirty },
  } = useForm({
    mode: "onBlur",
    reValidateMode: "onBlur",
    shouldUnregister: true,
    defaultValues: {
      name: "",
      id: "",
      //rest of values
    },
    resolver: yupResolver(schema),
  });  


  const handleOnSubmit = async (event) => {
    if(!isDirty){
      //navigate out of page
    } else {
      //save and exit
    }
  }

  const handleOnSave = async () => {
    trigger(); //triggers validation for whole form
    const formValue = getValues();
    const isValid = schema.isValidSync(formValue);
    if(isValid){
      //await save actions
      if(savedSuccessfully){
        reset(formValue);
        //anything else
      }
    }
  };

}

Upvotes: 1

Vasiliy vvscode Vanchuk
Vasiliy vvscode Vanchuk

Reputation: 7169

I did it in the next way:

onSubmit - form submission handler

                  <Button type="submit">Post</Button>
                  <Button
                    appearance="stroke"
                    onClick={handleSubmit((data) =>
                      onSubmit({
                        ...data,
                        status: CreateResumeRequestStatusEnum.Draft,
                      })
                    )}
                  >
                    Save for later
                  </Button>

Upvotes: -1

MhkAsif
MhkAsif

Reputation: 608

You can try giving name and type to a button and catch it using window.event.submitter.name.

    <button type="submit" name="submit">Submit</button> 
    
    <button type="submit" name="draft">Draft</button> 

    <form onSubmit={handleSubmit} > ...
    const handleSubmit = () => { 
    const buttonType=window.event.submitter.name // will return draft or submit and you can handle it using switch case.

    if(buttonType==="submit"){
    //HANDLE SUBMIT FUNCTION
    return;
    }

    if(buttonType==="draft"){
     //HANDLE DRAFT FUNC
    return;
    }

    }

But this solution doesn't work in safari

Upvotes: 1

ABHIJEET KHIRE
ABHIJEET KHIRE

Reputation: 2481

if you have to handle the multiple submit buttons in react-hook-form

1. remove your submit method from the form tag and add it to your button click

2. move your submit buttons outside the form tag

const { handleSubmit } = useForm();

<form>
 <input />
 <input />
</form>

<button onClick={handleSubmit((d) => console.log(d))} > Save </button>
<button onClick={handleSubmit((d) => console.log(d))} > Draft </button>

Upvotes: 17

lamhungypl
lamhungypl

Reputation: 195

You can use handleSubmit in multiple place.

const handleSubmitDraft=()=>{
  handleSubmit(aync(data)=>{...})()

}
const handleSubmitPreview=()=>{
  handleSubmit((data)=>{...})()
}


<button onClick={handleSubmitDraft}>
   Save Draft
</button > 
<button onClick={handleSubmitPreview}>
    Preview
</button> 

Upvotes: 13

Related Questions