From 43935457d87fc95ebac7eb1b90cfb56a8999c743 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Wed, 16 Sep 2020 22:01:36 +0100 Subject: [PATCH] Change live-search so it announces results If there is a search term when the page loads, a statement about the results is added to the searchbox label. All subsequent searches are announced via an aria live-region. --- app/assets/javascripts/liveSearch.js | 36 ++++++++++++++++++++--- app/templates/components/live-search.html | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/liveSearch.js b/app/assets/javascripts/liveSearch.js index 25cf880e5..024de40e9 100644 --- a/app/assets/javascripts/liveSearch.js +++ b/app/assets/javascripts/liveSearch.js @@ -1,32 +1,54 @@ (function(Modules) { "use strict"; + let state; let normalize = (string) => string.toLowerCase().replace(/ /g,''); + let resultsSummary = (num) => { + if (num === 0) { + return "no results"; + } else { + return num + (num === 1 ? " result" : " results"); + } + }; - let filter = ($searchBox, $targets) => () => { + let filter = ($searchBox, $searchLabel, $liveRegion, $targets) => () => { let query = normalize($searchBox.val()); + let results = 0; $targets.each(function() { let content = $('.live-search-relevant', this).text() || $(this).text(); + let isMatch = normalize(content).indexOf(normalize(query)) > -1; if ($(this).has(':checked').length) { $(this).show(); + results++; return; } if (query == '') { $(this).css('display', ''); + results++; return; } - $(this).toggle( - normalize(content).indexOf(normalize(query)) > -1 - ); + $(this).toggle(isMatch); + + if (isMatch) { results++; } }); + if (state === 'loaded') { + if (query !== '') { + $searchBox.attr('aria-label', $searchLabel.text().trim() + ', ' + resultsSummary(results)); + } + state = 'active'; + } else { + $searchBox.removeAttr('aria-label'); + $liveRegion.text(resultsSummary(results)); + } + // make sticky JS recalculate its cache of the element's position // because live search can change the height document if ('stickAtBottomWhenScrolling' in GOVUK) { @@ -43,12 +65,18 @@ let $component = $(component); let $searchBox = $('input', $component); + let $searchLabel = $('label', $component); + let $liveRegion = $('.live-search__status', $component); let filterFunc = filter( $searchBox, + $searchLabel, + $liveRegion, $($component.data('targets')) ); + state = 'loaded'; + $searchBox.on('keyup input', filterFunc); filterFunc(); diff --git a/app/templates/components/live-search.html b/app/templates/components/live-search.html index 6ba673350..4108ded7f 100644 --- a/app/templates/components/live-search.html +++ b/app/templates/components/live-search.html @@ -14,6 +14,7 @@ "label": {"text": search_label}, "autocomplete": "off" }) }} +
{% endif %}