Jason Anderson
Jason Anderson

Reputation: 43

Setting model value from input?

I am trying to make a To Do List with Elm and I am having problems figuring out how to set value from the input to add it to the list in model:

module ToDoList exposing (..)
import Browser
import Html exposing (Html, div, text, li, button, ul, input)
import Html.Events exposing (onClick)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)


type alias Model = List String

type Msg =
 NewTask String


init : Model
init = ["Premade Task"]
type alias AddToDo =
    { newTask : String
    , status: String }

update : Msg -> Model -> Model
update msg model =
    case msg of
        NewTask newContent ->
            model ++ [newContent]

view : Model -> Html Msg
view model =
    div [] [
        input [ placeholder "New Task", value model.content, onInput NewTask ] []
        , button [ onClick <| (NewTask model.content) ] [text "Add a task"]
        , ul [] (List.map viewTodo model)
      ]
viewTodo todo =
    li [] [text todo]

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

I've tried making Model a tuple but didn't work out, what is the correct way of implementing this, I just need to take value from the input and add it to the list when I click on the "Add a Task" button.

Upvotes: 1

Views: 379

Answers (1)

viam0Zah
viam0Zah

Reputation: 26312

You need a way to temporary store the todo item being typed before adding to the collection. In the following example I introduced a draft field on the Model. I introduced a new message type DraftTask, too, that gets dispatched as long as the user is typing. When they hit the button, the program appends the draft value to todos list.

module ToDoList exposing (..)

import Browser
import Html exposing (Html, button, div, input, li, text, ul)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)


type alias Model =
    { todos : List String
    , draft : String
    }


type Msg
    = NewTask
    | DraftTask String


init : Model
init =
    { todos = [ "Premade Task" ]
    , draft = ""
    }


update : Msg -> Model -> Model
update msg model =
    case msg of
        NewTask ->
            { model
                | todos = model.todos ++ [model.draft]
                , draft = ""
            }

        DraftTask s ->
            { model | draft = s }


view : Model -> Html Msg
view model =
    div []
        [ input [ placeholder "New Task", value model.draft, onInput DraftTask ] []
        , button [ onClick <| NewTask ] [ text "Add a task" ]
        , ul [] (List.map viewTodo model.todos)
        ]


viewTodo todo =
    li [] [ text todo ]


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

Upvotes: 1

Related Questions