3

I want to have two submit buttons for my form.

Both will use the same inputs and form validation, but will do different tasks

export default function Formtwosubmits() {

  function handlesubmit_task1(){


  }


  function handlesubmit_task2(){


  }


  return (
    <>
      <form onSubmit={handlesubmit_task1 if task 1 button pressed || handlesubmit_task2 if task2 button pressed } >
        <Button variant="contained" color="primary" type="submit">
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit">
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}

I am not able to undertand how to pass different handlesumit functions for different buttons

I have tried:

export default function Formtwosubmits() {

  function handlesubmit_task1(){


  }


  function handlesubmit_task2(){


  }


  return (
    <>
      <form >
        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task1}>
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task2}>
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}

putting onClick on the button. with type=submit but this does not check the form validation (like required etc), whereas with onSubmit i see the form validation is checked

How can i trigger form validation with onClick. even that can help me

0

4 Answers 4

4

Use a React ref on the form element to access the form fields in the submit handlers and attach the submit handlers to each button's onClick handler.

function Formtwosubmits() {
  const formRef = useRef(); // (1) <-- React ref for form DOMNode

  function handlesubmit_task1(event) {
    event.preventDefault();
    const { value } = formRef.current.myInput; // (4) <-- access form inputs by name

    // ...anything you need to do with form fields
    console.log("handler 1", value);

    formRef.current.reset(); // (5) <-- reset form if necessary
  }
  
  function handlesubmit_task2(event) {
    event.preventDefault();
    const { value } = formRef.current.myInput;

    console.log("handler 2", value);

    formRef.current.reset();
  }

  return (
    <>
      <form ref={formRef}> // (2) <-- Attach ref to element
        <button
          variant="contained"
          color="primary"
          type="submit"
          onClick={handlesubmit_task1} // (3) <-- Attach submit handler 1
        >
          task 1
        </button>
        <button
          variant="contained"
          color="primary"
          type="submit"
          onClick={handlesubmit_task2} // (3) <-- Attach submit handler 2
        >
          task 2
        </button>
        .... here input fields
        <input name="myInput" type="text" />
      </form>
    </>
  );
}

Demo

Edit reactjs-form-with-two-submit-buttons-doing-two-different-tasks-for-same-form

Update

You can assign an id to each submit button and access the React Synthetic event's nativeEvent to get to the underlying browser event and access the submitter value.

Create a submitHandler to receive the form's onSubmit event and check the submitter value and proxy the onSubmit event to the proper handler based on id.

const handlers = {
  submit1: handlesubmit_task1,
  submit2: handlesubmit_task2,
}

const submitHandler = (e) => {
  const { id } = e.nativeEvent.submitter; // <-- access submitter id
  handlers[id](e); // <--proxy event to proper callback handler
};

function handlesubmit_task1(event) {
  event.preventDefault();
  const { value } = event.target.myInput;
  console.log("handler 1", value);
  event.target.reset();
}

function handlesubmit_task2(event) {
  event.preventDefault();
  const { value } = event.target.myInput;
  console.log("handler 2", value);
  event.target.reset();
}

<form onSubmit={submitHandler}>
  <button
    id="submit1" // <-- id 1
    variant="contained"
    color="primary"
    type="submit"
  >
    task 1
  </button>
  <button
    id="submit2" // <-- id 2
    variant="contained"
    color="primary"
    type="submit"
  >
    task 2
  </button>
  .... here input fields
  <input name="myInput" type="text" />
</form>

Edit reactjs-form-with-two-submit-buttons-doing-two-different-tasks-for-same-form (forked)

Sign up to request clarification or add additional context in comments.

3 Comments

what if we have async const the this instead of function like change function handlesubmit_task1(event) { } to const onSubmitA = async (data) => { } and change this function handlesubmit_task2(event) { } to const onSubmitB = async (data) => { } ? i see you have event and e but what if we passing async data like async (data)?
@uberrebu How are you passing the additional data when attaching the submit handler callback to the form element's onSubmit handler? Are you asking if you can make the onSubmit callback async? This sounds like it'd be a great new post on SO. If you decide to create a new post with accompanying minimal reproducible example feel free to ping me here in a comment with a link to it and I can take a look when available.
yeah i will post the question as new post and let you know..thanks..you are the best react guy on SO!
1

You could write it like this:

export default function App() {
  function handleSubmitTask1() {
    console.log("Execute Task1");
  }

  function handleSubmitTask2() {
    console.log("Execute Task2");
  }

  return (
    <form
      onSubmit={(e) => {
        const buttonName = e.nativeEvent.submitter.name;
        if (buttonName === "button1") handleSubmitTask1();
        if (buttonName === "button2") handleSubmitTask2();
      }}
    >
      <input name="123" />

      <button type="submit" name="button1">
        task 1
      </button>
      <button type="submit" name="button2">
        task 2
      </button>
    </form>
  );
}

The main point is to get the button's name which triggers the form's submission.

1 Comment

this also a solution. Thanks. both are solutions. and completely different approaches
0

Use onClick on the button themselves and add type='submit' to submit it.

export default function Formtwosubmits() {

  function handlesubmit_task1(e){


  }


  function handlesubmit_task2(e){


  }


  return (
    <>
      <form >
        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task1}>
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task2}>
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}

2 Comments

check my edited question. i have tried this, then form validation is not done
you are using "handlesubmit_task1" inverted commas instead of curly braces around it.
0

This worked for me, using event.nativeEvent.submitter.id:

Form (note the id property value is distinct for each button):

<form onSubmit={this.testHandle}>
  <input type="submit" id="btn1" value="Submit button 1" />
  <input type="submit" id="btn2" value="Submit button 2" />
</form>

Handler:

testHandle(event) {
  console.log(event.nativeEvent.submitter.id);
  event.preventDefault();
}

It successfully prints in the console btn1 or btn2, depending on which button of the Form you click.

Note: using React 18.2.0.

Comments

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.