Accessibility issues - Image Manager and Document Manager popup windows

4 Answers 22 Views
Editor
Lan
Top achievements
Rank 1
Iron
Lan asked on 17 Oct 2025, 01:38 AM

Hello Telerik Team,

Our customers identified a few accessibility concerns related to the RadEditor Image Manager and Document Manager popup windows:

  1. Keyboard Focus on Popup Activation
    When a user tabs to the Image Manager plugin and presses Enter, the popup window opens. However, keyboard focus does not automatically move into the popup. Instead, the user must press the Tab key again to shift focus manually.
    ➤ To meet accessibility standards, focus should move directly into the modal or popup when it appears. This ensures that keyboard and screen reader users can interact with the dialog immediately without navigating through background content.
  2. Missing Dialog Roles and Labels
    The dialog containers ( see below ) currently lack appropriate accessibility roles.
    ➤ Each dialog container should include role="dialog".
    ➤ If the dialog has a visible title, it should also include aria-labelledby referencing the ID of that title element. This allows assistive technologies to announce the dialog context clearly.

Is there any way to fix these two issues?

Thanks,

Lan

 

4 Answers, 1 is accepted

Sort by
0
Rumen
Telerik team
answered on 17 Oct 2025, 10:06 AM

Hi Lan,

Thank you for outlining the accessibility concerns with the RadEditor Image Manager and Document Manager popup windows. Here's how you can address both issues:

1. Keyboard Focus on Popup Activation

To ensure that keyboard focus moves directly into the popup when it opens, you can use the RadEditor's client-side OnClientCommandExecuted event. This allows you to set focus to the first interactive element (the toolbar of RadFileExplorer) within the dialog:

        <telerik:RadEditor runat="server" ID="RadEditor2" Height="600px" EnableAriaSupport="true" OnClientCommandExecuted="OnClientCommandExecuted">
            <Content></Content>
            <Modules>
                <telerik:EditorModule Name="RadEditorStatistics" Visible="true" />
                <telerik:EditorModule Name="RadEditorDomInspector" Visible="true" />
                <telerik:EditorModule Name="RadEditorNodeInspector" Visible="false" />
                <telerik:EditorModule Name="RadEditorHtmlInspector" Visible="true" />
            </Modules>
            <ImageManager ViewPaths="~/Images" />
            <DocumentManager ViewPaths="~/Images" />
        </telerik:RadEditor>

        <script type="text/javascript">
            function OnClientCommandExecuted(sender, args) {
                var dialogWindow,
                    isIframe,
                    commandName = args.get_commandName();
                    
                switch (commandName) {
                    case "ImageManager":
                    case "DocumentManager":
                    
                    default:
                }

                dialogWindow = sender.get_dialogOpener()._dialogContainers[commandName];

                if (dialogWindow) {
                    isIframe = dialogWindow.get_contentFrame();
                    
                    if (isIframe) {
                        dialogWindow.add_pageLoad(function (e) {
                            var contentDocument = e.get_contentFrame().contentDocument;
                            var toolbar = contentDocument.getElementById('RadFileExplorer1_toolbar');
                            setTimeout(function () {
                                toolbar.focus();
                            }, 0);
                        });
                    }
                   
                }
            }
        </script>

This approach ensures that users relying on the keyboard are placed directly inside the dialog when it appears.

2. Adding Dialog Roles and Labels

You need to set the EnableAriaSupport="true" property in the RadEditor declaration and the RadWindow-based dialog will be rendered with a role="dialog" and aria-labelledby attributes:


Regards,
Rumen
Progress Telerik

Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
Start the 2025 Survey
0
Lan
Top achievements
Rank 1
Iron
answered on 24 Oct 2025, 01:46 PM

Hello Rumen,

Thank you for your feedback.

The current solution addresses the following two issues:

  1. Ensuring keyboard focus upon popup activation
  2. Adding appropriate dialog roles and labels for accessibility

We’d also like to explore whether the following enhancements can be implemented for the image/file manager popups:

  • Allow closing the modal via the ESC key
  • Restore focus to the triggering element once the modal is closed

Would these be feasible to support in the current framework?

Thank you again for your help!

 

Lan

0
Rumen
Telerik team
answered on 27 Oct 2025, 01:10 PM

You are welcome, Lan.

