Reputation: 43
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
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