Search code examples
haskellthreepenny-gui

Combining Event and an attribute in threepenny-gui


I have an Event String which I want to sink into a textarea. This works fine, but now I want to combine the current value of a checkbox selection to this string.

First I did this by using checkedChange of the checkbox which works, but has a problem. If the checked value is sinked to the checkbox, there is no checkedChange-Event and the value shown in the textarea isn't updated properly.

I could read the checkbox selection with get checked but then I run into problems combining Event String and UI Bool (or UI String as the boolean is going to be transformed to a string).

EDIT: To be more precise, I want to do something like

bCombinedValue <- stepper "" eCombinedValue
element textArea # sink UI.text bCombinedValue

where eCombinedValue has the original Event String and the current value of the checked attribute of a checkbox.

I could have

bCheck <- stepper False $ UI.checkedChange checkBox

but this fails if I have

element checkBox # sink UI.checked bBool

somewhere else (no UI.checkedChange).

I can use show <$> get UI.checked checkBox but then I would have to combine Event String and UI String.


Solution

  • This is intentional: The UI.checkedChange event only triggers when the user clicks the checkbox, but not when it is set programmatically. The intention is that the bBool behavior represents the canonical state of the checkbox and the UI.checkedChange event represents request from the user to change it, which may or may not be granted. This allows bidirectional dataflow (see also). Admittedly, Threepenny does not strictly follows these ideas just yet.

    In your case, I recommend to integrate the UI.checkedChange event into the bBool behavior to represent the "canonical" state of the checkbox. If that doesn't work, just hack it up with get UI.checked and Reactive.Threepenny.unsafeMapIO.