One Model...
I created a web site for my and clergy colleagues' use (legereme.com) . There is nothing special about it except that it works and it's written using Elixir, Phoenix, and Elm (which is really cool).
Now, I have a couple of colleagues generating content for it. My colleagues are brilliant and insightful people but frequently struggle with 20th [sic] century technology. They are just not computer people (how brilliant and insightful people can not be technologically insightful and brilliant is beyond me).
I want them to generate their content using markdown formatting as I think it is within their grasp and makes my life easier when it comes to publishing their content. Even so, they grew up with WYSIWYG word processors and the concept of data being separate from presentation is, perhaps, just at the limit of their technological reach.
First I considered having a <preview> button, but decided more immediate feedback would be desirable.
Elm to the rescue. And as it turned out, easier to implement than a <preview> button.
The content creation page is very simple with a couple of buttons, a textarea, and preview area. The user enters markdown into the textarea and simultaneously appears formatted in the preview area. Simple. And unbelievably easy to implement in Elm.
The page has a single model and changes to the model cascade through the page. The user enters a character in the textarea...
inputText model =
p [ id "refl-textarea"]
[ textarea
[ id "reflection-text"
, name "reflection-text"
, placeholder "Use Markdown formatting"
, Html.Attributes.value model.text
, onInput ReflectionText
, autofocus True
]
[]
]
The relevant bit is "onInput ReflectionText". When the text in the textarea changes, the single model is updated. That code looks like...
ReflectionText s -> ( { model | text = s }, Cmd.none)
"s" is the text in the textarea, and the "text" element in the model is updated. When the model is updated, Elm handles the bit of seeing if anything else on the page needs to be updated. As it turns out, the preview area displays the text element of the model, presuming it is in markdown format...
div [id "md-text"] [Markdown.toHtml [] model.text]
And that's all there is to it.
There are two bits of Elm brilliance at play here. The first being; there is a single model. Admittedly, this was a bit hard for me to wrap my head around at first, but having accepted the "Elm way" I can see the superiority of using a single model. But that's just a technique, a worthy technique.
The second bit of Elm brilliance is Elm watching for changes in the model and updating anything that depends on that model. Brilliant, just brilliant.