SOLVED

Re: Marketo Form Listener Tag in GTM not working

Go to solution
Elsa_Man3
Level 2

Marketo Form Listener Tag in GTM not working

Hello,

After doing a lot of research about how to use GTM to track form submissions into GA as Goal Completions, I mainly followed this article: https://nettlesnet.com/marketo-form-tracking-google-tag-manager-analytics/ 

 

Whenever I preview and test, it works, but after having it live for over a week, the GA goal completions (and even GA events that came in) is drastically lower than the number of actual people who 'filled out form" when I pull it from Marketo as either a Smart List or Landing Page Conversion Report.

 

After some more research, stumbled on a lot of discussions from @SanfordWhiteman to include an eventCallback to the GTM tag, so I did - but upon preview in GTM, it keeps giving me the error "Parse error. '}' expected (screenshot of error attached). 

 

So I have 2 questions:

1. Is this Custom HTML in the GTM tag correct? I have subsequent Trigger (that fires on All Pages) and Universal Analytics Tag to send this back to GA

2. If the above is correct, what's causing this error when I added in the eventCallback?

 

Thanks!

 

 

 

<script>
/**
 * push Marketo form events and values to Google Tag Manager via the data layer
 * uses the Marketo Forms 2.0 API
 */
(function marketoFormListener (MktoForms2) {
    "use strict";
    /**
     * helper function to push invalid Marketo field errors to GTM
     * @returns {undefined}
     */
    function waitForError () {
        var element, input, mktoErrorMsg;
        // check for error message
        element = document.querySelector(".mktoErrorMsg");
        if (element) {
            mktoErrorMsg = element.textContent || element.innerText;
            // look for invalid input
            input = document.querySelector("input.mktoInvalid, .mktoInvalid input");
            window.dataLayer.push({
                "event": "mkto.form.error",
                "mkto.form.error.message": mktoErrorMsg,
                "gtm.element": input,
                "gtm.elementClasses": input && input.className || "",
                "gtm.elementId": input && input.id || "",
                "gtm.elementName": input && input.name || "",
                "gtm.elementTarget": input && input.target || ""
            });
        }
    }
    if (MktoForms2) {
        MktoForms2.whenReady(function handleReady (form) {
            window.dataLayer.push({
                "event": "mkto.form.ready",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });
            form.onValidate(function handleValidate (valid) {
                window.dataLayer.push({
                    "event": "mkto.form.validate",
                    "mkto.form.valid": valid
                });
                // wait for the error message to appear
                setTimeout(waitForError, 0);
            });
            form.onSubmit(function handleSubmit (thisForm) {
                var button;
                button = thisForm.getFormElem().find("button[type=\"submit\"]");
                window.dataLayer.push({
                    "event": "mkto.form.submit",
                    "mkto.form.id": thisForm.getId(),
                    "mkto.form.submittable": thisForm.submittable(),
                    "mkto.form.allFieldsFilled": thisForm.allFieldsFilled(),
                    "mkto.form.values": thisForm.getValues(),
                    "mkto.form.button": {
                        "classes": button.attr("class"),
                        "text": button.text(),
                        "type": "submit"
                    }
                });
            });
            form.onSuccess(function handleSuccess (values, followUpUrl) {
                window.dataLayer.push({
                    "event": "mkto.form.success",
                    "mkto.form.values": values,
                    "mkto.form.followUpUrl": followUpUrl
                    "eventCallback": function () {
                      document.location.href = followUpUrl;
                    },
                      "eventTimeout" : 3000
                  });
                  return false;
                 });
        });
        MktoForms2.whenRendered(function handleRendered (form) {
            window.dataLayer.push({
                "event": "mkto.form.rendered",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });
        });
    }
}(window.MktoForms2));
</script>

 

 

GTM javascript compiler error.png

 

1 ACCEPTED SOLUTION

Accepted Solutions
SanfordWhiteman
Level 10 - Community Moderator

Re: Marketo Form Listener Tag in GTM not working

That setTimeout makes my stomach bubble a little bit... but anyway, you have a missing comma and misplaced parenthesis. Without the syntax errors:

