Shoora
7/11/2014 - 2:53 PM

Track outbound links and form submits with Google Analytics Universal code

Track outbound links and form submits with Google Analytics Universal code

/**
 * Create a Tracker module for Google Analytics
 *
 * This tracker enables to track clicks on links and submits on forms. Usually
 * these events will not be recorded as the window.location is changed and the
 * request to Google Analytics is cancelled. This module prevents default
 * behaviour, tracks the Google Analytics event and then continues the link/submit.
 *
 * Data attributes are used to augment the event with category/action/label values.
 * Use them as "data-track-category", "data-track-action" and "data-track-label".
 *
 * Usage of the module: initiate the tracker with a selector matching all links/
 * forms to be tracked. Example: var tracker = new Tracker('.tracking-link');
 *
 * @copyright   2014 Soflomo.
 * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @author      Jurian Sluiman
 */
var Tracker = (function(document, window){
    /** Utility method to universally add listeners */
    function addListener(element, type, callback) {
        if (element.addEventListener) element.addEventListener(type, callback);
        else if (element.attachEvent) element.attachEvent('on' + type, callback);
    }

    /** Utility method to track the event on an element */
    function track(element, callback) {
        var type = 'event', attrs = element.attributes, vars = ['category', 'action', 'label', 'value'],
            options = {
                'hitType':     type,
                'hitCallback': callback,
            }

        // Add event* properties to options object based on vars array
        for (var i in vars) {
            var name = vars[i], attr = attrs['data-track-' + name];
            if (typeof(attr) !== 'undefined') {
                options['event' + name.charAt(0).toUpperCase() + name.slice(1)] = attr.value;
            }
        }

        ga('send', {
            'hitType':       type,
            'eventCategory': attr['data-track-category'],
            'eventAction':   attr['data-track-action'],
            'eventLabel':    attr['data-track-label'],
            'eventValue':    attr['data-track-value'],
            'hitCallback':   callback
        });
    }

    /** Add GA tracker to clicks on hyperlinks */
    function attachToLink(element) {
        addListener(element, 'click', function(e){
            e.preventDefault();

            var href = this.href;
            track(this, function(){
                window.location.href = href;
            })
        });
    }

    /** Add GA tracker to submit of forms */
    function attachToForm(element) {
        addListener(element, 'submit', function(e){
            e.preventDefault();

            var form = this;
            track(this, function(){
                form.submit();
            })
        });
    }

    var module = function (selector) {
        // We do not initiate all the listeners when GA is not loaded
        if (typeof ga === 'undefined') return;

        var elements = document.querySelectorAll(selector),
            length   = elements.length;

        for(i=0; i<length; i++) {
            var element = elements[i];
            switch(element.tagName.toLowerCase()) {
                case 'a':
                    attachToLink(element);
                    break;
                case 'form':
                    attachToForm(element);
                    break;
            }
        }
    };

    module.prototype = {
        constructor: module
    };
    return module;
})(document, window);