Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way in reflex-dom to handle a modal dialog?

Tags:

haskell

reflex

I am just starting with the reflex-dom library and I cannot quite figure out the proper and convenient way to work with dialogs.

Showing a dialog generally means adding a few elements to the end of <body> and removing it when the user clicks on some button, backdrop or presses e.g. escape. However doing this from some nested widget means somehow bubbling up the event ('show the dialog') to the top, which could be quite clumsy. Is there any other way to do it nicely? I just had a look at markup.rocks and that seems to use some JS/jQuery hacks.

I can decide not to use modal dialogs (it may not be a bad option after all), but for some things I may really need it.

like image 655
ondra Avatar asked Sep 26 '22 05:09

ondra


1 Answers

Ultimately I found it quite easy:

First, get the body element:

getBody = do
  root <- askDocument
  Just nodelist <- getElementsByTagName root ("body" :: String)
  Just body <- nodelist `item` 0
  return body

Then, assuming trigger is the Event that triggers opening the dialog and visible is a Dynamic t Bool that holds the current state, we can create a backdrop and move it to the back of body:

backdropAttr <- forDyn visible (\vis -> if vis then ("class" =: "modal-backdrop fade in")
                                          else ("style" =: "display:none"))
(backdrop, _) <- elDynAttr' "div" backdropAttr blank
body <- getBody
let moveBackdrop = (const $ (appendChild body (Just $ _el_element backdrop))) `fmap` trigger
performEvent_ $ void `fmap` moveBackdrop
like image 128
ondra Avatar answered Nov 15 '22 10:11

ondra