如何从reflex-dom列表框

时间:2017-01-14 22:04:13

标签: haskell reflex

以下代码在视觉上以列表框形式显示reflex-dom下拉元素,并在底部始终显示最后选择(单击)的行。

{-# LANGUAGE OverloadedStrings #-}
import           Reflex.Dom
import qualified Data.Text as T
import qualified Data.Map as Map
import           Data.Monoid((<>))
import           Data.Maybe (fromJust)

main :: IO ()
main = mainWidget $ el "div" $ do
  dd <- dropdown "2" (constDyn countries) $ def & attributes .~ constDyn ("size" =: "10")
  el "p" $ return ()
  let selItem = result <$> value dd 
  dynText selItem
  return ()

countries :: Map.Map T.Text T.Text
countries = Map.fromList [("1", "France"), ("2", "Switzerland"), ("3", "Germany"), ("4", "Italy"), ("5", "USA")]

result :: T.Text -> T.Text
result key = "You selected: " <> fromJust (Map.lookup key countries)

我想更改此代码,因此它始终显示在最后双击行的底部!

我尝试了几件事

  • 使用 domEvent 函数:这不起作用,因为 Dropdown 不是 HasDomEvent 类的实例。
  • 过滤Dropdown记录的值 _dropdown_change 中的事件。但我没有找到任何方法来过滤DoubleClick事件。
  • 使用newtype EventSelector 。我再也看不到我可以使用它了。

问题:如何获得双击事件?

1 个答案:

答案 0 :(得分:2)

您可以使用domEvent来双击。

以下代码使用elAttr创建一个列表框,就像您使用下拉列表创建的列表框一样。 domEvent函数用于为每个列表框选项创建双击Event,然后将其合并以获得表示最近双击选项的Dynamic

我将保管箱代码留在原处以供比较。

{-# LANGUAGE OverloadedStrings #-}
import           Reflex.Dom
import qualified Data.Text as T
import qualified Data.Map as Map
import           Data.Monoid((<>))
import           Data.Maybe (fromJust)
import           Data.Traversable (forM)


-- a listbox that responds to double clicks
listbox :: MonadWidget t m =>    T.Text                -- default
                              -> Map.Map T.Text T.Text -- entries
                              -> Map.Map T.Text T.Text -- attributes
                              -> m (Dynamic t T.Text)  
listbox def entries attr = do
  optEv <- elAttr "select" attr $ 
             forM (Map.toList entries) $ \(i,c) -> do

               let sel = if i == def
                         then "selected" =: "selected"
                         else mempty 

               (e, _) <- elAttr' "option"  sel $ text c

               return (i <$ domEvent Dblclick e)

  holdDyn def $ leftmost optEv

main :: IO ()
main = mainWidget $ el "div" $ do
  -- original code (responds to single clicks)
  dd <- dropdown "2" (constDyn countries) $ def & attributes .~ constDyn ("size" =: "10")
  el "p" $ return ()
  let selItem = result <$> value dd
  dynText selItem

  el "p" $ return ()

  -- new code (responds to double clicks)
  lb <- listbox "3" countries ("size" =: "10")
  el "p" $ return ()
  let dblItem = result <$> lb
  dynText dblItem

  return ()

countries :: Map.Map T.Text T.Text
countries = Map.fromList [("1", "France"), ("2", "Switzerland"), ("3", "Germany"), ("4", "Italy"), ("5", "USA")]

result :: T.Text -> T.Text
result key = "You selected: " <> fromJust (Map.lookup key countries)