Home > OS >  Form submits despite preventDefault() because of a different EventListener
Form submits despite preventDefault() because of a different EventListener

Time:01-09

I have two EventListeners, one to handle a form and the other for 'Add to Cart' buttons. When the events are fired, a post request is sent to the server which handles the according data, so i need the form to not be submitted but be handled by the server instead.

Before implementing the EventListeners which handles the 'Add to cart' buttons, the form was working as intended with the use of event.preventDefault();. With the buttons' EventListener however the form now submits and directs me to /login. I have tried every solution I found, I used .stopPropagation(), .preventDefault() and return=false; to both listeners, I changed the buttons to div elements. However the form is not working as intended unless I completely remove the second EventListener.

I would go on replacing the form element with a div but it needs to stay as an HTML form, so I have to work out a solution to this.

I'm including the code below, thanks in advance:

window.onload =function formSubmit(){
  const form = document.getElementById('login-form');
  form.addEventListener('submit', event => {
    
    event.preventDefault(); // prevent the form from submitting
    const username = form.elements.username.value;
    const password = form.elements.password.value;
    login(username, password);
      
  });
}

//addbuttons are added dynamically after the other elements are already loaded so im putting a timeout for queryselector to gather them
setTimeout(window.onload =function productRequest(){
  const purchaseBtns = document.querySelectorAll('.purchase-button');

  purchaseBtns.forEach((btn) =>{
      btn.addEventListener('click', () => {
      var product_selected;
      for(i in products){
        if(products[i].id == btn.dataset.productId){
          product_selected = products[i];
        }
      }
      addToCart(product_selected);

    });
    
  });
  
}, 1000);

CodePudding user response:

window.onload can store ONE function... No more.

Seems like the first one fires... And not the second because at that point, the load event already fired (before the second assignement overwrote the first, that is after the first timeout).

So try with one load event listener:

document.addEventListener("load", function(){
  
  // Form's event listener
  const form = document.getElementById('login-form');
  form.addEventListener('submit', event => {
    
    event.preventDefault(); // prevent the form from submitting
    const username = form.elements.username.value;
    const password = form.elements.password.value;
    login(username, password);
  });
  
  
  // Buttons event listeners setting 1 second after page load
  setTimeout(() => {
    const purchaseBtns = document.querySelectorAll('.purchase-button');
    purchaseBtns.forEach((btn) =>{
      btn.addEventListener('click', (event) => {
      
        // Prevent the event from bubbling to the form if the buttons are inside it
        event.stopPropagation()

        // and obviously, also prevent submit
        event.preventDefault();
        
        var product_selected;
        for(i in products){ // Hoping you have that products defined...
          if(products[i].id == btn.dataset.productId){
            product_selected = products[i];
          }
        }
        addToCart(product_selected);
      });
    });
  }, 1000)
  
})  // end of the load event handler
  • Related