How to Detect Pressing Enter Key in Bucklescript-TEA

Want to find out how to send a Msg when a user presses the Enter key, but there’s no onEnter handler though?

Its a bit tricky, but here’s how you do it:

You need to detect keypresses using the custom on handler function:

on : String -> Decoder msg -> Attribute msg

The first String is the same events as when you use addEventListener in Javascript, so things like "click".

Here, we’ll use "keydown":

on "keydown" (Decoder msg)

Now, we need a decoder that can detect the “Enter” key, that being a Json.Decoder

The decoder tries to decode the Javascript event into a Bucklescript value and if it succeeds, the value is routed to your update function.

For example, we could use something like this to send a successful decoding message for "click":

on "click" (Decode.succeed message)

But that’s for click, but since keypresses are grouped together, we need to filter out the “Enter” key in our case.


But first, we need to examine the keydown event in Javascript.

We can use the keyCode of keydown’s event:

document.addEventListener('keydown', function(event) {
  console.log(event.keyCode);
});

This will output 13 if we press the “Enter” key.


Ok, so there’s the keyCode decoder in Bucklescript-TEA:

keyCode : Decoder Int

And this will successfully decode the "keydown" press, but we still need to filter out the “Enter” key with a keyCode of 13 though. So how do we do that?


What we do is use andThen from the decoders library to chain our logic back to a single decoder:

andThen : (a -> Decoder b) -> Decoder a -> Decoder b

We’ll use it like this:

Json.Decoder.andThen ( filter fun that returns decoder ) keyCode

and here’s the filtering function:

let isEnter code =
    if code = 13 then
      Json.Decoder.succeed msg
    else
      Json.Decoder.fail "not ENTER"


So all together, the final solution looks like this:

let onEnter msg =
  let isEnter code =
    if code = 13 then
      Json.Decoder.succeed msg
    else
      Json.Decoder.fail "not ENTER"
  in
    on "keydown" (Json.Decoder.andThen isEnter keyCode)

Then, you can use it like this for an input text box:

input'
  [ type' "text"
  ; id "search-bar"
  ; value model.search_term
  ; onInput updateSearchTerm
  ; onEnter Search   (* Here you are sending 'Search' as the msg *)
  ; placeholder "Search" 
  ]
  []

It was a bit complicated, but once you understand this, you should be able to build other event handlers easier as well.

Comments