(function marketoFormListener (MktoForms2) {
    "use strict";
    /**
     * helper function to push invalid Marketo field errors to GTM
     * @returns {undefined}
     */
    function waitForError () {
        var element, input, mktoErrorMsg;
        // check for error message
        element = document.querySelector(".mktoErrorMsg");
        if (element) {
            mktoErrorMsg = element.textContent || element.innerText;
            // look for invalid input
            input = document.querySelector("input.mktoInvalid, .mktoInvalid input");
            window.dataLayer.push({
                "event": "mkto.form.error",
                "mkto.form.error.message": mktoErrorMsg,
                "gtm.element": input,
                "gtm.elementClasses": input && input.className || "",
                "gtm.elementId": input && input.id || "",
                "gtm.elementName": input && input.name || "",
                "gtm.elementTarget": input && input.target || ""
            });
        }
    }

    if (MktoForms2) {
        MktoForms2.whenReady(function handleReady (form) {
            window.dataLayer.push({
                "event": "mkto.form.ready",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });

            form.onValidate(function handleValidate (valid) {
                window.dataLayer.push({
                    "event": "mkto.form.validate",
                    "mkto.form.valid": valid
                });
                // wait for the error message to appear
                setTimeout(waitForError, 0);
            });

            form.onSubmit(function handleSubmit (thisForm) {
                var button;
                button = thisForm.getFormElem().find("button[type=\"submit\"]");
                window.dataLayer.push({
                    "event": "mkto.form.submit",
                    "mkto.form.id": thisForm.getId(),
                    "mkto.form.submittable": thisForm.submittable(),
                    "mkto.form.allFieldsFilled": thisForm.allFieldsFilled(),
                    "mkto.form.values": thisForm.getValues(),
                    "mkto.form.button": {
                        "classes": button.attr("class"),
                        "text": button.text(),
                        "type": "submit"
                    }
                });
            });

            form.onSuccess(function handleSuccess (values, followUpUrl) {
                window.dataLayer.push({
                    "event": "mkto.form.success",
                    "mkto.form.values": values,
                    "mkto.form.followUpUrl": followUpUrl,
                    "eventCallback": function () {
                      document.location.href = followUpUrl;
                    },
                    "eventTimeout" : 3000
                  });
                  return false;
             });

        });

        MktoForms2.whenRendered(function handleRendered (form) {
            window.dataLayer.push({
                "event": "mkto.form.rendered",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });
        });
    }
})(window.MktoForms2);

 

View solution in original post

8 REPLIES 8
SanfordWhiteman
Level 10 - Community Moderator

Re: Marketo Form Listener Tag in GTM not working

That setTimeout makes my stomach bubble a little bit... but anyway, you have a missing comma and misplaced parenthesis. Without the syntax errors:

(function marketoFormListener (MktoForms2) {
    "use strict";
    /**
     * helper function to push invalid Marketo field errors to GTM
     * @returns {undefined}
     */
    function waitForError () {
        var element, input, mktoErrorMsg;
        // check for error message
        element = document.querySelector(".mktoErrorMsg");
        if (element) {
            mktoErrorMsg = element.textContent || element.innerText;
            // look for invalid input
            input = document.querySelector("input.mktoInvalid, .mktoInvalid input");
            window.dataLayer.push({
                "event": "mkto.form.error",
                "mkto.form.error.message": mktoErrorMsg,
                "gtm.element": input,
                "gtm.elementClasses": input && input.className || "",
                "gtm.elementId": input && input.id || "",
                "gtm.elementName": input && input.name || "",
                "gtm.elementTarget": input && input.target || ""
            });
        }
    }

    if (MktoForms2) {
        MktoForms2.whenReady(function handleReady (form) {
            window.dataLayer.push({
                "event": "mkto.form.ready",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });

            form.onValidate(function handleValidate (valid) {
                window.dataLayer.push({
                    "event": "mkto.form.validate",
                    "mkto.form.valid": valid
                });
                // wait for the error message to appear
                setTimeout(waitForError, 0);
            });

            form.onSubmit(function handleSubmit (thisForm) {
                var button;
                button = thisForm.getFormElem().find("button[type=\"submit\"]");
                window.dataLayer.push({
                    "event": "mkto.form.submit",
                    "mkto.form.id": thisForm.getId(),
                    "mkto.form.submittable": thisForm.submittable(),
                    "mkto.form.allFieldsFilled": thisForm.allFieldsFilled(),
                    "mkto.form.values": thisForm.getValues(),
                    "mkto.form.button": {
                        "classes": button.attr("class"),
                        "text": button.text(),
                        "type": "submit"
                    }
                });
            });

            form.onSuccess(function handleSuccess (values, followUpUrl) {
                window.dataLayer.push({
                    "event": "mkto.form.success",
                    "mkto.form.values": values,
                    "mkto.form.followUpUrl": followUpUrl,
                    "eventCallback": function () {
                      document.location.href = followUpUrl;
                    },
                    "eventTimeout" : 3000
                  });
                  return false;
             });

        });

        MktoForms2.whenRendered(function handleRendered (form) {
            window.dataLayer.push({
                "event": "mkto.form.rendered",
                "mkto.form.id": form.getId(),
                "mkto.form.submittable": form.submittable(),
                "mkto.form.allFieldsFilled": form.allFieldsFilled(),
                "mkto.form.values": form.getValues()
            });
        });
    }
})(window.MktoForms2);

 

