Merge pull request #2741 from alphagov/template-form-focus

Template form focus
This commit is contained in:
Tom Byers
2019-02-12 13:04:24 +00:00
committed by GitHub
5 changed files with 63 additions and 31 deletions

View File

@@ -263,7 +263,7 @@
$(window).scrollTop(this.getInPageEdgePosition(sticky) - windowHeight);
}
self.hasResized = false;
this.hasResized = false;
},
releaseEl: function (el, sticky) {
el.$fixedEl.css(sticky.edge, '');
@@ -576,9 +576,8 @@
el.removeStickyClasses(this);
$el.css('width', '');
if (_mode === 'dialog') {
dialog.releaseEl(el, this);
}
// clear styles from any elements stuck while in a dialog mode
dialog.releaseEl(el, this);
el.removeShim();
el.release(this);
}
@@ -658,9 +657,15 @@
}
};
stickAtTop.unstop = function (el) {
var offset = 0;
if (_mode === 'dialog') {
offset = dialog.getOffsetFromEdge(el, this);
}
el.$fixedEl.css({
'position': '',
'top': ''
'top': offset + 'px'
});
el.unstop();
};

View File

@@ -19,10 +19,10 @@
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},
{key: 'move-to-new-folder', $el: this.$form.find('#move_to_new_folder_form'), cancellable: true},
{key: 'add-new-folder', $el: this.$form.find('#add_new_folder_form'), cancellable: true},
{key: 'add-new-template', $el: this.$form.find('#add_new_template_form'), cancellable: true}
{key: 'move-to-existing-folder', $el: this.$form.find('#move_to_folder_radios'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_folder_radios legend', true)},
{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)},
{key: 'add-new-folder', $el: this.$form.find('#add_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_folder_name', false)},
{key: 'add-new-template', $el: this.$form.find('#add_new_template_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_template_form legend', true)}
];
// cancel/clear buttons only relevant if JS enabled, so
@@ -35,7 +35,7 @@
// first off show the new template / new folder buttons
this.currentState = this.$form.data('prev-state') || 'unknown';
if (this.currentState === 'unknown') {
this.selectActionButtons();
this.selectActionButtons(false);
} else {
this.render();
}
@@ -44,6 +44,24 @@
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);
};
if (setTabindex) {
$el.attr('tabindex', '-1');
$el.on('blur', removeTabindex);
}
$el.focus();
};
};
this.activateStickyElements = function() {
var oldClass = 'js-will-stick-at-bottom-when-scrolling';
var newClass = 'js-stick-at-bottom-when-scrolling';
@@ -57,6 +75,7 @@
};
this.addCancelButton = function(state) {
let selector = `[value=${state.key}]`;
let $cancel = this.makeButton('Cancel', () => {
// clear existing data
@@ -64,8 +83,8 @@
state.$el.find('input:text').val('');
// go back to action buttons
this.selectActionButtons();
});
this.selectActionButtons(selector);
}, selector);
state.$el.find('[type=submit]').after($cancel);
};
@@ -73,7 +92,6 @@
this.addClearButton = function(state) {
let $clear = this.makeButton('Clear', () => {
// uncheck all templates and folders
this.$form.find('input:checkbox').prop('checked', false);
@@ -84,9 +102,10 @@
state.$el.find('.template-list-selected-counter').append($clear);
};
this.makeButton = (text, fn) => $('<a></a>')
this.makeButton = (text, fn, cancelSelector) => $('<a></a>')
.html(text)
.addClass('js-cancel')
.data('target', cancelSelector) // isn't set if cancelSelector is undefined
.attr('tabindex', '0')
.on('click keydown', event => {
// space, enter or no keyCode (must be mouse input)
@@ -96,12 +115,16 @@
}
});
this.selectActionButtons = function () {
this.selectActionButtons = function (targetSelector) {
// If we want to show one of the grey choose actions state, we can pretend we're in the choose actions state,
// and then pretend a checkbox was clicked to work out whether to show zero or non-zero options.
// This calls a render at the end
this.currentState = 'nothing-selected-buttons';
this.templateFolderCheckboxChanged();
if (targetSelector) {
let setFocus = this.getFocusRoutine(targetSelector, false);
setFocus();
}
};
this.actionButtonClicked = function(event) {
@@ -139,7 +162,8 @@
};
this.render = function() {
var mode = 'default';
let mode = 'default';
let currentStateObj = this.states.filter(state => { return (state.key === this.currentState); })[0];
// detach everything, unless they are the currentState
this.states.forEach(
@@ -153,6 +177,8 @@
GOVUK.stickAtBottomWhenScrolling.setMode(mode);
// make sticky JS recalculate its cache of the element's position
GOVUK.stickAtBottomWhenScrolling.recalculate();
if (currentStateObj && ('setFocus' in currentStateObj)) { currentStateObj.setFocus(); }
};
this.nothingSelectedButtons = $(`

View File

@@ -1,6 +1,8 @@
// CSS adapted from
// https://github.com/alphagov/govuk_frontend_toolkit/blob/d9489a987086471fe30b4b925a81c12cd198c91d/docs/javascript.md#stick-at-top-when-scrolling
$sticky-padding: $gutter * 2 / 3;
.js-stick-at-top-when-scrolling,
.js-stick-at-bottom-when-scrolling {
@@ -11,6 +13,10 @@
.form-group {
margin-bottom: 20px;
legend {
outline: none;
}
}
.back-to-top-link {
@@ -40,14 +46,12 @@
.js-stick-at-bottom-when-scrolling {
$vertical-padding: $gutter * 2 / 3;
transition: bottom 0.1s ease-out, box-shadow 1s ease-in-out;
padding: $vertical-padding 0 $vertical-padding $gutter-half;
margin-top: -$vertical-padding;
padding: $sticky-padding 0 $sticky-padding $gutter-half;
margin-top: -$sticky-padding;
& + .js-stick-at-bottom-when-scrolling {
margin-top: ($vertical-padding * 2) * -1;
margin-top: ($sticky-padding * 2) * -1;
}
.page-footer {

View File

@@ -29,14 +29,11 @@
</fieldset>
</div>
<div id="add_new_template_form">
<fieldset>
<legend class="visuallyhidden">Add a new template</legend>
<div class="js-will-stick-at-bottom-when-scrolling">
{{ radios(templates_and_folders_form.add_template_by_template_type) }}
</div>
<div class="js-will-stick-at-bottom-when-scrolling">
{{ page_footer('Continue', button_name='operation', button_value='add-new-template') }}
</div>
</fieldset>
<div class="js-will-stick-at-bottom-when-scrolling">
{{ radios(templates_and_folders_form.add_template_by_template_type) }}
</div>
<div class="js-will-stick-at-bottom-when-scrolling">
{{ page_footer('Continue', button_name='operation', button_value='add-new-template') }}
</div>
</div>
</div>

View File

@@ -320,7 +320,7 @@ def test_should_show_new_template_choices_if_service_has_folder_permission(
if not page.select('#add_new_template_form'):
raise ElementNotFound()
assert normalize_spaces(page.select_one('#add_new_template_form fieldset fieldset legend').text) == (
assert normalize_spaces(page.select_one('#add_new_template_form fieldset legend').text) == (
'Add new'
)
assert [