-
Notifications
You must be signed in to change notification settings - Fork 1
/
Todos.elm
125 lines (98 loc) · 2.57 KB
/
Todos.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
module Todos exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
type alias State =
{ todos : List Todo
, newTodoId : Int
, newTodoText : String
}
type alias Todo =
{ id : Int
, text : String
, completed : Bool
}
type Msg
= Input String
| NewTodo
| ToggleTodo Int
| DeleteTodo Int
| Cancel
initState : State
initState =
{ todos = [], newTodoId = 0, newTodoText = "" }
update : Msg -> State -> State
update msg state =
case msg of
Input text ->
{ state | newTodoText = text }
NewTodo ->
addTodo state
ToggleTodo id ->
toggleTodo state id
DeleteTodo id ->
deleteTodo state id
Cancel ->
{ state | newTodoText = "" }
addTodo : State -> State
addTodo state =
let
todo =
Todo state.newTodoId state.newTodoText False
in
{ state
| newTodoText = ""
, newTodoId = state.newTodoId + 1
, todos = todo :: state.todos
}
toggleTodo : State -> Int -> State
toggleTodo state id =
{ state
| todos =
List.map
(\t ->
if t.id == id then
Todo id t.text (not t.completed)
else
t
)
state.todos
}
deleteTodo : State -> Int -> State
deleteTodo state id =
{ state | todos = List.filter (\t -> t.id /= id) state.todos }
view : State -> Html Msg
view { newTodoText, todos } =
div []
[ todoForm newTodoText
, ul [] (todos |> List.filter (not << .completed) |> List.map todo)
, ul [] (todos |> List.filter .completed |> List.map todo)
]
todoForm : String -> Html Msg
todoForm newTodoText =
Html.form [ onSubmit NewTodo ]
[ input
[ type_ "text"
, placeholder "Add todo..."
, onInput Input
, value newTodoText
]
[]
, button [ class "submit", type_ "submit" ] [ text "+" ]
, button [ class "cancel", type_ "button", onClick Cancel ] [ text "x" ]
]
todo : Todo -> Html Msg
todo todo =
let
className =
if todo.completed then
"completedTodo"
else
""
in
li [ class className ]
[ span
[ onClick <| ToggleTodo todo.id ]
[ text todo.text ]
, button [ onClick <| DeleteTodo todo.id ] []
]