Sick of the Google Tag Manager built-in form listener not working? This custom form listener can help.
There are many ways to build forms on the web. This means that tracking successful submissions can be challenging, particularly in situations where:
If you need help with something similar to this blog post, then get in touch through my contact page.
Get in touchThis tag adds an indempotent event listener on form submit buttons, and checks the values of the form’s fields before firing either an invalid form submit event, or valid submit event.
There are some caveats to this which I’ll cover in the closing comments.
To use the following code, create a new Custom HTML tag with the custom HTML tag code in Google Tag Manager. Fire the tag on All DOM Ready events. You should also fire this on any route changes for single page apps.
You can change your dataLayer name by updating the dataLayerName
variable, and track forms using the ‘GET’ method by changing postFormsOnly
to false
.
"use strict";
(function() {
//CONFIG///
var dataLayerName = "dataLayer";
var postFormsOnly = true;
///////////
var submitSelect = postFormsOnly ? "form[method='POST'] [type='submit']" : "form [type='submit']";
var formSubmitElements = document.querySelectorAll(submitSelect);
for (var i = 0; i < formSubmitElements.length; i++) {
var ele = formSubmitElements[i];
var listener;
listener = function(ele) {
return (function(event) {
if (ele.form) {
ele = ele.form
} else {
var j = 0;
while (j < 12) {
if (ele.tagName !== 'FORM') {
ele = ele["parentNode"];
if (j === 11) {
throw "Parent form not found.";
}
j++
} else break
}
}
var fields = ele.querySelectorAll("input, textarea, select");
var formState = {
valid: true,
missingRequiredField: false,
missingValidEmail: false,
};
for (var k = 0; k < fields.length; k++) {
var field = fields[k]; //check required
if (field.required === true || field.required === "") {
if (field.value.length === 0) {
formState.valid = false;
formState.missingRequiredField = true;
}
if (field.type === "checkbox" && !field.checked) {
formState.valid = false;
formState.missingRequiredField = true
}
} //check email
if (field.type === "email" || field.name === "email") {
//update later if needed
var isEmail = field.value.search("@") !== -1 && field.value.search(/\./) !== -1 && field.value.length > 3 ? true : false;
if (!isEmail) {
formState.valid = false;
formState.missingValidEmail = true;
}
}
}
var dataLayerEvent = {
form: ele,
formId: ele.id,
formClass: ele.className,
formAction: ele.action,
formMethod: ele.method,
formState: formState,
}
if (formState.valid === false) {
dataLayerEvent['event'] = "invalidFormSubmit";
} else dataLayerEvent['event'] = "validFormSubmit"
window[dataLayerName].push(dataLayerEvent);
})
};
if (ele.customSubmitClickListener !== undefined) {
if (ele.addEventListener) {
ele.removeEventListener("click", ele.customSubmitClickListener, false);
} else if (ele.attachEvent) {
ele.detachEvent("onclick", ele.customSubmitClickListener);
}
}
// add reference to new form listener so the trigger function can use it and we can remove if needed
ele.customSubmitClickListener = listener(ele);
// add new form listener
if (ele.addEventListener) {
ele.addEventListener("click", ele.customSubmitClickListener, false);
} else if (ele.attachEvent) {
// old browsers
ele.attachEvent("onclick", ele.customSubmitClickListener);
}
}
})();
//Latest dataLayer event will go here when you submit the form.
//If you inject GTM into this page to test it, this will stop populating.
If you need help with something similar to this blog post, then get in touch through my contact page.
Get in touchMaking sure you don’t accidentally exclude valid emails is important. You’re better off tracking some false positives than excluding some valid submissions.
With this in mind, my code does a crude check for a valid email address. I’m sure you could probably improve on this, but be careful not to accidentally exclude any valid emails.
I’m certain there are forms out there that won’t work with this code. If they don’t, try editing the code yourself to get it working. Otherwise, post a comment below and I’ll take a look. Good luck!
No comments yet!