elm

Work with elm and select


I try to understand how elm works with a custom example.

durationOption duration =
  option [value (toString duration) ] [ text (toString duration)]

view : Model -> Html Msg
view model =
  Html.div []
    [ h2 [] [ text "Month selector"]
    , select []
      (List.map durationOption [1..12])    
    ]

It's an easy example to work with a select. I would like, each time I change the month value it multiplies to value by 10 for example. According to the documentation there is not events like onChange or onSelect, do I have to create mine with on ?


Solution

  • UPDATE: onInput works, see another answer below with 0.19 working code: https://stackoverflow.com/a/41516493/540810

    Yes, you will need to use on to handle the change event. If you look at the source for other event handlers built into Elm, like onClick, you'll see that they are all built using the on function.

    Here's an example that is using targetValueIntParse from elm-community/html-extra for turning the string value from the option into an int.

    Updated to Elm-0.18

    import Html exposing (..)
    import Html.Events exposing (on)
    import Html.Attributes exposing (..)
    import Json.Decode as Json
    import String
    import Html.Events.Extra exposing (targetValueIntParse)
    
    
    main =
        beginnerProgram { model = { duration = 1 }, view = view, update = update }
    
    
    durationOption duration =
        option [ value (toString duration) ] [ text (toString duration) ]
    
    
    view : Model -> Html Msg
    view model =
        Html.div []
            [ h2 [] [ text "Month selector" ]
            , select [ on "change" (Json.map SetDuration targetValueIntParse) ]
                (List.map durationOption (List.range 1 12))
            , div [] [ text <| "Selected: " ++ (toString model.duration) ]
            ]
    
    
    type Msg
        = SetDuration Int
    
    
    type alias Model =
        { duration : Int }
    
    
    update msg model =
        case msg of
            SetDuration val ->
                { model | duration = val }
    

    You can run this example in browser https://runelm.io/c/ahz