I want to listen to both keypress
and keydown
events in Elm. But if I have the following, only the keydown
events will be listened to:
textarea
[ onWithOptions "keypress" (Options False True) <| Json.Decode.map KeyPress keyCode
, onWithOptions "keydown" (Options False True) <| Json.Decode.map KeyDown keyCode
] []
If I change the Options
to not preventDefault
, then both events will be listened to. But I need to preventDefault
in order to not let tab keys from changing focus.
Any way to do this in Elm?
Both are used as per the need of your program and as per the convenience of the user. keyup Fires when the user releases a key, after the default action of that key has been performed. keydown Fires when the user depresses a key.
keydown: This event is triggered when a key is pressed down. keypress: This event is triggered when a key is pressed. This event fails to recognise keys such as tab, shift, ctrl, backspace etc. keyup: This event is triggered when a key is released.
Occur in sequence when a user presses and releases a key. KeyDown occurs when the user presses a key. KeyUp occurs when the user releases a key.
How does a user generate multiple keydown events? Explanation: If the user holds the key down long enough for it to begin repeating, there will be multiple keydown events before the keyup event arrives. Pressing the key for long time results in multiple calls to the function onkeypress.
In Elm 19, to access keys pressed, you can use Browser.Events which is a part of the Elm Browser library. If you want to capture what key is down, you could use something like this:
import Json.Decode as Decode
type Key
= Character Char
| Control String
subscriptions : Model -> Sub Msg
subscriptions model =
Browser.Events.onKeyDown keyDecoder
keyDecoder : Decode.Decoder Msg
keyDecoder =
Decode.map toKey (Decode.field "key" Decode.string)
toKey : String -> Msg
toKey string =
case String.uncons string of
Just ( char, "" ) ->
PressedLetter char
_ ->
Control string
Adapted from here.
Pre Elm 0.19, I recommend you to use elm-lang/keyboard. This package uses subscriptions and it's very easy to use. You can subscribe to keydown and keyup at the same time.
For your specific case: The default action for a keydown event is to trigger a keypress event. If you prevent that default behaviour, you will not get the keypress events.
You can read more about keydown events here
Maybe you just need to use keyup and keydown.
I hope it helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With