Setting Focus in onAfterShow Fails When Navigating via JS window.history.go
See original GitHub issueThe API reference states that the application can set the focus in afterShow
event. This is great and works fine. There is only one problem which can be observed only when the app navigates back programmatically via window.history.go(-1)
. When the user navigates back natively with the browser button, the focus is set as intended.
Tested browsers/devices(OK/FAIL)
- Chrome: FAIL
- FF: FAIL
- Edge: FAIL
- Safari: FAIL
URL (minimal example if possible)
Steps to reproduce the problem
- Open the above sample page. The
sap.m.App
hasautoFocus="false"
and inonAfterShow
, the Input is supposed to have the focus after navigation finishes. - In Home.controller.js, replace
const onAfterShow = () => requestAnimationFrame(() => target.focus());
with
const onAfterShow = () => target.focus();
- In the preview panel, click on <kbd>Navigate ></kbd>.
- Navigate back by pressing <kbd>Alt</kbd>/<kbd>⌘</kbd> + <kbd>Left arrow</kbd> or click on the native back button.
Focus is set on the Input again (expected behavior). - Reload the preview panel, and click on <kbd>Navigate ></kbd> again.
- Navigate back, but this time, by clicking on the navButton from the Page header toolbar which calls
window.history.go(-1)
in the controller.
What is the expected result?
Focus is set on the Input, same as when navigated back natively.
What happens instead?
Focus is set on the first element (Button instead of Input).
Any other information? (attach screenshot if possible)
This seems to be related to the behavior mentioned in this talk given by Jake Archibald at JSConf this year (really good btw.) where the difference between JS and native trigger is explained.
My current workaround is just to call focus()
within setTimout
or requestAnimationFrame
queuing the task to be performed later.
Issue Analytics
- State:
- Created 5 years ago
- Comments:11 (10 by maintainers)
Top GitHub Comments
Hi @boghyon, fixing the issue wouldn’t take much effort I guess, but your proposal for identical initialFocus property makes more sense to me. We’ll discuss it and I’ll get back to you with the final decision (fix or feature).
Thanks, Mihail.
About the
initialFocus
proposal: Since a single screen can display multiple views at once (e.g. in a master-detail scenario), I wonder if it’s not a better solution to introduce the feature to targets & routes instead - Similar to using thetitle
property in targets:As soon as multiple targets are displayed, the corresponding control could receive the focus, following the same heuristic described in
titleChanged
.In the case above, it’s the control with
id="someControlIdInDetail"
. If theinitialFocusTarget
is not defined, then the control from the first target that hasinitialFocus
defined. Any thoughts?