Changes to other items based on a list selection in three pennies

So, I have a simple example of a layout with a list, button and text box, where clicking the button changes the text in the text box:

import Control.Applicative
import Control.Monad
import Data.Maybe

import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core

main :: IO ()
main = startGUI defaultConfig setup

setup :: Window -> UI ()
setup w = do
    return w # set UI.title "Simple example"

    listBox     <- UI.listBox   (pure ["First", "Second"]) (pure Nothing) ((UI.string .) <$> (pure id))
    button      <- UI.button    # set UI.text "Button"
    display     <- UI.textarea  # set UI.text "Initial value"

    element listBox # set (attr "size") "10"    

    getBody w   #+ [element listBox, element button, element display]

    on UI.click button $ const $ do
        element display # set UI.text "new text"

I would like to make a change depending on the choice of the list (for example, based on the selection, select "new text"be "First"or "Second").

I can easily get a choice by combining userSelectionand factshow

facts . userSelection :: ListBox a -> Behavior (Maybe a)

but since setting the value for textarea is done with

set text :: String -> UI Element -> UI Element

I do not know how to get around the fact that the choice is Behavior.

All this seems a little uniomatic for me, and I was wondering how to do it right. Maybe I should do something when the selection or change of the list is selected, and not just when the button is clicked.

+4
3

, , . . Threepenny 0.6.0.3 , .


pastebin, , . , sink - sink .

, :

{-# LANGUAGE RecursiveDo #-}
module Main where

import Control.Applicative
import Control.Monad
import Data.Maybe

import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core

main :: IO ()
main = startGUI defaultConfig setup

setup :: Window -> UI ()
setup w = void $ mdo
    return w # set UI.title "Simple example"

    listBox <- UI.listBox
        (pure ["First", "Second"]) bSelected (pure $ UI.string)
    button  <- UI.button # set UI.text "Button"
    display <- UI.textarea

    element listBox # set (attr "size") "10"

    getBody w #+ [element listBox, element button, element display]

    bSelected <- stepper Nothing $ rumors (UI.userSelection listBox)
    let eClick = UI.click button
        eValue = fromMaybe "No selection" <$> bSelected <@ eClick
    bValue    <- stepper "Initial value" eValue

    element display # sink UI.text bValue

, :

  • Behavior (Maybe a) listBox , . facts $ UI.userSelection listBox - bSelected, Widgets.
  • - (<@) ( <@>, , ).
+4

: ThreePenny, .

, sink :

element display # sink UI.text ((maybe "new text" id) <$> (facts $ userSelection listBox)) 
+1

Try creating a step item for the list, and then just uncheck to display

listB <- stepper Nothing (userSelection listBox)
element display # sink UI.text ((maybe "new text" id) <$> (listB) 

Then, if you want to try the behavior with the button

listB <- stepper Nothing (userSelection listBox)
button      <- UI.button    # set UI.text "Button"
cutedListB <- stepper Nothing (listB <@ UI.click button)
element display # sink UI.text ((maybe "new text" id) <$> (listB) 
+1
source

All Articles