I’m building a page with elm-ui (the most recent one) where I have a couple of floating elements that may or may not appear depending on certain conditions.
I express this with a list of inFront attributes for the layout element. For now I make them appear and disappear by swapping them the inFront content with Element.none, like so
[
--...
, Element.inFront
(if model.toSave then
Element.el [ Element.alignBottom, Element.centerX ]
(Element.Input.button [] { onPress = Nothing, label = Element.el [] <| Element.text "Save" })
else
Element.none
)
-- ...
]
However I can’t say I’m satisfied with this solution; it looks ugly and hard to read. Can I get some suggestions on how to make it better?
First: I normally use qualified imports, but not for elm-ui code:
, inFront
(if model.toSave then
el [ alignBottom, centerX ]
(Input.button [] { onPress = Nothing, label = el [] <| text "Save" })
else
none
)
Looks less ugly already…
You can also create yourself a helperfunction:
renderIf : Bool -> Element msg -> Element msg
renderIf condition content =
if condition then
content
else
none
So that your code looks something like this:
, inFront <| renderIf model.toSave <|
el [ alignBottom, centerX ]
(Input.button [] { onPress = Nothing, label = el [] <| text "Save" })
A somewhat similar problem is discussed in this thread.
You may check to see if any of those ideas are acceptable.
I would extract the if model.toSave ... portion out to another top level function. Something like viewSaveButton : { a | toSave : Bool } -> Element Msg or possibly viewSaveButton : Bool -> Element Msg. Then your parent element is
...
[ Element.inFront (viewSaveButton model)
, Element.inFront (viewOtherElement model)
, ...
]
For me, moving chunks of code to a top level function is a great way to help with readability. I often do this with the children of my elements to.