1

I want to submit two forms from a single button in next.js without using document.getElementById.

I am using two form tags and fetching their data in two different objects and I want them to be submitted at once with a single button.

I've tried doing this by document.getElementById.Submit() but it throws an error that document is not defined.

Similar question has been asked on SO but the solution offered is by using JQuery which I can't use.

const submitForms =  function () {

useEffect(()=>
  {
     document.getElementById("form1").submit();
     document.getElementById("form2").submit();

  })
};

Please tell me where am I going wrong?

Star
  • 11
  • 2
  • If you're storing the data for those forms in state when you click the button (which calls a function) you can just stringify the state data and send it to your endpoint and let it deal with it. – Andy Nov 20 '21 at 11:48
  • @Andy I've already tried this and this doesn't work. I need to call a function which submits both forms but unable to do that. – Star Nov 20 '21 at 11:55
  • Please add the code you've attempted to your question as a [mcve]. You can edit your question with a snippet ([which also supports React](https://meta.stackoverflow.com/a/338538/1377002)) by clicking on the `[<>]` button in the edit toolbar. (PS - you shouldn't be using native DOM methods with React so even if you wanted to use `querySelector` you shouldn't.) – Andy Nov 20 '21 at 11:56
  • @Andy I have added a sample code please have a look , and also I've tried using `querrySelector` that aslo didn't worked – Star Nov 20 '21 at 12:04

2 Answers2

1

The basic principle is that you store your form data in state, update the state when the form information changes, and then when the button is clicked, submit the state data to the server endpoint that processes that data.

In this working example we use an object as the state, and assign each form an id (see data attributes). We attach listeners to the forms so that when any of the inputs change we can capture their events as they bubble up the DOM (event delegation).

In the handleChange function we take the id from dataset of the form (currentTarget), and the name and value from the element that was changed (target) - more on the key differences here - and then update the state using that information.

handleClick then stringifies the state, at which point you can submit it to the server endpoint.

It may benefit you to revisit how React works. It has its own way of updating the DOM which means you shouldn't be using any native DOM methods.

const { useEffect, useState } = React;

function Example() {

  // Set the state
  const [ forms, setForms ] = useState({});

  function handleChange(e) {

    // Destructure the id from the dataset of the form
    const { dataset: { id } }  = e.currentTarget;

    // Destructure the name and value from the
    // element that changed
    const { name, value } = e.target;

    // Update the state. We preserve the existing
    // state data using the spread syntax, and set the new
    // value of the property that has the id as key.
    // That new value is an object representing the old
    // value data (again using the spread syntax), and
    // updating the property using the element name and value.
    setForms({
      ...forms,
      [id]: { ...forms[id], [name]: value }
    });
  }
    
  function handleClick() {

    // Stringify the data. You can now use
    // `fetch` or something like Axios to send the
    // data to the server
    console.log(JSON.stringify(forms));
  }

  return (
    <div>
      <form data-id="formone" onChange={handleChange}>
        <fieldset>
          <legend>Form 1</legend> 
          Name: <input name="name" />
          <br/>
          Age: <input name="age" />
        </fieldset>
      </form>
      <form data-id="formtwo" onChange={handleChange}>
        <fieldset>
          <legend>Form 2</legend> 
          Role: <input name="role" />
        </fieldset>
      </form>
      <button
        type="button"
        onClick={handleClick}
      >Submit all form data
      </button>
    </div>
  );
};

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
form, button { margin-top: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Additional documentation

Andy
  • 61,948
  • 13
  • 68
  • 95
0

you can use a function and when form submitted, use in first line of your function:

e.preventDefault()

And when click on another button, call this function and when form is submitted also run this function

Don't use DOM function when work with ReactJs or NextJs