Search code examples
listfunctional-programmingelm

How to store strings and integers in a list in elm?


I'm programming a Team Creator in which the user can write the name of the player and his strength. (So assuming the user writes 10 Players there are 5 Teams with 2 players each generated. I don't know how to store the values the users writes in the input (The values have to be stored since the input is empty again when the user presses the enter button in order to add the next player). I have already initialized the variables and the list but Im stuck when it comes to store the values.

My existing Elm Code:

import Browser
import Html exposing (Html, Attribute, button, text, h1, div, input, text)
import Html.Attributes exposing (style)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)




-- MAIN


main =
  Browser.sandbox { init = init, update = update, view = view }



-- MODEL
type alias Player =
  { player : String
  , strength : Int
  }


type alias Model =
  { content : String
  , teams : List Player
  }





init : Model
init =
  { content = ""
  , teams = []
   }



-- UPDATE


type Msg
  = Change String


update : Msg -> Model -> Model
update msg model =
  case msg of
    Change newContent ->
      { model | content = newContent }



-- VIEW

view : Model -> Html Msg
view model =
  div []
    [ h1 [style "font-family" "impact"] [ text "Team Creator" ]
    , div[] [ input [ placeholder  "🏅 Team 1", style "width" "300px", style "height" "30px", style "font-size" "25px", style "color"  "#488aff"] [] ]
    , input [ placeholder  "💪🏼 Strength", style "width" "300px", style "height" "30px", style "font-size" "25px", style "color"  "#32db64"] []
    , div [] [ button [ style "background-color" "#66cc81", style "color" "white", style "margin-top" "20px", style "width" "300px", style "border-radius" "25px", style "height" "60px", style "font-size" "30px", style "margin-right" "70px"] [ text "+ADD" ] ]
    ]

Solution

  • In Elm, if you want to capture the values of inputs, you need to use onInput for each field you care about. These will send a message containing the text to update each time the field changes. You'll end up creating one message per field that updates your model with the new value.

    Then, when the user clicks a button to submit — use onClick to handle this — the update function should convert and validate those values stored in model. If they're good, make them into a Player and push it into the model.teams list!

    From here, you could modify it to give feedback about errors when submitting, or even in realtime. But focus on getting the above working first! Refactoring is cheap in Elm.

    The official guide has a section on the Elm Architecture and how buttons, text fields, and forms work within it. It's a good read that should hopefully clarify how all of these messages get sent out and flow through your program.