Elsa_Man3
Level 2

Re: Marketo Form Listener Tag in GTM not working

Thanks so much @SanfordWhiteman! GTM preview/tested fine now without those errors and we'll now see if this modification will align the reports with Marketo's better.

 

What was the reason that the setTimeout isn't the best idea? I literally just took the script from the blog so not tied to it.

 

The reason we're going through GTM instead of sending an event directly to GA is because there are hundreds of Marketo LPs live, so to add the additional script on the LP itself to push the event directly to GA wouldn't be scalable for us.

Elsa_Man3
Level 2

Re: Marketo Form Listener Tag in GTM not working

Alright I just pulled some prelim report to see if the GA Goal Completions set for these form.success events are tracking closer to what Marketo's Landing Page Conversion Report numbers are, and GA's is still significantly lower. For example, GA's goal completions is 25 whereas Marketo says 33 - this is over the span of 3 hours only and there's already this gap. I was hoping the missing eventCallback was the key but am I missing something else @SanfordWhiteman ? Any ideas or insights would be greatly appreciated!

SanfordWhiteman
Level 10 - Community Moderator

Re: Marketo Form Listener Tag in GTM not working


. For example, GA's goal completions is 25 whereas Marketo says 33 - this is over the span of 3 hours only and there's already this gap. I was hoping the missing eventCallback was the key but am I missing something else...

We’ll take Marketo’s count as the truth, since the server counts actual form fills.

 

So let’s think about what can make a Marketo form post complete successfully, while a a relayed GA event in an onSuccess listener doesn’t complete, in rough order of descending likelihood:

  1. the custom GA events aren’t being sent because MktoForms2 isn’t always ready when you try to add them(JS race condition)
  2. GA is blocked by Tracking Protection
  3. JS as a whole is blocked

What’s the URL that’s displaying this behavior?

Elsa_Man3
Level 2

Re: Marketo Form Listener Tag in GTM not working

Thanks @SanfordWhiteman - the discrepancies have been on many different URLs. Here are a few examples below. I included the conversions numbers from Marketo report, as well as 3 different metrics in GA - I pulled both the Goal Completion, as well as the number of Events by page (Event Category = Marketo).  

 

Not sure why unique events are still higher than goal completions in GA, when the goal logic itself is the same as the filtered view of the Events in GA. Would love any insights you have to this mind boggler! 

 

URL (period Nov 3 - Nov 6) Marketo Conversions GA Goal Completions GA Total Events GA Unique Events
https://info.wegalvanize.com/sox-management-checklist.html 141 122 136 125
https://info.wegalvanize.com/Death-of-the-Tick-Mark_LP.html 88 76 88 82
https://info.wegalvanize.com/internal-audit-impact-series.html 70 58 66 63
         
SanfordWhiteman
Level 10 - Community Moderator

Re: Marketo Form Listener Tag in GTM not working

What about duplicate detection/avoidance in GA vs. Marketo? Marketo will count 2 form fills by the same lead as 2 “Conversions” for the purposes of the Landing Page Performance report.
Elsa_Man3
Level 2

Re: Marketo Form Listener Tag in GTM not working

Sorry for the late reply @SanfordWhiteman - for some reason I'm not getting email alerts when someone replies anymore. I did spot check a couple in Marketo using a smart list 'filled out form' to take out any duplicates...in some cases it reduces the number but a few but not enough to match closer with GA Goals.

 

There is one landing page I noticed that isn't even pulling any goal completions or events in GA, even though the GTM tag is on the page and Marketo says there are 14 submissions: https://info.wegalvanize.com/auditors-critical-to-vendor-onboarding-webinar.html  

Would you have any insights into this?  THanks! 

SanfordWhiteman
Level 10 - Community Moderator

Re: Marketo Form Listener Tag in GTM not working


What was the reason that the setTimeout isn't the best idea? I literally just took the script from the blog so not tied to it.


Just because JS is an event-driven environment so you should listen for the real event “error message shown” instead of guessing about when it will be shown.

 

In this case, though, the setTimeout is being used to wait for the next turn of the event loop (setTimeout(fn,0)) rather than an arbitrary number of milliseconds. That’s not bad, as long as the library keeps behaving as it currently does (an assumption I make all the time, so shouldn’t have been as harsh about it in this case!).