Skip to content

Instantly share code, notes, and snippets.

@madasebrof
Created July 10, 2017 09:37
Show Gist options
  • Save madasebrof/8b2c8a63b31985aaf797d9e7a00400c3 to your computer and use it in GitHub Desktop.
Save madasebrof/8b2c8a63b31985aaf797d9e7a00400c3 to your computer and use it in GitHub Desktop.
Reactive 'select' in Elm 0.18
module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (id, value)
import Json.Decode as Json exposing (Decoder, string, at)
import Html.Events exposing (on)
main =
beginnerProgram
{ model = model
, update = update
, view = view
}
-- TYPES
type alias SelectItem =
{ value : String
, text : String
}
type alias Model =
{ message : String
, selectOne : List SelectItem
, selectTwo : List SelectItem
, selectedOneValue : String
, selectedTwoValue : String
}
type Msg
= ChangeMeal String
| ChangeTime String
-- MODEL
-- Normally, we have an init, subscriptions, etc. but for simplicity, this uses
-- the beginner program.
model : Model
model =
{ message = "Select an item!"
, selectOne =
[ SelectItem "time-period-na" "--"
, SelectItem "time-period-all" "All time"
, SelectItem "time-period-week" "One Week"
, SelectItem "time-period-24h" "24h"
]
, selectTwo =
[ SelectItem "fish" "The Salmon"
, SelectItem "chicken" "Le Poulet"
, SelectItem "stew" "Beef Bourguignon"
, SelectItem "vegetarian" "Vegetable Terrine"
]
, selectedOneValue = "time-period-na"
, selectedTwoValue = "fish"
}
-- returns a zero-indexed integer of selected. Not so useful! Boo!
onSelectIndex : (Int -> msg) -> Html.Attribute msg
onSelectIndex message =
on "change" <| Json.map message <| Json.at [ "target", "selectedIndex" ] Json.int
-- returns the value of the target value. More useful! Yay!
-- (e.g. this is what would be returned if you submitted a form)
onSelectValue : (String -> msg) -> Attribute msg
onSelectValue message =
Json.at [ "target", "value" ] Json.string
|> Json.map message
|> Html.Events.on "change"
-- UPDATE
update : Msg -> Model -> Model
update msg model =
case msg of
ChangeTime value ->
{ model | selectedOneValue = value }
ChangeMeal value ->
{ model | selectedTwoValue = value }
-- VIEW
viewSelect : List SelectItem -> List (Html Msg)
viewSelect itemList =
itemList
|> List.map
(\item ->
option [ value item.value ] [ text item.text ]
)
view : Model -> Html Msg
view model =
div []
[ h1 [] [ text "Reactive 'select' in Elm 0.18!" ]
, h3 [] [ text "See? Not so hard ;)" ]
, p [] [ text model.message ]
, select [ onSelectValue ChangeTime ] (viewSelect model.selectOne)
, p [] [ text ("You selected item with value == " ++ model.selectedOneValue) ]
, select [ onSelectValue ChangeMeal ] (viewSelect model.selectTwo)
, p [] [ text ("You selected item with value == " ++ model.selectedTwoValue) ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment