Skip to content

Commit

Permalink
Remove jQuery from select.js
Browse files Browse the repository at this point in the history
- select.js is used to trigger analytics events on select elements
- it seems to be only used by finder-frontend
- it has an option for extra options to be added to the tracking via a data attribute on the select option elements
- this option does not appear to be in use by finder-frontend, and there was no test for it, so I've added one
  • Loading branch information
andysellick committed Sep 4, 2020
1 parent 439a992 commit 219030e
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 69 deletions.
93 changes: 48 additions & 45 deletions app/assets/javascripts/govuk_publishing_components/lib/select.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,55 @@
/* eslint-env jquery */

window.GOVUK = window.GOVUK || {}
window.GOVUK.Modules = window.GOVUK.Modules || {};

(function (Modules) {
'use strict'

Modules.TrackSelectChange = function () {
this.start = function (element) {
element.change(function (e) {
var selectedOption = $(this).find(':selected')
var trackable = '[data-track-category][data-track-action]'

if (selectedOption.is(trackable)) {
fireTrackingChange(selectedOption)
}
})

function fireTrackingChange (element) {
var options = { transport: 'beacon' }
var category = element.attr('data-track-category')
var action = element.attr('data-track-action')
var label = element.attr('data-track-label')
var value = element.attr('data-track-value')
var dimension = element.attr('data-track-dimension')
var dimensionIndex = element.attr('data-track-dimension-index')
var extraOptions = element.attr('data-track-options')

if (label) {
options.label = label
}

if (value) {
options.value = value
}

if (dimension && dimensionIndex) {
options['dimension' + dimensionIndex] = dimension
}

if (extraOptions) {
$.extend(options, JSON.parse(extraOptions))
}

if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
window.GOVUK.analytics.trackEvent(category, action, options)
}
};
function TrackSelectChange () { }

TrackSelectChange.prototype.start = function ($module) {
this.$module = $module[0]
this.$module.trackChange = this.trackChange.bind(this)
this.$module.fireTrackingChange = this.fireTrackingChange.bind(this)
this.$module.addEventListener('change', this.trackChange)
}

TrackSelectChange.prototype.trackChange = function () {
var selectedOption = this.options[this.selectedIndex]

if (selectedOption.hasAttribute('data-track-category') && selectedOption.hasAttribute('data-track-action')) {
this.fireTrackingChange(selectedOption)
}
}

TrackSelectChange.prototype.fireTrackingChange = function (selectedOption) {
var options = { transport: 'beacon' }
var category = selectedOption.getAttribute('data-track-category')
var action = selectedOption.getAttribute('data-track-action')
var label = selectedOption.getAttribute('data-track-label')
var value = selectedOption.getAttribute('data-track-value')
var dimension = selectedOption.getAttribute('data-track-dimension')
var dimensionIndex = selectedOption.getAttribute('data-track-dimension-index')
var extraOptions = selectedOption.getAttribute('data-track-options')

if (label) {
options.label = label
}

if (value) {
options.value = value
}

if (dimension && dimensionIndex) {
options['dimension' + dimensionIndex] = dimension
}

if (extraOptions) {
extraOptions = JSON.parse(extraOptions)
for (var k in extraOptions) options[k] = extraOptions[k]
}

if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
window.GOVUK.analytics.trackEvent(category, action, options)
}
}

Modules.TrackSelectChange = TrackSelectChange
})(window.GOVUK.Modules)
84 changes: 60 additions & 24 deletions spec/javascripts/components/select-spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-env jasmine, jquery */
/* global GOVUK */
/* global GOVUK, Event */

describe('Track select change', function () {
var tracker
Expand All @@ -9,36 +9,72 @@ describe('Track select change', function () {
trackEvent: function () {}
}

beforeEach(function () {
spyOn(GOVUK.analytics, 'trackEvent')

$element = $(
'<select id="taxon-list" name="taxon-list" data-module="track-select-change"' +
'<option value="">All topics</option>' +
'<option data-track-category="filterClicked" data-track-action="taxon-list" data-track-label="Social care" value="7d67047c-bf22-4c34-b566-b46d6973f961">Social care</option>' +
'<option data-track-label="Social care" value="no-data-attributes">No data attributes</option>' +
'</select>'
)

tracker = new GOVUK.Modules.TrackSelectChange()
tracker.start($element)
})

afterEach(function () {
GOVUK.analytics.trackEvent.calls.reset()
})

it('tracks when the selected value is changed', function () {
$element.val('7d67047c-bf22-4c34-b566-b46d6973f961').change()
describe('by default', function () {
beforeEach(function () {
spyOn(GOVUK.analytics, 'trackEvent')

$element = $(
'<select id="taxon-list" name="taxon-list" data-module="track-select-change">' +
'<option value="">All topics</option>' +
'<option data-track-category="filterClicked" data-track-action="taxon-list" data-track-label="Social care" value="7d67047c-bf22-4c34-b566-b46d6973f961">Social care</option>' +
'<option data-track-label="Social care" value="no-data-attributes">No data attributes</option>' +
'</select>'
)

tracker = new GOVUK.Modules.TrackSelectChange()
tracker.start($element)
})

expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
'filterClicked', 'taxon-list', { transport: 'beacon', label: 'Social care' }
)
it('tracks when the selected value is changed', function () {
$element.val('7d67047c-bf22-4c34-b566-b46d6973f961')
var jsSelect = $element[0]
var event = new Event('change')
jsSelect.dispatchEvent(event)

expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
'filterClicked', 'taxon-list', { transport: 'beacon', label: 'Social care' }
)
})

it('does not fire an event if track category and track action are not present', function () {
$element.val('no-data-attributes')
var jsSelect = $element[0]
var event = new Event('change')
jsSelect.dispatchEvent(event)

expect(GOVUK.analytics.trackEvent.calls.count()).toEqual(0)
})
})

it('does not fire an event if track category and track action are not present', function () {
$element.val('no-data-attributes').change()
describe('with options', function () {
beforeEach(function () {
spyOn(GOVUK.analytics, 'trackEvent')

$element = $(
'<select id="taxon-list" name="taxon-list" data-module="track-select-change">' +
'<option value="">All topics</option>' +
'<option data-track-category="filterClicked" data-track-action="taxon-list" data-track-label="Social care" value="7d67047c-bf22-4c34-b566-b46d6973f961" data-track-options=\'{"dimension28": "2x1 plates","dimension29": "1x1 tiles"}\'>Social care</option>' +
'<option data-track-label="Social care" value="no-data-attributes">No data attributes</option>' +
'</select>'
)

tracker = new GOVUK.Modules.TrackSelectChange()
tracker.start($element)
})

it('includes extra options when present on the select', function () {
$element.val('7d67047c-bf22-4c34-b566-b46d6973f961')
var jsSelect = $element[0]
var event = new Event('change')
jsSelect.dispatchEvent(event)

expect(GOVUK.analytics.trackEvent.calls.count()).toEqual(0)
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
'filterClicked', 'taxon-list', { transport: 'beacon', label: 'Social care', dimension28: '2x1 plates', dimension29: '1x1 tiles' }
)
})
})
})

0 comments on commit 219030e

Please sign in to comment.