Work with elm and select
This works with Ellie on Elm 0.19.0: https://ellie-app.com/58wGf2YsR9Ya1
Full code:
import Browser
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 =
Browser.sandbox { init = init, view = view, update = update }
init =
{ duration = 1 }
durationOption duration =
option [ value (String.fromInt duration) ] [ text (String.fromInt 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: " ++ (String.fromInt model.duration) ]
]
type Msg
= SetDuration Int
type alias Model =
{ duration : Int }
update msg model =
case msg of
SetDuration val ->
{ model | duration = val }
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
For future reference for Elm-newbies (like me): with Elm 0.18.0 + elm-lang/html 2.0.0, the onInput
event (see code below) works. (Also notice the difference in int range notation (List.range 0 12
instead of [0..12]
).
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
main =
Html.beginnerProgram
{ model = model
, view = view
, update = update
}
-- MODEL
type alias Model =
{ duration : Int
}
model : Model
model =
Model 0
-- UPDATE
type Msg
= SetDuration String
update : Msg -> Model -> Model
update msg model =
case msg of
SetDuration s ->
let result =
String.toInt s
in
case result of
Ok v ->
{ model | duration = v }
Err message ->
model
-- VIEW
view : Model -> Html Msg
view model =
div []
[ select [ onInput SetDuration ]
(List.range 0 12 |> List.map intToOption)
, div [] [ text <| "Selected: " ++ (toString model.duration) ]
]
intToOption : Int -> Html Msg
intToOption v =
option [ value (toString v) ] [ text (toString v) ]
Here is an update for Elm 0.19:
module Main exposing (main)
import Browser
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 =
Browser.sandbox { init = { duration = 1 }, view = view, update = update }
durationOption duration =
option [ value (String.fromInt duration) ] [ text (String.fromInt 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: " ++ (String.fromInt model.duration) ]
]
type Msg
= SetDuration Int
type alias Model =
{ duration : Int }
update msg model =
case msg of
SetDuration val ->
{ model | duration = val }