diff --git a/app/assets/sass/components/multi-select.scss b/app/assets/sass/components/multi-select.scss index 22041882d..1b1a09d7b 100644 --- a/app/assets/sass/components/multi-select.scss +++ b/app/assets/sass/components/multi-select.scss @@ -20,8 +20,6 @@ -webkit-appearance: none; appearance: none; max-width: 100%; - - display: block; cursor: pointer; div { @@ -47,48 +45,37 @@ } } -.multi-select-dropdown{ +.multi-select-dropdown { @extend .govuk-clearfix; - top: 0; left: 0; background-color: govuk-colour("white"); z-index: 10; position: absolute; border: 2px solid $govuk-text-colour; - box-sizing: border-box; width: 100%; font-size: 16px; + .multi-select-close-button { + min-height: 34px; + width: 100%; + margin-bottom: 0; + } + .multi-select-dropdown-inner-container { + padding: 10px 5px; overflow-y: scroll; overflow-x: hidden; + + .govuk-checkboxes__item { + label { + width: 100%; + } + } } &:focus { outline: 3px solid $govuk-focus-colour; outline-offset: 0; } - - .multi-select-dropdown-close-area { - width: 15%; - top: 0; - right: 13px; - position: absolute; - z-index: 14; - height: 100%; - background-image: url("/public/images/dd-arrow.svg"); - background-repeat: no-repeat; - background-position: right -4px top 6px; - } - - .govuk-checkboxes__item { - display: flex; - align-items: start; - text-align: left; - cursor: pointer; - input { - z-index: 12; - } - } } diff --git a/app/browsered/multi-select.js b/app/browsered/multi-select.js index 5f09a9a86..521e0003b 100644 --- a/app/browsered/multi-select.js +++ b/app/browsered/multi-select.js @@ -1,4 +1,3 @@ -'use strict' // TODO: we should probably do some browser testing in this project to prove this all works as intended const multiSelect = require('../views/includes/multi-select.njk') @@ -6,15 +5,13 @@ const multiSelect = require('../views/includes/multi-select.njk') // Polyfills introduced as a temporary fix to make Smoketests pass. See PP-3489 require('./polyfills') -// Variables const MAXIMUM_VISIBLE_ITEMS = 8.5 // Maximum amount of items to show in dropdown const MINIMUM_VISIBLE_ITEMS = 3.5 // Minimum amount of items to show in dropdown (assuming total is larger than this value) -// Selectors const ENHANCEMENT_SELECTOR = [...document.querySelectorAll('select[data-enhance-multiple]')] const TOP_LEVEL_SELECTOR = '.multi-select' const OPEN_BUTTON_SELECTOR = '.multi-select-title' -const CLOSE_BUTTON_SELECTOR = '.multi-select-dropdown-close-area' +const CLOSE_BUTTON_SELECTOR = '.multi-select-close-button' const DROPDOWN_SELECTOR = '.multi-select-dropdown' const SCROLL_CONTAINER_SELECTOR = '.multi-select-dropdown-inner-container' const ITEM_SELECTOR = '.govuk-checkboxes__input' @@ -56,11 +53,24 @@ function progressivelyEnhanceSelects () { const dropdown = [...newMultiSelect.querySelectorAll(DROPDOWN_SELECTOR)][0] const scrollContainer = [...newMultiSelect.querySelectorAll(SCROLL_CONTAINER_SELECTOR)][0] + // close if user clicks outside the dropdown + document.addEventListener('click', (event) => { + const dropdowns = document.querySelectorAll(DROPDOWN_SELECTOR) + dropdowns.forEach(dropdown => { + if (!dropdown.contains(event.target) && + !event.target.closest(OPEN_BUTTON_SELECTOR)) { + dropdown.style.visibility = 'hidden' + dropdown.closest(TOP_LEVEL_SELECTOR) + .querySelector(OPEN_BUTTON_SELECTOR) + .setAttribute('aria-expanded', false) + } + }) + }, false) + openButton.addEventListener('click', onOpenButtonClick, false) - closeButton.addEventListener('click', onCloseAreaClick, false) + closeButton.addEventListener('click', onCloseButtonClick, false) items.forEach(item => { item.addEventListener('change', onItemChange, false) - item.addEventListener('blur', onItemBlur, false) }) const itemHeight = ([...items].map(item => item.parentNode.offsetHeight).reduce((sum, value) => sum + value) / items.length) const maxVisibleItems = Math.min(Math.floor(((window.innerHeight - openButton.getBoundingClientRect().top) / itemHeight) - 0.5) + 0.5, MAXIMUM_VISIBLE_ITEMS) @@ -92,29 +102,30 @@ const closeMultiSelectOnEscapeKeypress = function () { } } -const onItemBlur = event => { - const dropdown = event.target.closest(DROPDOWN_SELECTOR) - setTimeout(() => { - if ([...dropdown.querySelectorAll(`${ITEM_SELECTOR}:focus`)].length <= 0) { - dropdown.style.visibility = 'hidden' - dropdown.closest(TOP_LEVEL_SELECTOR).querySelector(OPEN_BUTTON_SELECTOR).setAttribute('aria-expanded', false) - } - }, 100) +const onCloseButtonClick = event => { + const { target } = event + event.stopPropagation() + const dropdown = target.closest(TOP_LEVEL_SELECTOR).querySelector(DROPDOWN_SELECTOR) + dropdown.style.visibility = 'hidden' + target.setAttribute('aria-expanded', false) } const onOpenButtonClick = event => { const { target } = event - target.blur(); - [...target.closest(TOP_LEVEL_SELECTOR).querySelectorAll(DROPDOWN_SELECTOR)][0].style.visibility = 'visible'; - [...target.closest(TOP_LEVEL_SELECTOR).querySelectorAll(ITEM_SELECTOR)][0].focus() - target.closest(OPEN_BUTTON_SELECTOR).setAttribute('aria-expanded', true) -} + event.stopPropagation() + + // close all other dropdowns first + document.querySelectorAll(DROPDOWN_SELECTOR).forEach(dropdown => { + dropdown.style.visibility = 'hidden' + dropdown.closest(TOP_LEVEL_SELECTOR) + .querySelector(OPEN_BUTTON_SELECTOR) + .setAttribute('aria-expanded', false) + }) -const onCloseAreaClick = event => { - const { target } = event; - [...target.closest(TOP_LEVEL_SELECTOR).querySelectorAll(OPEN_BUTTON_SELECTOR)][0].focus(); - [...target.closest(TOP_LEVEL_SELECTOR).querySelectorAll(DROPDOWN_SELECTOR)][0].style.visibility = 'hidden' - target.closest(OPEN_BUTTON_SELECTOR).setAttribute('aria-expanded', false) + const dropdown = target.closest(TOP_LEVEL_SELECTOR).querySelector(DROPDOWN_SELECTOR) + dropdown.style.visibility = 'visible' + dropdown.querySelector(ITEM_SELECTOR).focus() + target.setAttribute('aria-expanded', true) } const onItemChange = event => { diff --git a/app/views/includes/multi-select.njk b/app/views/includes/multi-select.njk index 07c4c23e3..76188ed21 100644 --- a/app/views/includes/multi-select.njk +++ b/app/views/includes/multi-select.njk @@ -1,21 +1,23 @@ -
+
-