Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen for both keypress and keydown events in Elm?

Tags:

elm

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?

like image 963
at. Avatar asked Jun 06 '17 07:06

at.


People also ask

Should I use Keydown or Keyup?

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.

How do I trigger Keydown event?

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.

What is the difference between the Keydown and Keyup events?

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?

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.


2 Answers

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.

like image 103
HParker Avatar answered Oct 04 '22 19:10

HParker


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.

like image 42
nidstang Avatar answered Oct 04 '22 20:10

nidstang