Does Moodle maintain consistent focus management in legacy plugin modal dialogs?
0 reputation · 17 Nov 2021, 09:37 UTC
0 reputation · 17 Nov 2021, 09:37 UTC
Moodle aims for WCAG 2.1 Level AA compliance by utilizing ARIA landmarks and labels to support assistive technologies. While the core 'Boost' theme implements standardized accessibility patterns, the behavior of modal dialogs can vary when triggered by legacy plugins.
A critical requirement for keyboard accessibility is the ability to trap focus within a modal window until it is dismissed, preventing the user from accidentally interacting with the background page. There is uncertainty regarding whether these legacy components adhere to the current focus management standards used in the core codebase.
What is the expected behavior for focus restoration when a legacy plugin modal is closed? Does Moodle provide a standardized mechanism to ensure focus returns to the triggering element across all plugin types?
34775 reputation · 17 Nov 2021, 11:17 UTC
Moodle does not guarantee consistent focus management in legacy plugin modal dialogs; consistency depends on whether the plugin uses the core modal API.
Since Moodle 3.9 the core modal implementation includes a focus trap that returns focus to the triggering element when the dialog closes and prevents tabbing outside while the modal is open.
Legacy plugins that create modals directly with YUI2, custom JavaScript, or without invoking Moodle’s $PAGE->requires->js_call_function or the AMD modal API may omit this focus trap, leading to inconsistent focus behavior.
To determine whether the legacy plugin will exhibit consistent focus management, please specify the Moodle version in use and the JavaScript framework/YUI version the plugin employs to instantiate its modals.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 17 Nov 2021, 17:03 UTC
When a modal is opened via Moodle’s core AMD core/modal module, the focus trap and restoration logic rely on the element that fired the modal being a native focusable element (e.g., <button>, <a> with href, or an element with tabindex="0"). If the trigger is a plain <div> or non‑focusable element, the core will still trap focus inside the dialog, but the return focus may be lost once the modal closes.
tabindex="0" or use a button/anchor.core/modal (e.g., YUI2 or custom jQuery dialogs) must implement their own focus trap and restoration logic; otherwise focus can escape.In short, for consistent WCAG 2.1 compliance across Moodle versions, always use the core modal API and make sure the trigger element is focusable.