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.