Make footer popup forms groups & add labelling

The existing behaviour focused the form control
for each popup (radios or textbox) when opened.

This gives no indication the submit button or
cancel link have been added to the page.

These changes:
- make the parent element a region to group all
  the new content
- label the region to link it to the button that
  opened it
- add a description to the region so users know
  how to use it and that all the controls have
  been added to the page
This commit is contained in:
Tom Byers
2020-09-22 11:45:55 +01:00
parent 5819b5da2d
commit 87dcea779e
4 changed files with 251 additions and 119 deletions

View File

@@ -17,18 +17,59 @@
// all the diff states that we want to show or hide
this.states = [
{key: 'nothing-selected-buttons', $el: this.$form.find('#nothing_selected'), cancellable: false},
{key: 'items-selected-buttons', $el: this.$form.find('#items_selected'), cancellable: false},
{key: 'move-to-existing-folder', $el: this.$form.find('#move_to_folder_radios'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_folder_radios fieldset', true), action: 'move to folder'},
{key: 'move-to-new-folder', $el: this.$form.find('#move_to_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_new_folder_name', false), action: 'move to new folder'},
{key: 'add-new-folder', $el: this.$form.find('#add_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_folder_name', false), action: 'new folder'},
{key: 'add-new-template', $el: this.$form.find('#add_new_template_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_template_form fieldset', true), action: 'new template'}
{
key: 'nothing-selected-buttons',
$el: this.$form.find('#nothing_selected'),
cancellable: false
},
{
key: 'items-selected-buttons',
$el: this.$form.find('#items_selected'),
cancellable: false
},
{
key: 'move-to-existing-folder',
$el: this.$form.find('#move_to_folder_radios'),
cancellable: true,
setFocus: () => $('#move_to_folder_radios').focus(),
action: 'move to folder',
description: 'Press move to confirm or cancel to close'
},
{
key: 'move-to-new-folder',
$el: this.$form.find('#move_to_new_folder_form'),
cancellable: true,
setFocus: () => $('#move_to_new_folder_form').focus(),
action: 'move to new folder',
description: 'Press add to new folder to confirm name or cancel to close'
},
{
key: 'add-new-folder',
$el: this.$form.find('#add_new_folder_form'),
cancellable: true,
setFocus: () => $('#add_new_folder_form').focus(),
action: 'new folder',
description: 'Press add new folder to confirm name or cancel to close'
},
{
key: 'add-new-template',
$el: this.$form.find('#add_new_template_form'),
cancellable: true,
setFocus: () => $('#add_new_template_form').focus(),
action: 'new template',
description: 'Press continue to confirm selection or cancel to close'
}
];
// cancel/clear buttons only relevant if JS enabled, so
this.states.filter(state => state.cancellable).forEach((x) => this.addCancelButton(x));
this.states.filter(state => state.key === 'items-selected-buttons').forEach(x => this.addClearButton(x));
// make elements focusabled
this.states.filter(state => state.setFocus).forEach(x => x.$el.attr('tabindex', '0'));
this.addDescriptionsToStates();
// activate stickiness of elements in each state
this.activateStickyElements();
@@ -45,22 +86,16 @@
this.$form.on('change', 'input[type=checkbox]', () => this.templateFolderCheckboxChanged());
};
this.getFocusRoutine = function (selector, setTabindex) {
return function () {
let $el = $(selector);
let removeTabindex = (e) => {
$(e.target)
.removeAttr('tabindex')
.off('blur', removeTabindex);
};
this.addDescriptionsToStates = function () {
let id, description;
if (setTabindex) {
$el.attr('tabindex', '-1');
$el.on('blur', removeTabindex);
}
$el.focus();
};
$.each(this.states.filter(state => 'description' in state), (idx, state) => {
id = `${state.key}__description`;
description = `<p class="govuk-visually-hidden" id="${id}">${state.description}</p>`;
state.$el
.prepend(description)
.attr('aria-describedby', id);
});
};
this.activateStickyElements = function() {
@@ -140,8 +175,7 @@
this.currentState = 'nothing-selected-buttons';
this.templateFolderCheckboxChanged();
if (targetSelector) {
let setFocus = this.getFocusRoutine(targetSelector, false);
setFocus();
$(targetSelector).focus();
}
};
@@ -240,6 +274,7 @@
this.render = function() {
let mode = 'default';
let currentStateObj = this.states.filter(state => { return (state.key === this.currentState); })[0];
let scrollTop;
// detach everything, unless they are the currentState
this.states.forEach(
@@ -254,7 +289,11 @@
// make sticky JS recalculate its cache of the element's position
GOVUK.stickAtBottomWhenScrolling.recalculate();
if (currentStateObj && ('setFocus' in currentStateObj)) { currentStateObj.setFocus(); }
if (currentStateObj && ('setFocus' in currentStateObj)) {
scrollTop = $(window).scrollTop();
currentStateObj.setFocus();
$(window).scrollTop(scrollTop);
}
};
this.nothingSelectedButtons = $(`

View File

@@ -176,6 +176,17 @@ $message-type-bottom-spacing: govuk-spacing(4);
}
.sticky-template-form {
padding: govuk-spacing(3);
margin: govuk-spacing(3) * -1;
&:focus {
outline: none;
}
}
.folder-heading {
.govuk-grid-row & {