master
Jason Staten 2 years ago
parent 52374088df
commit 3dce44a652

@ -41,8 +41,9 @@ type Todo struct {
} }
type ViewModel struct { type ViewModel struct {
Todos []Todo Todos []Todo
Only string Only string
Incomplete int
} }
func filterSlice[T any](xs []T, pred func(T) bool) []T { func filterSlice[T any](xs []T, pred func(T) bool) []T {
@ -57,6 +58,17 @@ func filterSlice[T any](xs []T, pred func(T) bool) []T {
return result return result
} }
func countSlice[T any](xs []T, pred func(T) bool) int {
count := 0
for _, element := range xs {
if pred(element) {
count += 1
}
}
return count
}
func main() { func main() {
todos := make([]Todo, 0, 10) todos := make([]Todo, 0, 10)
@ -75,9 +87,12 @@ func main() {
renderTodos = filterSlice(todos, func(todo Todo) bool { return todo.Completed }) renderTodos = filterSlice(todos, func(todo Todo) bool { return todo.Completed })
} }
incomplete := countSlice(todos, func(todo Todo) bool { return !todo.Completed })
vm := ViewModel{ vm := ViewModel{
Todos: renderTodos, Todos: renderTodos,
Only: only, Only: only,
Incomplete: incomplete,
} }
err := t.Render(w, "list.html", vm) err := t.Render(w, "list.html", vm)
if err != nil { if err != nil {
@ -127,6 +142,42 @@ func main() {
w.Header().Set("Location", "/") w.Header().Set("Location", "/")
w.WriteHeader(http.StatusSeeOther) w.WriteHeader(http.StatusSeeOther)
}) })
http.HandleFunc("/destroy", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
id := r.Form.Get("id")
todos = filterSlice(todos, func(t Todo) bool { return t.Id != id })
w.Header().Set("Location", "/")
w.WriteHeader(http.StatusSeeOther)
})
http.HandleFunc("/clear", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
todos = filterSlice(todos, func(t Todo) bool { return !t.Completed })
w.Header().Set("Location", "/")
w.WriteHeader(http.StatusSeeOther)
})
log.Print("Running on 8080") log.Print("Running on 8080")
log.Fatal(http.ListenAndServe(":8080", nil)) log.Fatal(http.ListenAndServe(":8080", nil))
} }

@ -1,12 +1,13 @@
<li class="{{if .Completed}}completed{{end}}"> <li class="{{if .Completed}}completed{{end}}">
<div class="view"> <div class="view">
<form class="toggle" action="/toggle?id={{.Id}}" method="POST"> <form class="toggle" action="/toggle?id={{.Id}}" method="POST">
<button> <button></button>
t
</button>
</form> </form>
<!-- <input class="toggle" type="checkbox" {{if .Completed}}checked{{end}}> --> <!-- <input class="toggle" type="checkbox" {{if .Completed}}checked{{end}}> -->
<label>{{.Title}}</label> <label>{{.Title}}</label>
<button class="destroy"></button>
<form action="/destroy?id={{.Id}}" method="POST">
<button class="destroy"></button>
</form>
</div> </div>
</li> </li>

@ -20,7 +20,7 @@
<!-- This footer should be hidden by default and shown when there are todos --> <!-- This footer should be hidden by default and shown when there are todos -->
<footer class="footer"> <footer class="footer">
<!-- This should be `0 items left` by default --> <!-- This should be `0 items left` by default -->
<span class="todo-count"><strong>0</strong> item left</span> <span class="todo-count"><strong>{{.Incomplete}}</strong> items left</span>
<!-- Remove this if you don't implement routing --> <!-- Remove this if you don't implement routing -->
<ul class="filters"> <ul class="filters">
<li> <li>
@ -34,7 +34,9 @@
</li> </li>
</ul> </ul>
<!-- Hidden if no completed items are left ↓ --> <!-- Hidden if no completed items are left ↓ -->
<button class="clear-completed">Clear completed</button> <form action="/clear" method="POST">
<button class="clear-completed">Clear completed</button>
</form>
</footer> </footer>
</section> </section>
{{end}} {{end}}

Loading…
Cancel
Save