billyJoe
billyJoe

Reputation: 2064

Change a record value with a select in Elm

I try to do a simple thing, but it's hard to me to understand how to code. Suppose this record

type alias Model =
  { month : Int
  , cost : Int
  , email : String
  }

I have 2 ways to work with this model: - either user changes month and it's dynamically change cost (cost = month * 10) in this example - or user submits and it send data to a server with a json format

My view looks like:

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

view model =
  Html.div []
    [ 
    , input [ placeholder "[email protected]" ] []
    , select []
      (List.map durationOption [0..12]) -- month selector
    , Html.span [][text (toString model.total)] -- value automatically updated when users changes month value in the select
    , button [ onClick Submit ] [text "Send"]
    ] 

Unfortunately, i do not understand how to update values, how to just update the cost:

update : Msg -> Model -> (Model, Cmd Msg)
update action model =
  case action of
    Submit ->
      (model, Cmd.none)
    {-
    Calculate ->
       ???? 
    -}

I think I have to call Calculate, but I really do not understand how to do. I ve read example from documentation but there is nothing with select ... Can someone help me please ?

Upvotes: 3

Views: 1153

Answers (1)

Chad Gilbert
Chad Gilbert

Reputation: 36375

As in your previous question, you will have to handle the change event on the dropdown to be notified of changes.

First let's define a Message that we can use for changes in the Month dropdown.

Updated to Elm-0.18

type Msg
  = Submit
  | MonthChanged Int

We then need to incorporate MonthChanged into the on event handler. This is done with Json decoders, but you'll need a Json decoder that turns the string value in the option into an integer, so let's use targetValueIntParse from elm-community/html-extra to define the on "change" handler. Your select code looks like this:

select [ on "change" (Json.map MonthChanged targetValueIntParse) ]

Lastly, your update function needs to set the month and cost values in the model. You can do this by adding the following to your case statement:

MonthChanged month ->
  ({ model | month = month, cost = month * 10 }, Cmd.none)

I've posted a working example https://runelm.io/c/h2k that you can run in the browser

Upvotes: 6

Related Questions