Dynamically injected AJAX form submission broken

Hi,

We’re using the Advanced Ads plugin to inject ads with a GF email field for a client’s newsletter subscription. The form relies on AJAX for the submission process and displays a confirmation text after a successful sign-up.

Since the newsletter callout ad rotates on load, we’re using the plugin’s passive cache busting feature: Cache Busting: Enhancing Ad Display Efficiency | Advanced Ads.

Since GravityForms updated its AJAX submission process in its 2.9.0 update the form submission is broken.

When submitting the ad/form, injected via passive cache busting, the following error is shown in the dev console:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'getAttribute')

Occurring in scripts-theme.min.js on line 172 in the latest version of the plugin:

        , s = function(e) {
                console.log("s() called with element:", e);
                var t = e.getAttribute("data-formid")
                  , n = document.querySelectorAll(".gform_wrapper form");
                n && n.forEach((function(e) {
                    e.removeAttribute("data-active-form"),
                    e.getAttribute("data-formid") === t && e.setAttribute("data-active-form", "true")
                }
                ))
            }

Adding a console log to output the event, shows that the value as null.

This indicates that the script is trying to access the data-formid attribute on an element that doesn’t exist in the DOM at the time of execution. Since the GravityForm is being dynamically injected into an Advanced Ads ad (with passive cache-busting enabled), the form element isn’t present when the script is initialized — I’m guessing.

As part of Advanced Ads Javascript API, they do have a way to detect when a passive cache busting ad is injected into the DOM. From there it’s possible to also find the Gravity Form.

I’m looking for a way to reinitialize the Gravity Form scripts so that they can account for this dynamic addition. Something like:

reinitializeGravityForms() {
    if (typeof advanced_ads_pro === 'object') {
      advanced_ads_pro.observers.add(function(event) {
        if (event.event === 'inject_passive_ads') {
          console.log("Passive ad injected:", event);

          // Loop over each placement key in the ad_ids object
          Object.keys(event.ad_ids).forEach(function(placementKey) {
            var calloutIDs = event.ad_ids[placementKey];

            console.log(calloutIDs)

            calloutIDs.forEach(function(calloutId) {
              // Find the ad container using the data-callout-id attribute
              var adContainer = document.querySelector('[data-callout-id="' + calloutId + '"]');
              if (adContainer) {
                // Look for a Gravity Form inside the ad container (form IDs begin with "gform_")
                var form = adContainer.querySelector('form[id^="gform_"]');
                if (form) {

                  var formId = form.getAttribute('id');

                  console.log(formId)

                  console.log("Found GF form in callout " + calloutId);
                  // Reinitialize Gravity Forms
                  if ( typeof gform !== 'undefined' && typeof gform.initializeOnLoaded === 'function' ) {
          
                  } else {
                    console.error("Gravity Forms initialization function not found.");
                  }
                } else {
                  console.log("No Gravity Form found in ad container for callout " + calloutId);
                }
              } else {
                console.log("No ad container found with data-callout-id " + calloutId);
              }
            });
          });
        }
      });
    }
  }

However, I haven’t been able to make this work, and am not entirely sure if this is the correct approach.