philipp philipp - 3 months ago 10
Javascript Question

Observe Form Submission

In my application I need to submit forms via JavaScript. I know that I can do that with this code:

[...document.querySelectorAll('form')].forEach(form => {
form.addEventListener('submit', e => {
//doing the processing here
e.preventDefault();
})
})


From the server I get completely generated forms as HTML, which I inject into the DOM (or delete them from there), whenever necessary. By doing so, the registered event handlers stop to work, because the form element is either deleted or not registered.

Is it possible to register a global »Submission Listener«, comparable to that:

window.addEventListener('click' e => { … });


what will never be removed if the DOM changes, or will I have to register the submission handlers each time the DOM changes?

Is not a dublicate, because the mentioned delegation strategy is what I am looking for, but not for click events, for submission events instead.

Answer

You can definitely catch submit events as they bubble up, so what you want can be achieved by listening from a parent element that is always present as the dynamic forms are added and removed. I like doing this thing with a wrapper element with an ID, as opposed to listening a the body or html level. Here's a very simple example using just vanilla js. Codepen here: http://codepen.io/bsidelinger912/pen/RGbWYb

HTML:

<div id="form-wrapper">
  <h2>Form 1</h2>
  <form id="form1">
    <input name="test" placeholder="enter something" />
    <input type="submit" value="submit" />
  </form>

  <h2>Form 2</h2>
  <form id="form2">
    <input name="test" placeholder="enter something" />
    <input type="submit" value="submit" />
  </form>
</div>
<button id="form-adder">
  + Add a form
</button>

Javascript

var formWrapper = document.getElementById('form-wrapper');

// capture the submit event in the parent div
formWrapper.addEventListener("submit", function(e) {
  e.preventDefault();
  console.log('submit captured');

  var thisForm = e.srcElement || e.originalTarget;
  console.log('form id:' + thisForm.id);
  console.log(thisForm.test.value);
});

// dynamically add divs and see we can still capture the submit
var divNum = 3;
function addDiv(e) {
  e.preventDefault();

  formWrapper.innerHTML += '<h2>Form ' + divNum + '</h2>\
  <form id="form' + divNum + '">\
    <input name="test" placeholder="enter something" />\
    <input type="submit" value="submit" />\
  </form>';

  divNum++;
}

document.getElementById('form-adder').addEventListener('click', addDiv);