I have this Landing Page in Marketo: Download Mobile Usability Report 2014
I want to track conversions in GA. It seems the best way to do this is by setting the download action on the button to be a GA Event.
I added this code and it does not fire any events into GA...
$(document).ready(function() { $("form#mktoForm_1012").each(
function() { var jqForm = $(this); var jsForm = this; var action = jqForm.attr("action"); jqForm.submit(function(event) { // when someone submits the form(s) event.preventDefault(); // don't submit the form yet _gaq.push(["_trackEvent", "Reports", "Downloaded", action, , false]); // create a custom event setTimeout(function() { // now wait 300 milliseconds... jsForm.submit(); // ... and continue with the form submission },300); }); }); });
Can anyone help me please?
Solved! Go to Solution.
Yea probably. It sounds like you're using the new landing pages and my instructions are for free-form pages. You basically just want that last section of code where you would put any custom HTML for the actual landing page, not in the header.
I've actually done this before. It's a little tricky because you need the scripts to fire in the right order, which is easiest to manage if you put the scripts in the template. Here's the approach that worked for me:
1. Add this script in the <head> section of the landing page template. Replace XXXX with your pod info from the URL to your instance:
<script src="//app-XXXX.marketo.com/js/forms2/js/forms2.js"></script>
2. Add the Google Analytics snippet under the <!--SYSTEM JAVASCRIPT--> section of the template. It should look something like this:
<!-- Analytics Snippet -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
...
</script>
3. Add the form specific script under the <!--START TEMPLATE HTML--> section of the template. This is generic and will apply to any form on the landing page. It should look something like this, though you may not be trying to track all of these events:
<!-- START GOOGLE ANALYTICS CODE HERE -->
<script>
/**
* Sends to Google Analytics events when actions happen on the form
* @date: 2014-08-15
*/
MktoForms2.whenReady(function (form){
var ga_label = document.location.pathname + '#formId=' + form.getId();
// Form Loaded
ga('send', 'event', 'marketo form', 'load', ga_label);
// Initiation
var _gaFormInitiated = false;
form.getFormElem().find(':input').change(function(){
//alert ("Form Initiation");
if (!_gaFormInitiated){
_gaFormInitiated = true;
ga('send', 'event', 'marketo form', 'initiate', ga_label);
}
});
// Click the submit button
form.onSubmit(function(values, followUpUrl){
//alert ("Form Submitting");
// Form submitted
ga('send', 'event', 'marketo form', 'submit', ga_label);
return true;
});
// Check if form is valid
form.onValidate(function(values, followUpUrl) {
if (values) {
ga('send', 'event', 'marketo form', 'validation_error', ga_label);
}
return true;
});
// Form successfully Validate
form.onSuccess(function(values, followUpUrl){
//alert ("Form Successfully Validated");
// Form success
ga('send', 'event', 'marketo form', 'success', ga_label);
return true;
});
});
</script>
Thank you Kristen.
Steps 1 and 2 seem fine (have added to the template and I can see the page content in GA Real Time).
I could not find a "<!--START TEMPLATE HTML-->" section in the template. Could that be "<!-- Base of Landing Page Content -->"?
Lee
Yea probably. It sounds like you're using the new landing pages and my instructions are for free-form pages. You basically just want that last section of code where you would put any custom HTML for the actual landing page, not in the header.
If I may adapt Kristen Carmean's version to guided LPs, with Google UA (GTM is a different story).
First add some Marketo variables in the <head> to be able to ajust the info sent to GA :
<meta class="mktoBoolean" id="z-TriggerGAEvent" mktoName="Trigger GA Event" default="true" true_value="YES" false_value="NO" false_value_name="NO" true_value_name="YES">
<meta class="mktoString" id="z-GAEventCategory" mktoName="GA Event Category" default="form" allowHtml="false">
<meta class="mktoString" id="z-GAEventAction" mktoName="GA Event Action" default="submit" allowHtml="false">
The first variable will enable the user to decide whether or not a GA event should be triggered, and the 2 other variable will define the event category and action. The event label is defined by the code below and will contain the URL and the form ID.
Then in the <head> of the template, add your UA code which looks like this one :
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
...
</script>
Finally, add the following code at the bottom of the template, just before the </body> tag. It will trigger the GA event on form success :
<script>
MktoForms2.whenReady(function (form) {
var ga_label = document.location.pathname + '#formId=' + form.getId();
form.onSuccess(function(){
if ( 'YES' == '${z-TriggerGAEvent}') {
ga('send','event','${z-GAEventCategory}','${z-GAEventAction}',ga_label);
}
});
});
</script>
Code tested and works.
-Greg
You're preventing the default action but not providing a return to the process. Try this.. Let me know if that helps.
$('#mktoForm_1012').submit(function(event){
var send = false; // To test against and stop submission.
var actionVal = $(this).attr('action'); // Get your "action" variable
if (send == false) {
// call your GA stuff
_gaq.push(["_trackEvent", "Reports", "Downloaded", action, , false]);
setTimeout(function(){ // Wait 300 milliseconds
return; // Returns TRUE to proceed with submission and end this flow.
}, 300);
}
event.preventDefault(); // Just for safety we stop sumission here.
});
Hey Hussam, not sure what you think your setTimeout() is doing in this code, but it isn't "waiting." setTimeout calls the passed function asynchronously. JavaScript is single-threaded and any code block always runs to completion, so that empty "wait" function will not fire until after the submit handler is finished firing (i.e. after event.preventDefault()). It also will hit the scheduler after the asynchronous methods executed inside _gaq.push(). And optimizing compilers might even remove your empty function completely when compiling, as there's no reason to schedule code that is known in advance to do nothing.
Also, attaching the form's native submit event isn't correct with Marketo Forms 2.0. You must use the Forms 2.0 API to be assured of event order. For example, in your example the _gaq.push() fires even if the form doesn't pass Marketo's field validation. See Kristen's code in which she correctly (as she works for Marketo!) uses the API's submit, validate, and success events.
Thanks Sanford! Makes sense.
I wasn't sure why Lee had a wait in his code. I actually thought he needed to execute something else during this period. My mistake was looking at the code from a js point of view only. Thanks for pointing these out for me!
The problem with the wait in Lee's original code is that has a terrible race condition. It's rule #1 of async programming that you don't arbitrarily throw in a delay on the guess that another task will probably take some amount of time to return. Or maybe I should say that's not async programming at all, it's just throwing up your hands and hoping for a certain execution order. The right way to do it, of course, is to ensure that the events fire in the right order by having them chained together -- use one event's success/load to trigger the next.
Hi Hussam AlMukhtar,
If I understand well, this is a code that will work for GTM, not for UA.
Best regards,
-Greg