Search code examples
elm

How to implement a slider in elm


I want to link a slider and a input text area such that when I change one the other is automatically updated. I found elm-reactor's implementation, which uses native JavaScript and works with a callback. The callback is called whenever the slider is moved but I can't get it to move when the value is changed from the text area...


Solution

  • It's not that hard in fact. This code shows how to set the value of the two input types. See ellie for example

    Update for 0.19

    type alias Model =
        Int
    
    
    type Msg
        = Update String
    
    
    update : Msg -> Model -> Model
    update (Update v) model =
        String.toInt v |> Maybe.withDefault 0
    
    
    view model =
        div []
            [ input
                [ type_ "range"
                , Attrs.min "0"
                , Attrs.max "20"
                , value <| String.fromInt model
                , onInput Update
                ]
                []
            , text <| String.fromInt model
            ]
    

    Update for 0.18

    import Html exposing (Attribute, div, text, input)
    import Html.Attributes as H exposing (..)
    import Html.Events exposing (on, onInput)
    import Json.Decode exposing (string, map)
    import String
    
    type alias Model = Int
    
    type Msg
        = Update String
    
    update : Msg -> Model -> Model
    update (Update v) model =
        String.toInt v |> Result.withDefault 0
    
    view model =
      div []
        [ input
          [ type_ "range"
          , H.min "0"
          , H.max "20"
          , value <| toString model
          , onInput Update
          ] []
        , text <| toString model
        ]
    
    main =
      Html.beginnerProgram
        { model = 0
        , view = view
        , update = update
        }
    

    Update for 0.17

    import Html exposing (Attribute, div, text, input)
    import Html.App as Html
    import Html.Attributes as H exposing (..)
    import Html.Events exposing (on, onInput)
    import Json.Decode exposing (string, map)
    import String
    
    type alias Model = Int
    
    type Msg
        = Update String
    
    update : Msg -> Model -> Model
    update (Update v) model =
        String.toInt v |> Result.withDefault 0
    
    view model =
      div []
        [ input
          [ type' "range"
          , H.min "0"
          , H.max "20"
          , value <| toString model
          , onInput Update
          ] []
        , text <| toString model
        ]
    
    main =
      Html.beginnerProgram
        { model = 0
        , view = view
        , update = update
        }
    

    ** Original O.16 version **

    import Html exposing (div, text, input)
    import Html.Attributes as H exposing (..)
    import Html.Events as E 
    
    mbox = 
      Signal.mailbox "0"
    
    view v =
      let 
        evth = E.on "change" E.targetValue (Signal.message mbox.address)
      in
      div [] 
        [ input 
          [ type' "range"
          , H.min "0"
          , H.max "20"
          , value v
          , evth
          ] []
        , input
          [ type' "text", value v, evth ] []
        ]
    
    
    main =
      Signal.map view mbox.signal