Slide 1

Slide 1 text

Structuring Views in Elm

Slide 2

Slide 2 text

Common Views

Slide 3

Slide 3 text

div [ class "survey" ] [ div [class "survey-section" ] [ h2 [ class "section-title" ] [ text "Food" ] , div [ class "question" ] [ div [ class "question-text" ] [ text "Pineapple on Pizza?" ] , div [] [ label [ for "pop-yes" ] [ text "Yes"] , input [ type_ "radio" , id "pop-yes" , name "pop" , onCheck (always <| PoP True) ] [] , label [ for "pop-no" ] [ text "No"] , input [ type_ "radio" , id "pop-no" , name "pop" , onCheck (always <| PoP False) ] [] ] ] ] -- repeat for anchovies ]

Slide 4

Slide 4 text

Hard to read

Slide 5

Slide 5 text

Extract Method

Slide 6

Slide 6 text

Extract Method Function

Slide 7

Slide 7 text

radio : Msg -> String -> String -> String -> Html Msg radio msg groupName idSuffix labelText = ...

Slide 8

Slide 8 text

div [ class "survey" ] [ div [class "survey-section" ] [ h2 [ class "section-title" ] [ text "Food" ] , div [ class "question" ] [ div [ class "question-text" ] [ text "Pineapple on Pizza?" ] , div [] [ radio (PoP True) "pop" "-yes" "Yes" , radio (PoP False) "pop" "-no" "No" ] ] ] -- repeat for anchovies ]

Slide 9

Slide 9 text

Top-down

Slide 10

Slide 10 text

That's a lot of arguments

Slide 11

Slide 11 text

Layered API

Slide 12

Slide 12 text

elm/html

Slide 13

Slide 13 text

node : String -> List (Attribute msg) -> List (Html msg) -> Html msg

Slide 14

Slide 14 text

div : List (Attribute msg) -> List (Html msg) -> Html msg div attributes children = node "div" attributes children

Slide 15

Slide 15 text

yesNoQuestion : String -> (Bool -> Msg) -> String -> Html Msg yesNoQuestion questionText tagger groupName = ...

Slide 16

Slide 16 text

div [ class "survey" ] [ div [class "survey-section" ] [ h2 [ class "section-title" ] [ text "Food" ] , yesNoQuestion "Pineaple on Pizza?" PoP "pop" ] -- repeat for anchovies ]

Slide 17

Slide 17 text

Bottom-up

Slide 18

Slide 18 text

surveySection : String -> List (Html a) -> Html a surveySection sectionTitle questions = ...

Slide 19

Slide 19 text

survey : List (Html a) -> Html a survey sections = ...

Slide 20

Slide 20 text

survey [ surveySection "Toppings" [ yesNoQuestion "Pineaple on Pizza?" PoP "pop" -- repeat for anchovies ] ]

Slide 21

Slide 21 text

The reader shouldn't be able to tell what technology you used for you view

Slide 22

Slide 22 text

In particular, try to avoid duplicating CSS classes

Slide 23

Slide 23 text

survey [ surveySection "Toppings" [ yesNoQuestion "Pineaple on Pizza?" PoP "pop" , yesNoQuestion "Anchovies?" Anchovies "ancho" ] , surveySection "Crust" [ pickOne [ ("Thin Crust", Thin) , ("Thick Crust", Thick) , ("Chicago Style", Chicago) ] ] ]

Slide 24

Slide 24 text

Bonus tips: Conditions

Slide 25

Slide 25 text

Separate conditional logic from content

Slide 26

Slide 26 text

viewMessage : Message -> Html a viewMessage message div [ if message.isError then (class "red") else (class "green") ] [ text message.text ]

Slide 27

Slide 27 text

messageClass : Bool -> Html.Attribute a messageClass isError = ...

Slide 28

Slide 28 text

viewMessage : Message -> Html a viewMessage message div [ messageClass message.isError ] [ text message.text ]

Slide 29

Slide 29 text

Push up conditional logic

Slide 30

Slide 30 text

viewMessage : Message -> Html a viewMessage message div [ if message.isError then (class "red") else (class "green") ] (if message.isError then [ errorIcon, text message.text ] else [ text message.text ] )

Slide 31

Slide 31 text

viewMessage : Message -> Html a viewMessage message div [ messageClass message.isError ] (messageContent message)

Slide 32

Slide 32 text

viewMessage : Message -> Html a viewMessage message if message.isError then errorMessage message.text else successMessage message.text

Slide 33

Slide 33 text

Easier to understand individual messages

Slide 34

Slide 34 text

errorMessage : String -> Html a errorMessage content = div [ class "red" ] [ errorIcon, text content ]

Slide 35

Slide 35 text

successMessage : String -> Html a successMessage content = div [ class "green" ] [ text content ]