How do I listen to the keyboard using Fable in an Elmish app?

198 Views Asked by At

Using Fable in an Elmish app, I'd like to listen to the keyboard directly and get each keystroke as a message.

The Elmish documentation has a page on Subscriptions, which shows how to convert JavaScript events to messages. In my case, the events are "keydown" events, and I found code in JavaScript to capture "keydown" events.

However, I'm having trouble putting the F# code together. My issue is that I don't know how to access the keyCode from the event raised when a key is pressed. Here's the code I have so far:

let keyDown initial =
    let sub dispatch =
        document.addEventListener("keydown", fun e ->
            dispatch (KeyDown e.keyCode))  // keyCode is not accessible here
    Cmd.ofSub sub
2

There are 2 best solutions below

4
Brian Berns On BEST ANSWER

I think you want to use onKeyDown instead of adding an event listener. If you generate your HTML elements using Feliz, you can dispatch on keydown like this:

Html.input [
    prop.onKeyDown (fun evt ->
        dispatch (KeyDown evt.key))
]

Alternatively, you can probably use dynamic typing to access the property by name (bypassing the type checker):

open Fable.Core.JsInterop

document.addEventListener("keydown", fun e ->
    dispatch (KeyDown e?keyCode))   // use ? operator

I haven't tried that, though, and wouldn't recommend it.

0
Peheje On

In this case you know that the event produced by a keydown is actually a Browser.Types.KeyboardEvent and not only Browser.Types.Event So you can safely downcast

let keydown (event: Event) =
    let keyboardEvent = event :?> KeyboardEvent
    printfn "%A" keyboardEvent.key

document.addEventListener("keydown", keydown)

Related Questions in F#

Related Questions in FABLE-F#