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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With