From e27bdfe7dcd70f7df5dade26c1407e79f6aee9c1 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Wed, 6 Dec 2023 11:09:35 +0000 Subject: [PATCH] Change expander component - allow it to accept data attributes to be applied to the expand/collapse button - will allow us to add GA4 tracking via a Rails/component approach and remove some JS - likely to be a breaking change as will depend on some other stuff in a subsequent commit - brings the component more in line with the option select component changes coming here: https://github.com/alphagov/govuk_publishing_components/pull/3750 --- app/assets/javascripts/components/expander.js | 18 ++++----- app/views/components/_expander.html.erb | 1 + app/views/components/docs/expander.yml | 40 +++++++++++++++++++ spec/components/expander_spec.rb | 16 ++++++++ spec/javascripts/components/expander-spec.js | 25 ++++++------ 5 files changed, 79 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/components/expander.js b/app/assets/javascripts/components/expander.js index 6e0cb9440e..a98cffd57b 100644 --- a/app/assets/javascripts/components/expander.js +++ b/app/assets/javascripts/components/expander.js @@ -69,17 +69,17 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; // if this ; is omitted, none $button.setAttribute('aria-expanded', expanded) $button.setAttribute('aria-controls', this.$content.getAttribute('id')) - // GA4 Accordion tracking. Relies on the ga4-finder-tracker setting the index first, so we wrap this in a custom event. - window.addEventListener('ga4-filter-indexes-added', function () { - if (window.GOVUK.analyticsGa4) { - if (window.GOVUK.analyticsGa4.Ga4FinderTracker) { - window.GOVUK.analyticsGa4.Ga4FinderTracker.addFilterButtonTracking($button, this.$toggle.innerHTML) - } + var buttonAttributes = this.$module.getAttribute('data-button-data-attributes') + if (buttonAttributes) { + buttonAttributes = JSON.parse(buttonAttributes) + for (var rawKey in buttonAttributes) { + var key = rawKey.replace(/_/i, '-').toLowerCase() + var rawValue = buttonAttributes[rawKey] + var value = typeof rawValue === 'object' ? JSON.stringify(rawValue) : rawValue + $button.setAttribute('data-' + key, value) } - }.bind(this)) - + } $button.innerHTML = toggleHtml - this.$toggle.parentNode.replaceChild($button, this.$toggle) } diff --git a/app/views/components/_expander.html.erb b/app/views/components/_expander.html.erb index 81f72a2417..1ea33aa8f5 100644 --- a/app/views/components/_expander.html.erb +++ b/app/views/components/_expander.html.erb @@ -12,6 +12,7 @@ component_helper.add_data_attribute({ "open-on-load": open_on_load }) component_helper.add_class("app-c-expander") component_helper.add_class(shared_helper.get_margin_bottom) unless margin_bottom == 0 + component_helper.add_data_attribute({ "button-data-attributes": button_data_attributes }) if local_assigns.include?(:button_data_attributes) %> <% if title %> <%= tag.div(**component_helper.all_attributes) do %> diff --git a/app/views/components/docs/expander.yml b/app/views/components/docs/expander.yml index cef3e760dd..f13078ffaa 100644 --- a/app/views/components/docs/expander.yml +++ b/app/views/components/docs/expander.yml @@ -28,3 +28,43 @@ examples: margin_bottom: 9 block: | This is some content that is passed to the component. It should be distinct from the component, in that the component should not style or interact with it, other than to show and hide it. + with_counter: + description: If there are form elements within the expander it can display a count of the number of form elements with a selected or input value. This is to make it appear the same as the option select component when appearing with it in search pages. Note that if any form elements are selected on page load, the component will expand by default. + data: + title: Things + block: | +
+ + +
+
+
+ + +
+
+
+ + +
+ with_button_data_attributes: + description: Allows data attributes to be passed to the component to be added to the expand/collapse button. The attributes are written to the parent element then read by the JavaScript and applied to the button. This is used for tracking purposes. + data: + title: Organisation + button_data_attributes: + ga4_expandable: "" + ga4_event: + event_name: "select_content" + type: "finder" + block: | + Sssh I'm hiding diff --git a/spec/components/expander_spec.rb b/spec/components/expander_spec.rb index 88965c2ac2..cd948b8387 100644 --- a/spec/components/expander_spec.rb +++ b/spec/components/expander_spec.rb @@ -42,4 +42,20 @@ def render_component(locals, &block) assert_select '.app-c-expander.govuk-\!-margin-bottom-9' end + + it "accepts button data attributes" do + button_attrs = { + ga4_expandable: "true", + ga4_event: { + event_name: "select_content", + type: "finder", + }, + } + + render_component(title: "Some title", button_data_attributes: button_attrs) do + "This is more info" + end + + assert_select ".app-c-expander[data-button-data-attributes='#{button_attrs.to_json}']" + end end diff --git a/spec/javascripts/components/expander-spec.js b/spec/javascripts/components/expander-spec.js index 6c31840c8c..9cfb140232 100644 --- a/spec/javascripts/components/expander-spec.js +++ b/spec/javascripts/components/expander-spec.js @@ -126,11 +126,19 @@ describe('An expander module', function () { }) }) - describe('GA4 tracking', function () { + describe('adds data attributes to the button', function () { + var buttonAttrs = { + ga4_expandable: '', + ga4_event: { + event_name: 'select_content', + type: 'finder' + } + } + beforeEach(function () { $element = document.createElement('div') $element.innerHTML = html - + $element.querySelector('.app-c-expander').setAttribute('data-button-data-attributes', JSON.stringify(buttonAttrs)) new GOVUK.Modules.Expander($element.querySelector('.app-c-expander')).init() }) @@ -138,17 +146,10 @@ describe('An expander module', function () { $(document).off() }) - it('adds the ga4 event tracker values to the button', function () { + it('adds button data attributes passed to the component onto the button', function () { var $button = $($element).find('.app-c-expander__button') - window.GOVUK.triggerEvent(window, 'ga4-filter-indexes-added') - var expected = JSON.stringify({ - event_name: 'select_content', - type: 'finder', - section: 'Organisation', - index_section: 1, - index_section_count: 3 - }) - + var expected = JSON.stringify(buttonAttrs.ga4_event) + expect($button.attr('data-ga4-expandable')).toEqual('') expect($button.attr('data-ga4-event')).toEqual(expected) }) })