Extending Auto Event Tracking in Google Tag Manager
BY Doug Hall ON December 12, 2013 | IN Tutorials
This is a alt
2020_04_Headshot_Doug_color.jpg
Doug Hall
Doug has 20+ years industry experience working with global brands on Web Analytics and Conversion Rate Optimization projects. A frequent conference speaker on CRO, Google Analytics, and Tag Management, he has published a wide range of authoritative articles on the subjects.

Introduction

It’s an old adage but the best software has little or no code. Adding code to a system creates more complexity, risk, time and expense.

This is certainly true for Google Tag Manager implementations. Auto Event tracking was rolled out earlier this year and it’s a super fine functional addition – we like it. The events that can be tracked are a little limited for now though. I emphasise ‘for now’ as I’d be very surprised if the subject matter of this post isn’t natively supported very soon.

Cutting to the chase, long story short, here’s how to extend the auto event tracking in GTM cleanly and without adding jQuery (or similar) javascript framework dependencies until the native support is added.

Increasing the cliche quota slightly, there are two types of people using jQuery in GTM, those who have been bitten by dependency issues and those who will be – version incompatibility for example. This technique allows you to extend auto event tracking events with no framework dependency.

The Code Bit

The use case we’ll use is tracking the selection of an item in a drop down on a web page. The issue we have is that using a click event will expose the value selected in the drop down at the time of click rather than change – we need to fire a GTM tag (GA event for example) when the drop down is changed. We need to extend Auto Event Tracking!

I found a very useful article here that got me thinking. Using the addListener method (in a similar fashion to the addEventListener as documented by Google) it’s easy to drop _gaq.push calls into the callback.

I wanted to go another step though. Baking GA calls into the event handler is not ideal. I’d rather have the events fire in the same way as Auto Event

Tracking using a dataLayer push. Pushing the click event on to the dataLayer in the right way will expose gtm.element and all the goodness you can do with that gem in v2 of the dataLayer. You end up with a much more generic solution that has little coupling to your markup or analytics package.

So, start with the addListener method:

function addListener(element, type, callback) {
  if (element.addEventListener) element.addEventListener(type, callback);
  else if (element.attachEvent) element.attachEvent('on' + type, callback);
}

Now, we need to add a listener to our drop down. We can identify the <select> tag to attach the listener to using an ID, name or class but sticking with the idea of building nice, generic event handlers that can be reused, we’ll go find all the <select> tags on the page:

var mySelects = document.getElementsByTagName('select');
selectIndex=mySelects.length;

Now we iterate through all the selects and attach our change event handler:
while(--selectIndex >= 0){
  addListener(mySelects[selectIndex],'change', function(){
    customEvent = {
      "event": "gtm.change",
      "gtm.element": this,
      "gtm.elementClasses": this.className,
      "gtm.elementId": this.id,
      "gtm.elementTarget": this.target
    };
    dataLayer.push(customEvent);
  });    
};

Lets decompose that block to understand it properly:

We tell addListener that the <select> tag in question will fire on change and when it changes we’ll execute the callback block:

addListener(mySelects[selectIndex],'change', function(){

The magic is in specifying the customEvent structure. This allows the change event to fire a GTM event in the same fashion as the current auto event tracking. We get to specify the event type but the rest of the structure is the same as is used in gtm.js – take a look at a beautified version of gtm.js to see this:

customEvent = {
  "event": "gtm.change",
  "gtm.element": this,
  "gtm.elementClasses": this.className,
  "gtm.elementId": this.id,
  "gtm.elementTarget": this.target
};

So, finally, we push the customEvent onto the dataLayer and GTM takes care of the rest. All that script lives in a custom HTML tag that fires on your required pages with a gtm.dom event clause too! Be certain that your markup has loaded before scanning the DOM.

Now we can fire a GA tag based on the GTM event matching gtm.change and the class, ID or name matching the <select> we’re interested in. We add a macro to pull the text of the selected option:

gtm.element.selectedOptions.0.label

You can change this to pull the value if required.

That’s all folks!