0

enter image description here

The following code get's loaded after the page is done:

<div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions">

<input data-drupal-selector="edit-submit" type="submit" id="edit-submit--6" name="op" value="Save" class="button button--primary js-form-submit form-submit">

</div>

I'm trying to attach an event to this SAVE button by monitoring the page for this button to get injected. My code has the following: node.value === 'Save' to see if the input button is injected, but doesnt detect it. It looks like the "node" injects the entire FORM block, which is why it's not working.

This is my mutation code that is most likely incorrect somewhere:

// Your ready function
function ready(fn) {
  if (document.readyState !== 'loading') {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

// Function to handle button click
function buttonClickHandler() {
    
      event.preventDefault();
        console.log(event.target.form.reportValidity())
        if (event.target.form.reportValidity()) {
            sendMessageToTelegram('000000000', '-999999999');
            event.target.form.submit(); 
        }
}

// Function to add an event listener to the button when it's added to the DOM
function addButtonEventListener() {
    console.log('add Button Event List......')
    
  // Create a MutationObserver instance to observe changes in the DOM
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.addedNodes) {
        mutation.addedNodes.forEach((node) => {
          // Check if the added node is an input button with the value "Save"
            console.log(node)

          if (node.value === 'Save') {

            // Add the event listener to the button
            node.addEventListener('click', buttonClickHandler);

            // Disconnect the observer once the button is found
            observer.disconnect();
          }
        });
      }
    });
  });

  // Configure the MutationObserver to watch for changes in the entire DOM tree
  const observerConfig = { childList: true, subtree: true };

  var commentForm = document.querySelector('.comment-wrapper');

  // Start observing the DOM
  observer.observe(commentForm, observerConfig);
}

// Execute the addButtonEventListener function when the DOM is ready
ready(addButtonEventListener);
Patoshi パトシ
  • 21,707
  • 5
  • 29
  • 47
  • 2
    Try [event delegation](https://stackoverflow.com/a/27373951) (observing on `window`) instead of MutationObserver. To observe the event earlier than the normal listener you can set `true` in addEventListener's third parameter. – wOxxOm Mar 29 '23 at 21:57

1 Answers1

0

The NodeList supplied in MutationRecord.addedNodes contains only the top-level nodes added to the document. If your input here is added as part of a larger document fragment (i.e. <div ...><input .../></div>) then the input itself will not be in the addedNodes list itself.

You can work around this by searching for your target element within the nodes in the node list, using (for example) querySelector:

        // use `for` rather than `.forEach` so we can break out on success
        for (const node of mutation.addedNodes) {
          // Check if the added node contains an input button with the value "Save"
         
         // The NodeList may contain non-Element Nodes (e.g. text)
         const match = node instanceof Element && node.querySelector("input[value='Save']");

          if (match) {
            console.log(node.id)

            // Add the event listener to the button
            node.addEventListener('click', buttonClickHandler);

            // Disconnect the observer once the button is found
            observer.disconnect();
            break;
          }
        };

The node.querySelector will allow you to be more precise with your search for the target input – perhaps by id, or class. value seems a little brittle and prone to false positives.

motto
  • 2,888
  • 2
  • 2
  • 14