4

I would like something like this:

on UI.keydown textfield $ \c -> when (c == 13) $ void $ do
    trigger UI.click button

Namely, is there something that acts like the trigger function I just inserted?

allidoiswin
  • 2,543
  • 1
  • 20
  • 23

1 Answers1

1

In order to have Enter keypresses handled as if they were button clicks you don't need to trigger a click literally. Rather, you need an event which is fired whenever either the keypress or the click happen. The easiest way to do so, specially if you are already using Threepenny's FRP combinators (which I heartily recommend), is through unionWith. With that and some other Reactive.Threepenny combinators, the code might look like this:

-- I'm giving separate names to the events for extra clarity.
let eClick = UI.click button
    eEnter = void $ filterE (== 13) (UI.keydown textfield)
    -- This event is fired whenever `eClick` or `eEnter` happen.
    eGo = unionWith const eClick eEnter

Then you just handle eGo, using onEvent, in the way you would handle the click event.

Note that an alternative solution in the spirit of the pseudocode in your question would be defining eGo via newEvent and then using the trigger function you get to fire the event in the on handlers of both click and keypress:

-- Assuming you are in an `UI` do-block, thus the `liftIO`.
(eGo, fireGo) <- liftIO newEvent
on UI.click button $ \_ -> fireGo ()
on UI.keydown textfield $ \c -> when (c == 13) (fireGo ())
-- Alternatively, you might define an `eEnter` with `filterE`,
-- as in the first example, instead of using `on` and `when`. 

That is not as nice a solution as the first one, as it is somewhat messier and doesn't play quite as smoothly with FRP code. I wouldn't recommend it, except perhaps if you are not using the FRP combinators at all.

duplode
  • 33,731
  • 7
  • 79
  • 150
  • How would I add more than 2 events to eGo? Would you be able to give an example of the newEvent construct? Thanks! – allidoiswin Dec 03 '15 at 18:11
  • 1
    @allidoiswin (1) Use `unionWith` multiple times (e.g. `unionWith const eA (unionWith const eB eC)`) or [`unions`](https://hackage.haskell.org/package/threepenny-gui-0.6.0.3/docs/Reactive-Threepenny.html#v:unions) (e.g. `void (unions [eA, eB, eC])`). (2) I added an example of what the alternative would look like. – duplode Dec 03 '15 at 19:36