skip to Main Content

I want to send a form by clicking the Submit button. The form originally only consists of a CSRF token. When the user clicks submit, I want to fill up the form using vanilla JS with data gathered on the page.

Now here’s the HTML with the form and an input field which shall be injected afterwards:

<input id="user-input" type="text" name="userInput">

<form id="best-form-ever" method="post" action="/amaze-me">

    <input type="hidden" name="_csrf" value="xyz1234">
    <button id="submit-form" name="submit-form">Submit</button>

</form>

I have the following JavaScript code so far in place:

document.querySelector("#best-form-ever").addEventListener("submit", this.handleSubmit, false);

handleSubmit(event) {
    event.preventDefault();

    const form = document.getElementById("best-form-ever");
    const userInput = document.querySelector("#user-input").innerHTML;

    const payload = new FormData(form);
    payload.append("userInput", userInput);

    payload.submit(); /* this doesn't work :( */
}

Unfortunately, the form won’t get send this way since FormData:submit is not a function.

So here’s my question:
How can I inject additional data to a form after the submit event?

3

Answers


  1. try like this

    document.querySelector("#best-form-ever").addEventListener("submit", this.handleSubmit, false);
    
    function handleSubmit(event) {
        event.preventDefault();
    
        const form = document.getElementById("best-form-ever");
        const userInput = document.querySelector("#user-input").value;
    
        
        document.getElementById("userInput1").value=userInput;
    
        form.submit(); 
    }
    <input id="user-input" type="text" name="userInput">
    
    <form id="best-form-ever" method="post" action="/amaze-me">
    <input type="hidden" id="userInput1" name="userInput">
        <input type="hidden" name="_csrf" value="xyz1234">
        <button id="submit-form" name="submit-form">Submit</button>
    
    </form>
    Login or Signup to reply.
  2. If you set the attribute form on the input element and set the value to the ID of the form, it will be included in the form.

    <input type="text" name="userinput" form="bestformever">
    
    <form id="bestformever" method="post" action="/amaze-me">
      <input type="hidden" name="_csrf" value="xyz1234">
      <button type="submit">Submit</button>
    </form>

    Elements can also be added on the submit event either by setting the form attribute on input elements or by adding elements directly to the form that is submitted:

    document.forms.bestformever.addEventListener('submit', e => {
      let formid = e.target.id;
      
      // input "collected" on the submit event
      [...document.forms.dynamicallyaddedinputs.elements]
        .forEach(elm => elm.setAttribute('form', formid));
      
      // input added to the DOM on the submit event
      e.target.innerHTML += `<input name="calculated" type="hidden" value="${2+3}">`;
    });
    <form name="dynamicallyaddedinputs">
      <input type="text" name="userinput">
    </form>
    
    <form id="bestformever" name="bestformever" method="post" action="/amaze-me">
      <input type="hidden" name="_csrf" value="xyz1234">
      <button type="submit">Submit</button>
    </form>
    Login or Signup to reply.
  3. The main issue is that the submit function doesn’t exactly behave the same as clicking the submit button. From the docs:

    No submit event is raised. In particular, the form’s onsubmit event handler is not run.
    Constraint validation is not triggered.

    However, it looks like requestSubmit does not have such limitations, and will behave exactly the same as clicking submit. Note that this method is run against the Form DOM object, not FormData.

    An easier approach is to manually perform the http request and pass in the FormData object. More documentation on this can be found here: https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript#associating_a_formdata_object_and_a_form

    document.querySelector("#best-form-ever").addEventListener("submit", this.handleSubmit, false);
    
    async function handleSubmit(event) {
      event.preventDefault();
    
      const form = document.getElementById("best-form-ever");
      const userInput = document.querySelector("#user-input").innerHTML;
    
      const payload = new FormData(form);
      payload.append("userInput", userInput);
    
      try {
        const response = await fetch(form.action, {
          method: form.method,
          body: payload
        });
      } catch (e) {
        console.error(e);
      }
    }
    <input id="user-input" type="text" name="userInput">
    
    <form id="best-form-ever" method="post" action="/amaze-me">
    
      <input type="hidden" name="_csrf" value="xyz1234">
      <button id="submit-form" name="submit-form">Submit</button>
    
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search