From 04aaa425d8c4e4e18c7dd3350e015a3f13f1c648 Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:25:14 +0000 Subject: [PATCH 1/6] Fixed bug where buttons added after page load don't activate JS behaviours Fixes https://github.com/nhsuk/nhsuk-frontend/issues/906 --- packages/components/button/button.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/components/button/button.js b/packages/components/button/button.js index 0653d27c0..2eb8261e8 100644 --- a/packages/components/button/button.js +++ b/packages/components/button/button.js @@ -26,6 +26,7 @@ class Button { event.preventDefault() // trigger the target's click event target.click() + console.log('Space click') } } @@ -63,8 +64,5 @@ class Button { } export default () => { - const buttons = document.querySelectorAll('[data-module="nhsuk-button"]') - buttons.forEach((el) => { - new Button(el).init() - }) + new Button(document).init() } From a29d75da1770565374ebfdc1642e50d01ab032b3 Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:28:53 +0000 Subject: [PATCH 2/6] Changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62c590f9e..d450b203a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Updated header component unit tests ([PR 900](https://github.com/nhsuk/nhsuk-frontend/pull/900)). - Fixed bug where the header didn't align with the main width container ([PR 902](https://github.com/nhsuk/nhsuk-frontend/pull/902)). This fixes [Issue 901](https://github.com/nhsuk/nhsuk-frontend/issues/901) +- Fixed bug where button elements added _after_ the page has loaded would not benefit from the button component's JS behaviours (double click prevention and space bar activation for links). This fixes [issue 906](https://github.com/nhsuk/nhsuk-frontend/issues/906). ([PR 907](https://github.com/nhsuk/nhsuk-frontend/pull/907)). ## 8.0.2 - 19 October 2023 From 82a38b5e7a5af8bd111dfd5589f86bb57e0d79d9 Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:35:38 +0000 Subject: [PATCH 3/6] Remove console log --- packages/components/button/button.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/button/button.js b/packages/components/button/button.js index 2eb8261e8..6092596a0 100644 --- a/packages/components/button/button.js +++ b/packages/components/button/button.js @@ -26,7 +26,6 @@ class Button { event.preventDefault() // trigger the target's click event target.click() - console.log('Space click') } } From 6c750b3adf3159408843907516710dd15915bcc5 Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:36:16 +0000 Subject: [PATCH 4/6] Refactor component initialisation to allow for later reinitialisation within a different scope --- packages/components/button/button.js | 7 ++- .../character-count/character-count.js | 4 +- packages/components/checkboxes/checkboxes.js | 4 +- packages/components/details/details.js | 8 +-- .../components/error-summary/error-summary.js | 4 +- packages/components/radios/radios.js | 4 +- packages/components/tabs/tabs.js | 4 +- packages/nhsuk.js | 51 ++++++++++++------- 8 files changed, 52 insertions(+), 34 deletions(-) diff --git a/packages/components/button/button.js b/packages/components/button/button.js index 6092596a0..3b2a87755 100644 --- a/packages/components/button/button.js +++ b/packages/components/button/button.js @@ -62,6 +62,9 @@ class Button { } } -export default () => { - new Button(document).init() +export default ({ scope = document } = {}) => { + const buttons = scope.querySelectorAll('[data-module="nhsuk-button"]') + buttons.forEach((el) => { + new Button(el).init() + }) } diff --git a/packages/components/character-count/character-count.js b/packages/components/character-count/character-count.js index 6a4f19552..8a96b2344 100644 --- a/packages/components/character-count/character-count.js +++ b/packages/components/character-count/character-count.js @@ -248,8 +248,8 @@ CharacterCount.prototype.defaults = { wordCountAttribute: 'data-maxwords' } -export default () => { - const characterCounts = document.querySelectorAll('[data-module="nhsuk-character-count"]') +export default ({ scope = document } = {}) => { + const characterCounts = scope.querySelectorAll('[data-module="nhsuk-character-count"]') characterCounts.forEach((el) => { new CharacterCount(el).init() }) diff --git a/packages/components/checkboxes/checkboxes.js b/packages/components/checkboxes/checkboxes.js index 39650acf5..6b3ecc197 100644 --- a/packages/components/checkboxes/checkboxes.js +++ b/packages/components/checkboxes/checkboxes.js @@ -54,9 +54,9 @@ const unCheckExclusiveInputs = function unCheckExclusiveInputs(input) { syncAllConditionalReveals(input) } -export default () => { +export default ({ scope = document } = {}) => { // Checkbox input DOMElements inside a conditional form group - const checkboxInputs = document.querySelectorAll('.nhsuk-checkboxes .nhsuk-checkboxes__input') + const checkboxInputs = scope.querySelectorAll('.nhsuk-checkboxes .nhsuk-checkboxes__input') /** * Toggle classes and attributes diff --git a/packages/components/details/details.js b/packages/components/details/details.js index 09c5fe196..70cd993e5 100644 --- a/packages/components/details/details.js +++ b/packages/components/details/details.js @@ -5,7 +5,7 @@ import { toggleAttribute } from '../../common' * Test at http://0.0.0.0:3000/components/details/index.html */ -export default () => { +export default ({ scope = document } = {}) => { // Does the browser support details component const nativeSupport = typeof document.createElement('details').open === 'boolean' if (nativeSupport) { @@ -13,7 +13,7 @@ export default () => { } // Nodelist of all details elements - const allDetails = document.querySelectorAll('details') + const allDetails = scope.querySelectorAll('details') /** * Adds all necessary functionality to a details element @@ -28,11 +28,11 @@ export default () => { if (!element.id) element.setAttribute('id', `nhsuk-details${index}`) // Set content element and give it an ID if it doesn't already have one - const content = document.querySelector(`#${element.id} .nhsuk-details__text`) + const content = scope.querySelector(`#${element.id} .nhsuk-details__text`) if (!content.id) content.setAttribute('id', `nhsuk-details__text${index}`) // Set summary element - const summary = document.querySelector(`#${element.id} .nhsuk-details__summary`) + const summary = scope.querySelector(`#${element.id} .nhsuk-details__summary`) // Set initial summary aria attributes summary.setAttribute('role', 'button') diff --git a/packages/components/error-summary/error-summary.js b/packages/components/error-summary/error-summary.js index 35a584152..2c797c26a 100644 --- a/packages/components/error-summary/error-summary.js +++ b/packages/components/error-summary/error-summary.js @@ -101,9 +101,9 @@ function handleClick(event) { } } -export default ({ focusOnPageLoad = true } = {}) => { +export default ({ focusOnPageLoad = true, scope = document } = {}) => { // Error summary component - const errorSummary = document.querySelector('.nhsuk-error-summary') + const errorSummary = scope.querySelector('.nhsuk-error-summary') if (errorSummary) { // Focus error summary component if it exists diff --git a/packages/components/radios/radios.js b/packages/components/radios/radios.js index 48dba75f5..aaa6a5c63 100644 --- a/packages/components/radios/radios.js +++ b/packages/components/radios/radios.js @@ -5,9 +5,9 @@ import { toggleConditionalInput } from '../../common' * Test at http://0.0.0.0:3000/components/radios/conditional.html */ -export default () => { +export default ({ scope = document } = {}) => { // Radio input HTMLElements inside a conditional form group - const radioInputs = document.querySelectorAll('.nhsuk-radios--conditional .nhsuk-radios__input') + const radioInputs = scope.querySelectorAll('.nhsuk-radios--conditional .nhsuk-radios__input') /** * Update all conditional reveals to match checked state diff --git a/packages/components/tabs/tabs.js b/packages/components/tabs/tabs.js index 75f5bbf9e..6c87bbc16 100644 --- a/packages/components/tabs/tabs.js +++ b/packages/components/tabs/tabs.js @@ -315,8 +315,8 @@ class Tabs { * Tabs({responsive: false}); * Tabs({namespace: 'my-custom-namespace'}); // Alters classes allowing alternative css */ -export default ({ namespace = 'nhsuk-tabs', responsive = true, historyEnabled = true } = {}) => { - const tabs = document.querySelectorAll(`[data-module="${namespace}"]`) +export default ({ namespace = 'nhsuk-tabs', responsive = true, historyEnabled = true, scope = document } = {}) => { + const tabs = scope.querySelectorAll(`[data-module="${namespace}"]`) tabs.forEach((el) => { new Tabs(el, namespace, responsive, historyEnabled).init() }) diff --git a/packages/nhsuk.js b/packages/nhsuk.js index 6334b30a3..7271b52c5 100644 --- a/packages/nhsuk.js +++ b/packages/nhsuk.js @@ -1,25 +1,40 @@ // Components -import Button from './components/button/button' -import CharacterCount from './components/character-count/character-count' -import Checkboxes from './components/checkboxes/checkboxes' -import Details from './components/details/details' -import ErrorSummary from './components/error-summary/error-summary' -import Header from './components/header/header' -import Radios from './components/radios/radios' -import SkipLink from './components/skip-link/skip-link' -import Tabs from './components/tabs/tabs' +import initButton from './components/button/button' +import initCharacterCount from './components/character-count/character-count' +import initCheckboxes from './components/checkboxes/checkboxes' +import initDetails from './components/details/details' +import initErrorSummary from './components/error-summary/error-summary' +import initHeader from './components/header/header' +import initRadios from './components/radios/radios' +import initSkipLink from './components/skip-link/skip-link' +import initTabs from './components/tabs/tabs' import './polyfills' +/** + * Use this function to initialise nhsuk-frontend components within a + * given scope. This function is called by default with the document + * element, but you can call it again later with a new DOM element + * containing nhsuk-frontend components which you wish to initialise. + * + * @param {HTMLElement} scope + */ +export function initAll(scope) { + initButton({ scope }) + initCharacterCount({ scope }) + initCheckboxes({ scope }) + initDetails({ scope }) + initErrorSummary({ scope }) + initRadios({ scope }) + initTabs({ scope }) +} + +window.temp = initAll + // Initialize components document.addEventListener('DOMContentLoaded', () => { - CharacterCount() - Button() - Checkboxes() - Details() - ErrorSummary() - Header() - Radios() - SkipLink() - Tabs() + initHeader() + initSkipLink() + + initAll(document) }) From fec7b8fa4cb0753731ec9adb51af076f6fc1bf4e Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:40:15 +0000 Subject: [PATCH 5/6] Update changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d450b203a..537869795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ - Updated header component unit tests ([PR 900](https://github.com/nhsuk/nhsuk-frontend/pull/900)). - Fixed bug where the header didn't align with the main width container ([PR 902](https://github.com/nhsuk/nhsuk-frontend/pull/902)). This fixes [Issue 901](https://github.com/nhsuk/nhsuk-frontend/issues/901) -- Fixed bug where button elements added _after_ the page has loaded would not benefit from the button component's JS behaviours (double click prevention and space bar activation for links). This fixes [issue 906](https://github.com/nhsuk/nhsuk-frontend/issues/906). ([PR 907](https://github.com/nhsuk/nhsuk-frontend/pull/907)). + +:new: **New features** + +- Add and export new `initAll` method in `nhsuk.js`, and pass document by default, but allowing smaller DOM scopes to be passed. This allows new nhsuk-frontend JS components to be initialised after page load, such as in new pieces of DOM added by JavaScript. + - This fixes [issue 906](https://github.com/nhsuk/nhsuk-frontend/issues/906) where button elements added _after_ the page has loaded would not benefit from the button component's JS behaviours (double click prevention and space bar activation for links). ([PR 907](https://github.com/nhsuk/nhsuk-frontend/pull/907)). ## 8.0.2 - 19 October 2023 From e1f7b70f64d925f5273dd8b6fce8d1d811fabc20 Mon Sep 17 00:00:00 2001 From: Andy Mantell <134642+andymantell@users.noreply.github.com> Date: Mon, 4 Dec 2023 08:31:20 +0000 Subject: [PATCH 6/6] Remove debug line --- packages/nhsuk.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/nhsuk.js b/packages/nhsuk.js index 7271b52c5..f3638a347 100644 --- a/packages/nhsuk.js +++ b/packages/nhsuk.js @@ -29,8 +29,6 @@ export function initAll(scope) { initTabs({ scope }) } -window.temp = initAll - // Initialize components document.addEventListener('DOMContentLoaded', () => { initHeader()