skip to Main Content

I’ve got a case where an external app is injecting a html form into my code. To do anything with the form, I first need to wait on a click event, as the form is only injected once a trigger button is pressed, I’ve then added a delay to make sure the form is loaded and then I need to reload the page, once the form has been submitted.
See my code below

_birthdayRefresh() {
    const birthdayActionButton = document.querySelector(".lion-rule-item--birthday .lion-action-button");
    birthdayActionButton.addEventListener("click", () => {
      setTimeout(() => {
        const birthdayForm = document.querySelector("form.lion-birthday-entry-form");
        if (birthdayForm) {
          birthdayForm.addEventListener("submit", () => {
            location.reload();
          });
        }
      }, 1000);
    });
  }

This kind of works…however, sometimes the page is reloaded before the form has been submitted, I think, and the data from the form isn’t saved. How can I make sure the page reload happens only after the form has been successfully submitted?

2

Answers


  1. Your current implementation adds a delay before attaching the event listener to the form. This can be unreliable because the form might take longer than the set timeout to load, or the page might reload before the form submission is completed.

    A more reliable approach is to attach the event listener directly to the form submission event and only reload the page after the form’s submission has been successfully processed. Here’s an updated version of your function:

    _birthdayRefresh() {
      const birthdayActionButton = document.querySelector(".lion-rule-item--birthday .lion-action-button");
    
      birthdayActionButton.addEventListener("click", () => {
        // Use MutationObserver to watch for changes in the DOM
        const observer = new MutationObserver(mutations => {
          mutations.forEach(mutation => {
            if (!mutation.addedNodes) return;
    
            for (let i = 0; i < mutation.addedNodes.length; i++) {
              let node = mutation.addedNodes[i];
              // Check if the added node is the form you are interested in
              if (node.matches && node.matches("form.lion-birthday-entry-form")) {
                node.addEventListener("submit", (event) => {
                  event.preventDefault(); // Prevent the default form submission
    
                  // Implement the form submission logic here.
                  // You can use AJAX or fetch API to submit the form data.
    
                  // After successful form submission, reload the page.
                  location.reload();
                });
    
                // Once the form is detected and event listener is attached, disconnect the observer
                observer.disconnect();
              }
            }
          });
        });
    
        // Start observing the document for added nodes
        observer.observe(document.body, {
          childList: true,
          subtree: true
        });
      });
    }
    
    Login or Signup to reply.
  2. Try to use MutationObserver. This is a more robust way to detect when the form is added to the DOM. It’s a built-in feature of modern browsers that allows you to observe changes to the DOM and execute code when these changes occur. Obviously, setTimeout doesn’t guarantee that some external form is fully loaded.

    _birthdayRefresh() {
       const birthdayActionButton = document.querySelector(".lion-rule-item-- 
            birthday .lion-action-button");
    
     birthdayActionButton.addEventListener("click", () => {
        // Create a MutationObserver to observe changes in the DOM
        const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
          mutation.addedNodes.forEach(node => {
            if (node.matches && node.matches('form.lion-birthday-entry-form')) {
              // Once the form is added, attach the submit event listener
              node.addEventListener('submit', () => {
                location.reload();
              });
    
              // Stop observing once the form is found
              observer.disconnect();
            }
        });
      });
    });
    
        // Start observing the DOM for added nodes
        observer.observe(document.body, { childList: true, subtree: true });
      });
    }
    

    The code isn’t tested so, please use it carefully. Also please add type="button" to your trigger button. If you don’t specify it it might accidentally submit the form

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search