You can achieve both new requirements (Esc to close the dialog and restore the selection) using the code below:

        <telerik:RadEditor runat="server" ID="RadEditor2" Height="600px" EnableAriaSupport="true" OnClientCommandExecuted="OnClientCommandExecuted">
            <Content>line1 <br> line 2</Content>
            <Modules>
                <telerik:EditorModule Name="RadEditorStatistics" Visible="true" />
                <telerik:EditorModule Name="RadEditorDomInspector" Visible="true" />
                <telerik:EditorModule Name="RadEditorNodeInspector" Visible="false" />
                <telerik:EditorModule Name="RadEditorHtmlInspector" Visible="true" />
            </Modules>
            <ImageManager ViewPaths="~/Images" />
            <DocumentManager ViewPaths="~/Images" />
        </telerik:RadEditor>

        <script type="text/javascript">
            var lastFocusedElement, range = null;

            function OnClientCommandExecuted(sender, args) {
                var dialogWindow,
                    isIframe,
                    commandName = args.get_commandName();
                var editor = sender;

                // Store the currently focused element before opening dialog
                lastFocusedElement = sender.get_document().activeElement; // or 
                range = sender.getSelection().getRange(true);
                switch (commandName) {
                    case "ImageManager":
                    case "DocumentManager":

                    default:
                }

                dialogWindow = sender.get_dialogOpener()._dialogContainers[commandName];

                if (dialogWindow) {
                    isIframe = dialogWindow.get_contentFrame();

                    if (isIframe) {
                        dialogWindow.add_pageLoad(function (e) {
                            var contentDocument = e.get_contentFrame().contentDocument;
                            var toolbar = contentDocument.getElementById('RadFileExplorer1_toolbar');
                            setTimeout(function () {
                                toolbar.focus();
                            }, 0);

                            // Add ESC key handler to close the dialog
                            attachEscKeyHandler(contentDocument, dialogWindow);
                        });
                    }

                    // Also attach ESC handler to the dialog window itself
                    attachEscKeyHandler(document, dialogWindow);

                    // Attach close event handler to restore focus
                    dialogWindow.add_close(function (sender, args) {
                        restoreFocus(editor);
                    });
                }
            }

            function restoreFocus(editor) {
                // Restore focus to the element that triggered the dialog
                if (range) {
                    setTimeout(function () {
                        try {
                           // lastFocusedElement.focus();
                           editor.getSelection().selectRange(range)
                        } catch (e) {
                            // Element might not be focusable anymore
                            console.log('Could not restore focus:', e);
                        }
                    }, 100);
                }
            }

            function attachEscKeyHandler(doc, radWindow) {
                if (!doc || !radWindow) return;

                // Remove any existing handler to avoid duplicates
                if (doc._escKeyHandler) {
                    doc.removeEventListener('keydown', doc._escKeyHandler);
                }

                // Create and attach new handler
                doc._escKeyHandler = function (e) {
                    if (e.keyCode === 27 || e.key === 'Escape') {
                        // Use RadWindow's client-side close() method
                        if (radWindow && radWindow.close) {
                            radWindow.close();
                        }
                    }
                };

                doc.addEventListener('keydown', doc._escKeyHandler);
            }
        </script>

 

Regards,
Rumen
Progress Telerik

Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
Start the 2025 Survey
Lan
Top achievements
Rank 1
Iron
commented on 30 Oct 2025, 04:48 PM

Hello Rumen,

Thanks so much for the quick reply! The ESC key behavior works great, but I’m still having trouble restoring focus to the previous clicked element. I tried run below scripts on both OnClientCommandExecuting and OnClientCommandExecuted, but they only return the focused element inside the content area. So when the popup closes, focus jumps back to the editor. Any ideas on how to fix this?

Thanks a lot!

Lan

lastFocusedElement = sender.get_document().activeElement; // or range = sender.getSelection().getRange(true);
0
Rumen
Telerik team
answered on 31 Oct 2025, 10:04 AM

Hi Lan,

To restore focus to the exact element that triggered the dialog (such as a toolbar button or an external control), you should capture the focused element from the entire page, not just from the editor's content area. The approach using sender.get_document().activeElement only tracks elements inside the editor's editable iframe-based content area, which is why focus returns to the editor itself.

Here’s how you can address this:

  • Capture the focused element before opening the dialog:
    Use document.activeElement inside the OnClientCommandExecuting event. This will store a reference to the actual page element that was focused, including toolbar buttons or external controls.

  • Restore focus after the dialog closes:
    Use the .focus() method on the stored element inside your dialog's close handler.

Example:

var lastFocusedElement = null;

function OnClientCommandExecuting(sender, args) {
    // Capture the focused element on the page (works for toolbar buttons, etc.)
    lastFocusedElement = document.activeElement;
}

function restoreFocus() {
    // Restore focus to the previously focused element
    if (lastFocusedElement && typeof lastFocusedElement.focus === "function") {
        setTimeout(function () {
            lastFocusedElement.focus();
        }, 100);
    }
}

// Attach restoreFocus to your dialog's close event

Attach the event to RadEditor:

<telerik:RadEditor runat="server" ID="RadEditor1"
    OnClientCommandExecuting="OnClientCommandExecuting"
    ...>
    ...
</telerik:RadEditor>

Make sure your triggering elements (toolbar buttons, etc.) are focusable (<button>, <a>, or have tabindex="0").

 

    Regards,
    Rumen
    Progress Telerik

    Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
    Start the 2025 Survey
    Lan
    Top achievements
    Rank 1
    Iron
    commented on 03 Nov 2025, 03:38 PM

    Thank you Rumen. It works!

    Lan

    Tags
    Editor
    Asked by
    Lan
    Top achievements
    Rank 1
    Iron
    Answers by
    Rumen
    Telerik team
    Lan
    Top achievements
    Rank 1
    Iron
    Share this question
    or