Skip to content

Commit

Permalink
Re-write 'select all'
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmhaig committed Oct 20, 2023
1 parent 5629cd9 commit 1f3813f
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@
= govuk_table_thead do
= govuk_table_row do
= govuk_table_th do
= govuk_link_to t('.select_all'), '#', class: 'select-all', data: { 'all-checked': 'false' }, 'aria-label': t('.select_all_label')
.govuk-form-group{ data: { module: 'govuk-select-all', 'select-all-class': 'select-all', 'collection-class': 'select-all-box' } }
.govuk-checkboxes.govuk-checkboxes--small{ data: { module: 'govuk-checkboxes' } }
.govuk-checkboxes__item
%input.govuk-checkboxes__input.select-all{ type: :checkbox, name: 'select-all', id: 'select-all', selected: false }
%label.govuk-label.govuk-checkboxes__label{ for: 'select-all' }
%span.govuk-visually-hidden
Select all
= govuk_table_th do
= t('.case_number')
= govuk_table_th do
Expand All @@ -65,7 +71,7 @@
.govuk-form-group.error-message-container
.govuk-checkboxes.govuk-checkboxes--small{ 'data-module': 'govuk-checkboxes' }
.govuk-checkboxes__item
= b.check_box(class: 'govuk-checkboxes__input')
= b.check_box(class: 'govuk-checkboxes__input select-all-box')
= b.label(class: 'govuk-label govuk-checkboxes__label'){ t('.choose_label_html', case_number: claim.case_number) }

- claim.injection_error do |message|
Expand Down
21 changes: 0 additions & 21 deletions app/webpack/javascripts/modules/Modules.SelectAll.js

This file was deleted.

47 changes: 47 additions & 0 deletions app/webpack/javascripts/modules/selectAll.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* SelectAll
*
* A checkbox that is used to automatically select and deselect a collection of other checkboxes.
*
* * data-select-all-class defines the class to identify the 'select all' checkbox
* * data-collection-class defines the class to identify the checkboxes in the collection
*
* <div data-module="govuk-select-all" data-select-all-class="select-all" data-collection-class="select-all-box" >
* <input class="select-all" type="checkbox" />
* </div>
*
* <input class="select-all-box" type="checkbox" id="option_1" />
* <input class="select-all-box" type="checkbox" id="option_2" />
* <input class="select-all-box" type="checkbox" id="option_3" />
* <input class="select-all-box" type="checkbox" id="option_4" />
* <input type="checkbox" id="option_5 /> <!-- not part of the collection" -->
*/
export class SelectAll {
/**
* @param {Element} $module - HTML element to use for component
*/
constructor ($module) {
if (($module instanceof window.HTMLElement) && document.body.classList.contains('govuk-frontend-supported')) {
this.$module = $module
}
}

/**
* Initialise component
*/
init () {
// Check that required elements are present
if (!this.$module) { return }

const selector = this.$module.dataset.selectAllClass
this.collection = this.$module.dataset.collectionClass

this.selectAllBox = this.$module.querySelector(`.${selector}`)
this.selectAllBox.addEventListener('change', () => this.toggleSelection())
}

toggleSelection = () => {
const checkBoxes = document.querySelectorAll(`.${this.collection}`)
checkBoxes.forEach((box) => { box.checked = this.selectAllBox.checked })
}
}
86 changes: 86 additions & 0 deletions app/webpack/javascripts/modules/selectAll_spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { SelectAll } from './selectAll.mjs'

describe('SelectAll', () => {
describe('toggleSelection', () => {
let selectAllBox = null
let selectedBox = null
let unselectedBox = null
let testArea = null

beforeEach(() => {
document.body.classList.add('govuk-frontend-supported')

testArea = document.createElement('div')
document.body.appendChild(testArea)

// <div data-module="govuk-select-all" data-select-all-class="selector-box" data collection-class="pick-me">
// <input class="selector-box" type="checkbox" />
// </div>
const selectAllDiv = document.createElement('div')
selectAllDiv.setAttribute('data-module', 'govuk-select-all')
selectAllDiv.setAttribute('data-select-all-class', 'selector-box')
selectAllDiv.setAttribute('data-collection-class', 'pick-me')
selectAllBox = document.createElement('input')
selectAllBox.type = 'checkbox'
selectAllBox.classList.add('selector-box')
selectAllBox.checked = false
selectAllDiv.appendChild(selectAllBox)
testArea.appendChild(selectAllDiv)

// <input class="pick-me" type="checkbox" name="box1" checked=true>
selectedBox = createCheckbox('pick-me', true, 'box1')
testArea.appendChild(selectedBox)

// <input class="pick-me" type="checkbox" name="box2">
unselectedBox = createCheckbox('pick-me', true, 'box1')
testArea.appendChild(unselectedBox)

const selectAll = new SelectAll(selectAllDiv)
selectAll.init()
})

afterEach(() => {
document.body.classList.remove('govuk-frontend-supported')
testArea.remove()
})

const createCheckbox = (className, checked = false, name = '') => {
const checkbox = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.classList.add(className)
checkbox.name = name
checkbox.checked = checked
return checkbox
}

const toggleSelectAll = () => {
const event = new Event('change')
selectAllBox.checked = !selectAllBox.checked
selectAllBox.dispatchEvent(event)
}

it('should mark all checkboxes as checked', () => {
toggleSelectAll()

expect(selectedBox.checked).toBeTrue()
expect(unselectedBox.checked).toBeTrue()
})

it('should mark all checkboxes as unchecked', () => {
toggleSelectAll()
toggleSelectAll()

expect(selectedBox.checked).toBeFalse()
expect(unselectedBox.checked).toBeFalse()
})

it('should select newly created boxes', () => {
const newBox = createCheckbox('pick-me', false, 'new-box')
document.body.appendChild(newBox)

toggleSelectAll()

expect(newBox.checked).toBeTrue()
})
})
})
1 change: 0 additions & 1 deletion app/webpack/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import '../javascripts/modules/show-hide-content.js'
import '../javascripts/modules/Helpers.FormControls.js'
import '../javascripts/modules/Modules.ReAllocationFilterSubmit.js'
import '../javascripts/modules/Helpers.API.Distance.js'
import '../javascripts/modules/Modules.SelectAll.js'
import '../javascripts/modules/Helpers.API.Core.js'
import '../javascripts/modules/Modules.Messaging.js'
import '../javascripts/modules/Helpers.DataTables.js'
Expand Down
6 changes: 6 additions & 0 deletions app/webpack/packs/govuk-frontend.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '../stylesheets/govuk-frontend.scss'

import { Determination } from '../javascripts/modules/determination.mjs'
import { SelectAll } from '../javascripts/modules/selectAll.mjs'

// fonts & images
require.context('govuk-frontend/govuk/assets', true)
Expand All @@ -10,4 +11,9 @@ determinations.forEach((determination) => {
new Determination(determination).init()
})

const selectAlls = document.querySelectorAll('[data-module="govuk-select-all"]')
selectAlls.forEach((selectAll) => {
new SelectAll(selectAll).init()
})

require('govuk-frontend').initAll()

0 comments on commit 1f3813f

Please sign in to comment.