Skip to content

Commit

Permalink
MDL-69116 qtype_multichoice: accessibility improvement
Browse files Browse the repository at this point in the history
- Screen-readers should not see 'clear my choice' when it is not visible
- 'clear my choice' option should only become visible when a choice is
selected
  • Loading branch information
rezaies committed Aug 31, 2020
1 parent b0af846 commit 8739f21
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 7 deletions.
2 changes: 1 addition & 1 deletion question/type/multichoice/amd/build/clearchoice.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion question/type/multichoice/amd/build/clearchoice.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion question/type/multichoice/amd/src/clearchoice.js
Expand Up @@ -55,7 +55,10 @@ define(['jquery', 'core/custom_interaction_events'], function($, CustomEvents) {
* @param {Object} clearChoiceContainer The clear choice option container.
*/
var hideClearChoiceOption = function(clearChoiceContainer) {
// We are using .sr-only and aria-hidden together so while the element is hidden
// from both the monitor and the screen-reader, it is still tabbable.
clearChoiceContainer.addClass('sr-only');
clearChoiceContainer.attr('aria-hidden', true);
clearChoiceContainer.find(SELECTORS.LINK).attr('tabindex', -1);
};

Expand All @@ -66,6 +69,7 @@ define(['jquery', 'core/custom_interaction_events'], function($, CustomEvents) {
*/
var showClearChoiceOption = function(clearChoiceContainer) {
clearChoiceContainer.removeClass('sr-only');
clearChoiceContainer.removeAttr('aria-hidden');
clearChoiceContainer.find(SELECTORS.LINK).attr('tabindex', 0);
clearChoiceContainer.find(SELECTORS.RADIO).prop('disabled', true);
};
Expand All @@ -89,7 +93,7 @@ define(['jquery', 'core/custom_interaction_events'], function($, CustomEvents) {
data.originalEvent.preventDefault();
});

root.on(CustomEvents.events.activate, SELECTORS.CHOICE_ELEMENT, function() {
root.on('change', SELECTORS.CHOICE_ELEMENT, function() {
// If the event has been triggered by any other choice, show the clear choice option.
showClearChoiceOption(clearChoiceContainer);
});
Expand Down
15 changes: 11 additions & 4 deletions question/type/multichoice/renderer.php
Expand Up @@ -293,14 +293,21 @@ public function after_choices(question_attempt $qa, question_display_options $op
'name' => $qa->get_qt_field_name('answer'),
'id' => $clearchoiceid,
'value' => -1,
'class' => 'sr-only'
'class' => 'sr-only',
'aria-hidden' => 'true'
];
$clearchoicewrapperattrs = [
'id' => $clearchoicefieldname,
'class' => 'qtype_multichoice_clearchoice',
];

$cssclass = 'qtype_multichoice_clearchoice';
// When no choice selected during rendering, then hide the clear choice option.
// We are using .sr-only and aria-hidden together so while the element is hidden
// from both the monitor and the screen-reader, it is still tabbable.
$linktabindex = 0;
if (!$hascheckedchoice && $response == -1) {
$cssclass .= ' sr-only';
$clearchoicewrapperattrs['class'] .= ' sr-only';
$clearchoicewrapperattrs['aria-hidden'] = 'true';
$clearchoiceradioattrs['checked'] = 'checked';
$linktabindex = -1;
}
Expand All @@ -311,7 +318,7 @@ public function after_choices(question_attempt $qa, question_display_options $op
'class' => 'btn btn-link ml-4 pl-1 mt-2']);

// Now wrap the radio and label inside a div.
$result = html_writer::tag('div', $clearchoiceradio, ['id' => $clearchoicefieldname, 'class' => $cssclass]);
$result = html_writer::tag('div', $clearchoiceradio, $clearchoicewrapperattrs);

// Load required clearchoice AMD module.
$this->page->requires->js_call_amd('qtype_multichoice/clearchoice', 'init',
Expand Down

0 comments on commit 8739f21

Please sign in to comment.