2017-01-14 9 views
3

次のコードは、reflex-domドロップダウン要素を視覚的にリストボックスとして表示し、最後に選択された(クリックされた)行を常に下に表示します。Reflex-domリストボックスからDoubleClickedイベントを取得する方法

{-# 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) 

私はこのコードを変更したいので、最後ダブルクリックラインは常に一番下に表示します! ドロップダウンHasDomEventクラスのインスタンスではないので、これは動作しません:

は、私はいくつかのこと
  • domEvent機能を使用

    を試してみました。
  • ドロップダウンリストの_dropdown_changeのイベントをフィルタリングします。しかし、私はDoubleClickイベントだけをフィルタリングする方法を見つけることはできませんでした。
  • newtype EventSelectorを使用してください。もう一度私はそれを使うことができないと私は見ない。

質問:ダブルクリックイベントはどのようにして取得できますか?

答えて

2

domEventをダブルクリックすると利用できます。

次のコードでは、elAttrを使用して、ドロップダウンリストで作成したリストボックスを作成します。 domEvent関数は、リストボックスオプションのそれぞれに対してダブルクリックEventを作成するために使用され、最後にダブルクリックされたオプションを表すDynamicが得られます。

比較目的でDropboxコードをそのまま残しました。

{-# 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) 
+1

多くの感謝!これは非常にクリーンで、良い説明と完璧に動作します。残念ながら私はあなたの答えをアップアップするのに十分なポイントがまだありません... – Jogger

+1

'GHCJS.DOM.Events'をインポートする必要はありません。すべてはReflex.Dom内で行うことができます:_wrapDomEvent_への関数呼び出しは削除でき、次の行は 'return(i <$ domEvent Dblclick e)'と書かれます – Jogger

+0

ありがとう!はい、それはもちろん良いです。私はそれに応じて答えを編集しました。 –

関連する問題