Experimental reuse of code in Elm, Part III — Counters Bonanza

Lucamug
3 min readMay 6, 2017

--

Experimenting with recycling Elm code transforming it in a module

You can find the code for this post at https://github.com/lucamug/elm-multiple-buttons-II

In the previous article I took the counter in the “buttons” official example and I duplicated it in the page.

Then I tried to generalise the importer module and eventually I wrote a module that was enough generic that I could import it again to create list of list of counters just changing few lines of code at the beginning of the module.

For details please refer to the previous article.

The view in the two modules that load the counters and the list of counters is

view model =
div [ style [ ( "margin", "10px" ) ] ]
[ button [ onClick (Add) ] [ text "Add" ]
, div []
(List.indexedMap
(\index element ->
div
[ style
[ ( "border", "1px solid #aaa" )
, ( "background-color", "#eee" )
, ( "display", "inline-block" )
, ( "padding", "10px" )
, ( "margin", "10px" )
]
]
[ Html.map
(MsgFromChild index)
(div
[]
[ Imported.view element ]
)
, button [ onClick (Remove index) ]
[ text "Remove" ]
]
)
model
)
, pre [] [ text ("model: " ++ (toString model)) ]
]

Compared to the previous version, I added here two buttons

  1. “Remove” that remove one element from the list
  2. “Add” that add one element from the list

So now is possible to add and remove elements from the lists.

The list of messages is now

type Msg
= MsgFromChild Int Imported.Msg
| Remove Int
| Add

and the updated function is

update msg model =
case msg of
MsgFromChild index msgFromChild ->
let
oldElement =
getElementFromList model index
defaultElementIfNothing
newElement =
Imported.update msgFromChild oldElement
in
setElementIntoList model index newElement
Remove index ->
removeElementFromList index model
Add ->
List.append model [ defaultElementIfNothing ]

To test the code you need to

$ git clone https://github.com/lucamug/elm-multiple-buttons-II.git
$ cd elm-multiple-buttons/
$ elm-reactor

The three module can be accessed independently and they retain their functionalities. You can also see these in these compiled codepen examples:

buttons.elm
buttonslist.elm
main.elm

The only differences between buttonslist.elm and main.elm are:

So I guess these two modules could be brought together somehow, for DRY sake.

Here you can find a version with an extra level and some color:

These are the levels in this second example:

level0.elm
level1.elm
level2.elm
buttons.elm

--

--

No responses yet