Skip to content

Instantly share code, notes, and snippets.

@breadchris
Created January 26, 2024 03:22
TODO App Elm
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
type alias Todo =
{ id : Int
, text : String
, done : Bool
}
type alias Model =
{ todos : List Todo
, nextId : Int
, newTodo : String
, currentUser : String
}
type Msg
= AddTodo String
| ToggleTodo Int
| DeleteTodo Int
| ChangeNewTodo String
update : Msg -> Model -> Model
update msg model =
case msg of
AddTodo text ->
{ model | todos = Todo model.nextId text False :: model.todos
, nextId = model.nextId + 1
, newTodo = ""
}
ToggleTodo id ->
{ model | todos = List.map (toggleTodo id) model.todos }
DeleteTodo id ->
{ model | todos = List.filter (\todo -> todo.id /= id) model.todos }
ChangeNewTodo string ->
{ model | newTodo = string }
toggleTodo : Int -> Todo -> Todo
toggleTodo id todo =
if todo.id == id then
{ todo | done = not todo.done }
else
todo
view : Model -> Html Msg
view model =
div []
[ viewNavbar model.currentUser
, viewNewTodoInput model.newTodo
, viewTodos model.todos
]
viewNavbar : String -> Html Msg
viewNavbar user =
div []
[ text ("Logged in as: " ++ user)
-- Add UI for deletion
]
viewTodos : List Todo -> Html Msg
viewTodos todos =
ul []
(List.map viewTodo todos)
viewTodo : Todo -> Html Msg
viewTodo todo =
li
[ onClick (ToggleTodo todo.id) ]
[ text todo.text
]
viewNewTodoInput : String -> Html Msg
viewNewTodoInput newTodoText =
div []
[ input [ placeholder "Add new todo", value newTodoText, onInput ChangeNewTodo ] []
, button [ onClick (AddTodo newTodoText) ] [ text "Add" ]
]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, update = update
, view = view
}
initialModel : Model
initialModel =
{ todos = []
, nextId = 0
, currentUser = "John Doe"
, newTodo = ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment