Open ChristophP opened 5 years ago
related #77
We're also running into this issue, on a large-ish app that's replacing a desktop app. Many of the existing shortcuts that users have muscle memory of, collide with browser shortcuts such as Alt + F.
related unanswered SO question: how to use prevent default on Elm Browser.Event.onKeyDown
I faced the same issue today but found a workaround that works like I want:
Add Html.Events.preventDefaultOn "keydown" yourDecoder
to the outermost div
To be able to pick up all keydown you must also add Html.Attributes.tabIndex 0
to this div.
Now in your decoder you can check the input before the key is sent to the browser. If you detect a keycombination your decoder should give back ( KeyCombinationMsg, True ) so that f.eks. any textbox in parts of your application with focus does not receive any characters.
If no known key-combination is found your decoder should fail, letting the focused textInput get that event :)
Update: There was a slight problem with the proposed workaround. If an input on the page gets removed/destroyed focus is lost to document.body and the outermost div will not pick up keypresses before clicking somewhere in the application. Was hoping to have a pure elm workaround, but needed to add this to index.html to get it working. ( add focus to the outermost div if focus is lost )
document.addEventListener("focusout", (e) => {
if (e.relatedTarget == null) {
document.getElementById("layout").focus()
}
})
I made a package for dealing with this issue, at least for my use case:
https://package.elm-lang.org/packages/bburdette/windowkeys/latest/
The issue I am building an editor using Elm, so I am handling all sorts of keyboard input. I just learned that the subscriptions in
Browser.Events
unfortunately don't provide the possibilty toprevendDefault
the browser behavior. This is unfortunate because sometime I need the tab key to do something different than switch to the nexttabIndex
element or intercept key strokes on inputs. Possible workaroundHtml.Events
on the outermost<div>
. Unfortunately this won't work if the focus gets somehow changed to the body.