diff --git a/app/assets/javascripts/modules/track-radio-group.js b/app/assets/javascripts/modules/track-radio-group.js index 464100192..107c76024 100644 --- a/app/assets/javascripts/modules/track-radio-group.js +++ b/app/assets/javascripts/modules/track-radio-group.js @@ -1,95 +1,108 @@ window.GOVUK = window.GOVUK || {} -window.GOVUK.Modules = window.GOVUK.Modules || {}; - -(function (global, GOVUK) { - 'use strict' - - var $ = global.jQuery +window.GOVUK.Modules = window.GOVUK.Modules || {} + +// This callback is triggered by the script attached to the DOM by the +// checkVerifyUser function. It has to be outside the module because the script +// can't access the running instance of TrackRadioGroup +window.GOVUK.TrackRadioGroupVerify = function (data) { + window.GOVUK.triggerEvent(document, 'have-verify-data', { detail: data }) +}; + +(function (Modules) { + function TrackRadioGroup (element) { + this.element = element + } - GOVUK.Modules.TrackRadioGroup = function () { - this.start = function (element) { - track(element) + TrackRadioGroup.prototype.init = function () { + document.addEventListener('have-verify-data', function (event) { + this.reportVerifyUser(this.element, event.detail) + }.bind(this)) - if (crossDomainTrackingEnabled(element)) { - addCrossDomainTracking(element) - } + this.track(this.element) - checkVerifyUser(element) + if (this.crossDomainTrackingEnabled(this.element)) { + this.addCrossDomainTracking(this.element) } - function track (element, withHint) { - element.on('submit', function (event) { - var options = { transport: 'beacon' } + this.checkVerifyUser(this.element) + } - var $submittedForm = $(event.target) + TrackRadioGroup.prototype.track = function (element, withHint) { + this.element.addEventListener('submit', function (event) { + var options = { transport: 'beacon' } + var submittedForm = event.target + var checkedOption = submittedForm.querySelector('input:checked') + var eventValue = this.eventTrackingValue(checkedOption, withHint) - var $checkedOption = $submittedForm.find('input:checked') + GOVUK.analytics.trackEvent('Radio button chosen', eventValue, options) - var eventValue = eventTrackingValue($checkedOption, withHint) + if (this.crossDomainTrackingEnabled(submittedForm)) { + this.trackCrossDomainEvent(submittedForm, eventValue, options) + } + }.bind(this)) + } - GOVUK.analytics.trackEvent('Radio button chosen', eventValue, options) + // The analytics data should include whether the user has previously signed in + // to Verify this simulates the behaviour of JSONP, returning a true or false + // value from Verify + TrackRadioGroup.prototype.checkVerifyUser = function (element) { + var url = 'https://www.signin.service.gov.uk/hint' + var timestamp = Math.floor(Date.now() / 1000) + var script = document.createElement('script') + script.setAttribute('src', url + '?callback=window.GOVUK.TrackRadioGroupVerify&_=' + timestamp) + document.body.appendChild(script) + } - if (crossDomainTrackingEnabled($submittedForm)) { - trackCrossDomainEvent($submittedForm, eventValue, options) - } - }) - } + TrackRadioGroup.prototype.trackVerifyUser = function (element, data) { + this.reportVerifyUser(element, data) + } - function checkVerifyUser (element) { - $.ajax({ - url: 'https://www.signin.service.gov.uk/hint', - cache: false, - dataType: 'jsonp', - timeout: 3000 - }).then(function (data) { - reportVerifyUser(element, data) - }, function (e) { console.log('error', e) }) + TrackRadioGroup.prototype.reportVerifyUser = function (element, data) { + if (data != null && data.value === true) { + GOVUK.analytics.trackEvent('verify-hint', 'shown', { transport: 'beacon' }) + this.track(element, data.value) } + } - this.trackVerifyUser = function (element, data) { - reportVerifyUser(element, data) - } + TrackRadioGroup.prototype.eventTrackingValue = function (element, withHint) { + var value = null - function reportVerifyUser (element, data) { - if (data != null && data.value === true) { - GOVUK.analytics.trackEvent('verify-hint', 'shown', { transport: 'beacon' }) - track(element, data.value) - } + if (typeof element === 'undefined' || element === null) { + value = 'submitted-without-choosing' + } else { + value = element.value } - function eventTrackingValue (element, withHint) { - var value = element.val() - - if (typeof value === 'undefined') { - value = 'submitted-without-choosing' - } - - if (withHint) { - value += '-with-hint' - } - return value + if (withHint) { + value += '-with-hint' } + return value + } - function addCrossDomainTracking (element) { - var code = element.attr('data-tracking-code') - var domain = element.attr('data-tracking-domain') - var name = element.attr('data-tracking-name') + TrackRadioGroup.prototype.addCrossDomainTracking = function (element) { + var code = element.getAttribute('data-tracking-code') + var domain = element.getAttribute('data-tracking-domain') + var name = element.getAttribute('data-tracking-name') - GOVUK.analytics.addLinkedTrackerDomain(code, name, domain) - } + GOVUK.analytics.addLinkedTrackerDomain(code, name, domain) + } - function trackCrossDomainEvent (element, eventValue, options) { - var name = element.attr('data-tracking-name') - var eventOptions = $.extend({ trackerName: name }, options) - GOVUK.analytics.trackEvent('Radio button chosen', eventValue, eventOptions) + TrackRadioGroup.prototype.trackCrossDomainEvent = function (element, eventValue, options) { + var name = element.getAttribute('data-tracking-name') + if (name) { + options.trackerName = name } - function crossDomainTrackingEnabled (element) { - return ( - typeof element.attr('data-tracking-code') !== 'undefined' && - typeof element.attr('data-tracking-domain') !== 'undefined' && - typeof element.attr('data-tracking-name') !== 'undefined' - ) - } + GOVUK.analytics.trackEvent('Radio button chosen', eventValue, options) } -})(window, window.GOVUK) + + TrackRadioGroup.prototype.crossDomainTrackingEnabled = function (element) { + return ( + element.getAttribute('data-tracking-code') && + element.getAttribute('data-tracking-domain') && + element.getAttribute('data-tracking-name') + ) + } + + Modules.TrackRadioGroup = TrackRadioGroup +})(window.GOVUK.Modules) diff --git a/spec/javascripts/track-radio-group.spec.js b/spec/javascripts/track-radio-group.spec.js index 205fbc01f..d12ce6326 100644 --- a/spec/javascripts/track-radio-group.spec.js +++ b/spec/javascripts/track-radio-group.spec.js @@ -13,23 +13,27 @@ describe('A radio group tracker', function () { spyOn(GOVUK.analytics, 'trackEvent') element = $( - '
' + - '
' + - '' + - '' + - '' + - '' + - '
' + - '
' - ) - - tracker = new GOVUK.Modules.TrackRadioGroup() - tracker.start(element) + '
' + + '' + + '' + + '' + + '' + + '
' + ) + + $('body').append(element) + + tracker = new GOVUK.Modules.TrackRadioGroup(element[0]) + tracker.init() + }) + + afterEach(function () { + element.remove() }) it('tracks government-gateway checked radio when clicking submit', function () { element.find('input[value="government-gateway"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'Radio button chosen', 'government-gateway', { transport: 'beacon' } @@ -38,7 +42,7 @@ describe('A radio group tracker', function () { it('tracks govuk-verify checked radio when clicking submit', function () { element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'Radio button chosen', 'govuk-verify', { transport: 'beacon' } @@ -52,7 +56,7 @@ describe('A radio group tracker', function () { } tracker.trackVerifyUser(element, data) element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'verify-hint', 'shown', { transport: 'beacon' } @@ -75,7 +79,7 @@ describe('A radio group tracker', function () { 'verify-hint', 'shown', { transport: 'beacon' } ) element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'Radio button chosen', 'govuk-verify', { transport: 'beacon' } @@ -92,7 +96,7 @@ describe('A radio group tracker', function () { } tracker.trackVerifyUser(element, data) element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith( 'verify-hint', 'shown', { transport: 'beacon' } @@ -109,7 +113,7 @@ describe('A radio group tracker', function () { var data = null tracker.trackVerifyUser(element, data) element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith( 'verify-hint', 'shown', { transport: 'beacon' } @@ -126,7 +130,7 @@ describe('A radio group tracker', function () { var data = 'string' tracker.trackVerifyUser(element, data) element.find('input[value="govuk-verify"]').trigger('click') - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith( 'verify-hint', 'shown', { transport: 'beacon' } @@ -140,7 +144,7 @@ describe('A radio group tracker', function () { }) it('tracks no choice when clicking submit and checked nothing', function () { - element.find('form').trigger('submit') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'Radio button chosen', 'submitted-without-choosing', { transport: 'beacon' } @@ -148,20 +152,17 @@ describe('A radio group tracker', function () { }) describe('cross domain tracking enabled', function () { - var $form - beforeEach(function () { tracker.trackVerifyUser(element, { status: 'OK', value: true }) spyOn(GOVUK.analytics, 'addLinkedTrackerDomain') - $form = element.find('form') - $form.attr('data-tracking-code', 'UA-xxxxxx') - $form.attr('data-tracking-domain', 'test.service.gov.uk') - $form.attr('data-tracking-name', 'testTracker') + element.attr('data-tracking-code', 'UA-xxxxxx') + element.attr('data-tracking-domain', 'test.service.gov.uk') + element.attr('data-tracking-name', 'testTracker') - tracker = new GOVUK.Modules.TrackRadioGroup() - tracker.start($form) + tracker = new GOVUK.Modules.TrackRadioGroup(element[0]) + tracker.init() }) it('adds a linked tracker as the module is started', function () { @@ -171,8 +172,8 @@ describe('A radio group tracker', function () { }) it('sends an event to the linked tracker when the form is submitted', function () { - $form.find('input[value="govuk-verify"]').trigger('click') - $form.trigger('submit') + element.find('input[value="govuk-verify"]').trigger('click') + element.find('button').trigger('click') expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith( 'Radio button chosen', 'govuk-verify-with-hint', { trackerName: 'testTracker', transport: 'beacon' }