From 3efbb619c9b9bb02f38358c1786fcda11167298e Mon Sep 17 00:00:00 2001 From: Alex Jurubita Date: Wed, 22 May 2019 11:31:26 +0100 Subject: [PATCH 1/2] Set debounceFormSubmitTimer at instance level instead of global When there are multiple form submit buttons on the page with prevent-double-click enabled they will all reference to the same debounceFormSubmitTimer which means that in a sequence of actions only the first one will called on causing automated end-to-end tests to fail and potentially preventing 'quick' users to be efficient. We're attaching the debounceFormSubmitTimer to each instance so a specific action is stopped from being called multiple times without interfering with other submit button on the page. --- src/components/button/button.js | 11 ++++++----- src/components/button/button.test.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/components/button/button.js b/src/components/button/button.js index f43fdf3ae4..3a7688c6d1 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -1,11 +1,12 @@ import '../../vendor/polyfills/Event' // addEventListener and event.target normaliziation +import '../../vendor/polyfills/Function/prototype/bind' var KEY_SPACE = 32 var DEBOUNCE_TIMEOUT_IN_SECONDS = 1 -var debounceFormSubmitTimer = null function Button ($module) { this.$module = $module + this.debounceFormSubmitTimer = null } /** @@ -41,14 +42,14 @@ Button.prototype.debounce = function (event) { } // If the timer is still running then we want to prevent the click from submitting the form - if (debounceFormSubmitTimer) { + if (this.debounceFormSubmitTimer) { event.preventDefault() return false } - debounceFormSubmitTimer = setTimeout(function () { - debounceFormSubmitTimer = null - }, DEBOUNCE_TIMEOUT_IN_SECONDS * 1000) + this.debounceFormSubmitTimer = setTimeout(function () { + this.debounceFormSubmitTimer = null + }.bind(this), DEBOUNCE_TIMEOUT_IN_SECONDS * 1000) } /** diff --git a/src/components/button/button.test.js b/src/components/button/button.test.js index aaa99215a9..45dc2c7da1 100644 --- a/src/components/button/button.test.js +++ b/src/components/button/button.test.js @@ -102,6 +102,34 @@ describe('/components/button', () => { const submitCount = await page.evaluate(() => window.__SUBMIT_EVENTS) + expect(submitCount).toBe(2) + }) + it('does not prevent subsequent clicks on different buttons', async () => { + await page.goto(baseUrl + '/components/button/prevent-double-click/preview', { waitUntil: 'load' }) + + // Our examples don't have form wrappers so we need to overwrite it. + await page.evaluate(() => { + const $button = document.querySelector('button') + const $buttonPrime = $button.cloneNode() + const $form = document.createElement('form') + $button.parentNode.appendChild($form) + $button.parentNode.removeChild($button) + $form.appendChild($button) + $form.appendChild($buttonPrime) + + window.__SUBMIT_EVENTS = 0 + $form.addEventListener('submit', event => { + window.__SUBMIT_EVENTS++ + // Don't refresh the page, which will destroy the context to test against. + event.preventDefault() + }) + }) + + await page.click('button:nth-child(1)') + await page.click('button:nth-child(2)') + + const submitCount = await page.evaluate(() => window.__SUBMIT_EVENTS) + expect(submitCount).toBe(2) }) }) From 911a52f9899c223096d0e731f1a15236f895276b Mon Sep 17 00:00:00 2001 From: Alex Jurubita Date: Wed, 22 May 2019 12:26:51 +0100 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43cfadce16..f37022e674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -508,6 +508,13 @@ [compatibility mode]: https://github.com/alphagov/govuk-frontend/blob/master/docs/installation/installing-with-npm.md#compatibility-mode +- Allow distinct buttons with `prevent-double-click` enabled to be clicked subsequently within one second + + For buttons with `prevent-double-click` enabled we set the `debounceFormSubmitTimer` for each instance, so a specific action is stopped from being called multiple times without interfering with other submit buttons on the page. + + ([PR #1370](https://github.com/alphagov/govuk-frontend/pull/1370)) + + ## 2.11.0 (Feature release) 🆕 New features: