如何从 reflex-dom 列表框中获取 DoubleClicked 事件
How to get a DoubleClicked event from a reflex-dom listbox
以下代码将 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 class.
- 在 Dropdown 记录的值 _dropdown_change 中筛选事件。但是我没有找到任何方法来仅过滤 DoubleClick 事件。
- 使用新类型 EventSelector。我又没看到我可以使用它。
问题:如何获取双击事件?
您可以使用 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)
以下代码将 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 class.
- 在 Dropdown 记录的值 _dropdown_change 中筛选事件。但是我没有找到任何方法来仅过滤 DoubleClick 事件。
- 使用新类型 EventSelector。我又没看到我可以使用它。
问题:如何获取双击事件?
您可以使用 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)