Created
September 29, 2013 21:56
-
-
Save jguthmiller/6756953 to your computer and use it in GitHub Desktop.
Google Analytics Event Tracking directive in AngularJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.directive('gaTrack', ['$log', 'GoogleAnalyticsService', '$timeout', function ($log, GoogleAnalyticsService, $timeout) { | |
return { | |
//should always be defined as an attribute | |
restrict: 'A', | |
//make sure it executes before other directives applied to the same scope | |
priority: 10, | |
link: function (scope, element, attrs) { | |
//initialize variables for use later | |
var fieldFocus = 0; | |
var fieldSeconds = 0; | |
var ms; | |
var opts = {}; | |
//gaAction is required | |
if(angular.isUndefined(attrs.gaAction)) { | |
$log.error('You must specify an action for Google Analytics event tracking'); | |
return; | |
} | |
//gaLabel is optional | |
//TODO possibly add noninteraction as a supported attribute | |
if(angular.isDefined(attrs.gaLabel)) { | |
opts.label = attrs.gaLabel; | |
} | |
switch(attrs.gaAction) { | |
case 'Click': | |
//bind any click actions to the click event (duh) | |
element.bind('click', function (event) { | |
GoogleAnalyticsService._trackEvent(attrs.gaTrack, attrs.gaAction, opts); | |
//If the click action is bound to an outbound link, | |
//we need to delay the redirect action so that the tracking event has enough time to register | |
//see https://support.google.com/analytics/answer/1136920?hl=en | |
if(element.prop('tagName').toLowerCase() == 'a' && angular.isDefined(element.prop('href')) && angular.isDefined(attrs.gaDelay)) { | |
event.preventDefault(); | |
$timeout(function () { | |
document.location.href = element.prop('href'); | |
}, 100) | |
} | |
}); | |
break; | |
//If the action specified is 'Field Completed', | |
//count the number of seconds the user spent in the field | |
case 'Field Completed': | |
//radio buttons, checkboxes, and submit buttons are ususally clicked | |
//so we'll bind those fields to click events | |
var excludeTypes = ['radio', 'checkbox', 'submit']; | |
//valid html tag types that we want to track the time spent in the field | |
var tagTypes = ['input', 'textarea', 'select']; | |
var tagName = element.prop('tagName').toLowerCase(); | |
var tagType = element.prop('type').toLowerCase(); | |
var timerStarted = false; | |
//only count time spent in inputs, textareas, and select boxes | |
if(tagTypes.indexOf(tagName) !== -1) { | |
//if the input type isn't in the excludeTypes array, count the time spent in the field | |
if(excludeTypes.indexOf(tagType) === -1) { | |
//start the timer on focus | |
element.bind('focus', function () { | |
if(timerStarted === false) { | |
fieldFocus = (new Date()).getTime(); | |
timerStarted = true; | |
} | |
}); | |
element.bind('blur', function () { | |
if(timerStarted) { | |
//stop the timer, and convert milliseconds to seconds | |
timerStarted = false; | |
ms = (new Date()).getTime() - fieldFocus; | |
fieldSeconds = (ms - (ms % 1000)) / 1000; | |
//send the tracking event | |
opts.value = fieldSeconds; | |
GoogleAnalyticsService._trackEvent(attrs.gaTrack, attrs.gaAction, opts); | |
} | |
}); | |
//if the element is not a textarea, | |
//we also need to stop the timer if the user hits enter to submit the form | |
if(tagName != 'textarea') { | |
element.keypress(function (e) { | |
if(e.keyCode == 13) { | |
if(timerStarted) { | |
//stop the timer, and convert milliseconds to seconds | |
timerStarted = false; | |
ms = (new Date()).getTime() - fieldFocus; | |
fieldSeconds = (ms - (ms % 1000)) / 1000; | |
//send the tracking event | |
opts.value = fieldSeconds; | |
GoogleAnalyticsService._trackEvent(attrs.gaTrack, attrs.gaAction, opts); | |
} | |
} | |
}) | |
} | |
} | |
//if the input type IS in the excludeTypes array, trigger the event on click | |
else { | |
element.bind('click', function () { | |
GoogleAnalyticsService._trackEvent(attrs.gaTrack, attrs.gaAction, opts); | |
}) | |
} | |
} | |
break; | |
default: | |
$log.error(attrs.gaAction + ' is not a valid action'); | |
break; | |
} | |
} | |
} | |
}]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment