Elm: Generating controls Dynamically

Intro

In this post, I attempt to document my understanding of how to generate controls dynamically and handle their events within the Elm programming language.

Mapping a Dataset to Checkboxes

Within project Nikeza, I defined the following Topic type:

type Topic
    = Topic String


getTopic : Topic -> String
getTopic topic =
    let
        (Topic value) =
            topic
    in
        value

I have a TestAPI that provides arbitrary topics:

topics : Id -> List Topic
topics profileId =
    profileId
        |> links All
        |> List.map (\p -> p.topics)
        |> List.concat

The topics property of the Link type can be found here:

type alias Link =
    { contributor : Profile
    , title : Title
    , url : Url
    , topics : List Topic
    }

I dynamically generate a set of checkboxes per topic here:

div [] (topics |> List.map toCheckbox)

Thus, the toCheckbox button can be found here:

toCheckbox : Topic -> Html Msg
toCheckbox topic =
    div []
        [ input [ type_ "checkbox", checked True, onCheck (\b -> Toggle ( topic, b )) ] [ text <| getTopic topic ]
        , label [] [ text <| getTopic topic ]
        ]

Handling Events

The onCheck attribute referenced above requires a function that takes a Boolean value and returns a Msg. In this case, the message that gets returned is Toggle (topic,b).

The Toggle message is a case value that can be found in the following discriminated union:

type Msg
    = UrlChange Navigation.Location
    ...
    | Toggle ( Topic, Bool )
    ...

The Update function will do a pattern match on the Toggle case value and perform some filtering logic on links that are associated to the topic checkbox controls.

Here’s the code:

Toggle ( topic, include ) ->
            let
                contributor =
                    model.contributor

                toggleTopic contentType links =
                    if include then
                        List.append (contributor.profile.id |> runtime.topicLinks topic contentType) links
                    else
                        links |> List.filter (\a -> not (a.topics |> List.member topic))

                newState =
                    { model
                        | contributor =
                            { contributor
                                | answers = contributor.answers |> toggleTopic Answer
                                , articles = contributor.articles |> toggleTopic Article
                                , videos = contributor.videos |> toggleTopic Video
                                , podcasts = contributor.podcasts |> toggleTopic Podcast
                            }
                    }
            in
                ( newState, Cmd.none )

Conclusion

In conclusion, I attempted to document my understanding of how to generate controls dynamically and handle their events within the Elm programming language.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: