Work with elm and select

后端 未结 5 1019
既然无缘
既然无缘 2021-02-07 04:41

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

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

view : Mode         


        
相关标签:
5条回答
  • 2021-02-07 04:47

    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

    0 讨论(0)
  • 2021-02-07 04:59

    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 }
    
    0 讨论(0)
  • 2021-02-07 05:01

    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) ]
    
    0 讨论(0)
  • 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 }
    
    0 讨论(0)
  • 2021-02-07 05:09

    An example with onInput handler (you can also check the Ellie):

    module Main exposing (main)
    
    import Browser import Html exposing (Html, button, div, text, select, option) import Html.Attributes exposing (value, selected) import Html.Events exposing (onInput) import Dict exposing (Dict)
    
    type alias Model =
        { options : Dict Int (String, Bool)
        }
    
    
    initialModel : Model initialModel =
        { options = Dict.fromList [(0, ("All time", False)), (1, ("One week", True)), (2, ("24h", False))] 
        }
    
    
    type Msg
        = Select String
    
    
    update : Msg -> Model -> Model update msg model =
        case msg of
            Select value ->
                case String.toInt value of
                    Just selectedID ->
                        let
                            changeSelection id (label, _) =
                                if id == selectedID then
                                    (label, True)
                                else
                                    (label, False)
                        in
                        {model | options = Dict.map changeSelection model.options}
    
                    Nothing ->
                        model
    
    
    
    view : Model -> Html Msg view model =
        let
            toOption (id, (label, isSelected)) =
                option [value (String.fromInt id), selected isSelected] [text label]
        in
        div []
            [ select [onInput Select] (List.map toOption <| Dict.toList model.options)
            , div [] [text "DEBUG"]
            , div [] [text <| Debug.toString model.options]
            ]
    
    
    main : Program () Model Msg main =
        Browser.sandbox
            { init = initialModel
            , view = view
            , update = update
            }
    
    0 讨论(0)
提交回复
热议问题