Select to view content in your preferred language

Set focus to popup title

509
4
01-25-2024 09:47 AM
Jeff-Reinhart
New Contributor III

We are working to implement a keyboard map click to open a map popup. With the map application element focused, the user can pan using the arrow keys and press enter or spacebar to get a popup for the center of the map (where we float a crosshairs). After the enter or spacebar event, it is very useful to change the focus to the popup so the user can quickly access controls for collapsing, docking, and closing the popup without having to tab through all of the other actionable items (e.g. widget buttons) first. It is also useful to focus first on the popup title so a screen reader reads the title after the click.

Please see this codepen: https://codepen.io/jeffreinhart/pen/LYajqNW

This should be easy enough, right? Just wrap the popup title text in a div with a class to select and a tabindex:

`<div tabindex='0' class='popup-title'>Reverse geocode: ${lon}, ${lat}</div>`,

But then, we need to wait for the SDK to add that element to the DOM before we can set focus, so we wait for the waitForElm() function to complete (line 113). That function uses a mutation observer to check if an element has been added to the DOM, a link to the SO description is provided in the function definition.

At this point, popupTitleElement.focus() on line 116 should work. But it doesn’t. I cannot figure out what else I need to wait for to be able to focus this element. Best I could come up with is a setInterval() that stops when the element finally gets focus.

Anybody have any idea what else is happening that could be blocking setting focus or a better solution than setInterval()?

0 Kudos
4 Replies
RalucaNicola1
Esri Contributor

There is a focus method on the popup. I've set it after setting the content in the popup: https://codepen.io/ralucanicola/pen/mdoqEyj?editors=1000. I am not sure if you still won't run into timing issues... but it seems that the view container gets a focus from the map click and the popup gets the focus when the content is set, which is afterwards, so it should be safe. (the title is focused because you set tabindex: 0 on it, otherwise it would focus the docking button first...). 

0 Kudos
Jeff-Reinhart
New Contributor III

Thanks for the reply! Definitely missed the focus() method of the map view popup. Was too focused on using the mutation observer.

Unfortunately, I am running into timing issues. It seems the locator in your example is giving the popup time to render before setting the focus on the popup. I have a much faster retrieval of popup content (identify task) on my actual implementation so even if I wait until I have the popup content retrieved, the popup still is not rendered in time on some occasions. I throttled the network and it fails to focus consistently.

It seems what would really help is a "completed" or "rendered" property on the popup that could be watched with reactiveUtils for when the popup is actually fully rendered.

0 Kudos
RalucaNicola1
Esri Contributor

I was talking to the developer and the bad news is that this is a bug and we need workarounds like the `setInterval` method you used. The good news is that there is a ticket for this, so it will be fixed in the next releases. 

From what I also tested the popup rendering depends on requests it needs to make on initialization. So once we render the popup once and it gets all the resources it needs, the next time rendering is fast and setting the focus works well. So another hack I thought of is to open an empty popup right when you load the application, make it invisible and when the user actually opens a popup, then it already has all the resources and it can set the focus on the elements. I made an example here: https://codepen.io/ralucanicola/pen/mdoqEyj?editors=1010

I also discovered that there is a `shouldFocus` property on the `openPopup` method. What this does in the background is to listen for when the `viewModel.active` is true and then focus. However, this also doesn't guarantee that the popup is rendered. We'll keep you posted when this gets fixed and in the meantime, settle for one of these hacks.

0 Kudos
Jeff-Reinhart
New Contributor III

Thanks for looking into this, much appreciated! Looking forward to seeing the fix. In the broader scope of accessibility - having ways to track completed rendering and to select elements in the DOM is always a huge help to developers.