MDL-85698 core: combo box informs screen reader users
This commit is contained in:
@@ -1451,6 +1451,7 @@ $string['moveselectedcategoriesto'] = 'Move selected categories to';
|
||||
$string['moveselectedcoursesto'] = 'Move selected courses to...';
|
||||
$string['movetoanotherfolder'] = 'Move to another folder';
|
||||
$string['moveup'] = 'Move up';
|
||||
$string['multipleitemsfound'] = 'There are {$a} items found.';
|
||||
$string['mustconfirm'] = 'You need to confirm your account';
|
||||
$string['mustchangepassword'] = 'The new password must be different than the current one';
|
||||
$string['mycourses'] = 'My courses';
|
||||
@@ -1537,6 +1538,7 @@ $string['nograde'] = 'No grade';
|
||||
$string['nohelpforactivityorresource'] = 'There is currently no help associated with this resource or activity';
|
||||
$string['nochange'] = 'No change';
|
||||
$string['noimagesyet'] = 'No images have been uploaded to your course yet';
|
||||
$string['noitemsfound'] = 'No items found.';
|
||||
$string['nologsfound'] = 'No logs have been found';
|
||||
$string['nomatchingusers'] = 'No users match \'{$a}\'';
|
||||
$string['nomorecourses'] = 'No more matching courses could be found';
|
||||
@@ -1611,6 +1613,7 @@ $string['numyears'] = '{$a} years';
|
||||
$string['ok'] = 'OK';
|
||||
$string['oldpassword'] = 'Current password';
|
||||
$string['olduserdirectory'] = 'This is the OLD users directory, and is no longer needed. You may safely delete it. The files it contains have been copied to the NEW user directory.';
|
||||
$string['oneitemfound'] = 'There is 1 item found.';
|
||||
$string['opendrawerblocks'] = 'Open block drawer';
|
||||
$string['opendrawerindex'] = 'Open course index';
|
||||
$string['opensinnewwindow'] = 'Opens in new window';
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -16,6 +16,8 @@
|
||||
import $ from 'jquery';
|
||||
import {debounce} from 'core/utils';
|
||||
import Pending from 'core/pending';
|
||||
import {get_string as getString} from 'core/str';
|
||||
|
||||
|
||||
/**
|
||||
* The class that manages the state of the search within a combobox.
|
||||
@@ -330,6 +332,7 @@ export default class {
|
||||
this.setMatchedResults(await this.filterDataset(await this.getDataset()));
|
||||
this.filterMatchDataset();
|
||||
await this.renderDropdown();
|
||||
await this.updateLiveRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,6 +348,7 @@ export default class {
|
||||
await this.renderDropdown();
|
||||
// Set the dropdown to open.
|
||||
this.toggleDropdown(true);
|
||||
await this.updateLiveRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,4 +384,51 @@ export default class {
|
||||
changeHandler(e) {
|
||||
// Components may override this method to do something.
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the screen reader live region with the result count.
|
||||
*/
|
||||
async updateLiveRegion() {
|
||||
if (!this.searchDropdown?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const idParts = this.searchDropdown.id.split('-');
|
||||
|
||||
if (idParts.length < 3) {
|
||||
return;
|
||||
}
|
||||
const [, instanceId, id] = idParts; // E.g. dialog-12-34 only want the last two parts.
|
||||
const liveRegion = document.getElementById(`combobox-status-${instanceId}-${id}`);
|
||||
|
||||
if (!liveRegion) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resultCount = this.getMatchedResults().length;
|
||||
let message;
|
||||
if (resultCount === 0) {
|
||||
message = await getString('noitemsfound', 'core');
|
||||
} else if (resultCount === 1) {
|
||||
message = await getString('oneitemfound', 'core');
|
||||
} else {
|
||||
message = await getString('multipleitemsfound', 'core', resultCount);
|
||||
}
|
||||
|
||||
liveRegion.textContent = message;
|
||||
|
||||
// Reset previous timeout if it exists.
|
||||
if (this.liveRegionTimeout) {
|
||||
clearTimeout(this.liveRegionTimeout);
|
||||
}
|
||||
|
||||
// Clear the feedback message after 4 seconds. This is similar to the default timeout of toast messages
|
||||
// before disappearing from view. It is important to clear the message to prevent screen reader users from navigating
|
||||
// into this region and avoiding confusion.
|
||||
this.liveRegionTimeout = setTimeout(() => {
|
||||
liveRegion.textContent = '';
|
||||
this.liveRegionTimeout = null;
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -90,3 +90,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ARIA live region for screen readers -->
|
||||
<div id="combobox-status-{{instance}}-{{uniqid}}" class="sr-only" aria-live="polite" aria-atomic="true"></div>
|
||||
|
||||
Reference in New Issue
Block a user