type TodoList struct {
live.Base
Todos []Todo
}
type Todo struct {
ID string
Title string
Completed bool
}
func (t *TodoList) Mount(ctx context.Context, params live.Params) error {
t.Todos = loadTodos()
return nil
}
func (t *TodoList) HandleEvent(ctx context.Context, event string, data map[string]any) error {
switch event {
case "add":
title := data["title"].(string)
t.Todos = append(t.Todos, Todo{
ID: generateID(),
Title: title,
})
case "toggle":
id := data["id"].(string)
for i := range t.Todos {
if t.Todos[i].ID == id {
t.Todos[i].Completed = !t.Todos[i].Completed
}
}
case "delete":
id := data["id"].(string)
t.Todos = filter(t.Todos, func(todo Todo) bool {
return todo.ID != id
})
}
return nil
}
func (t *TodoList) Render() string {
return `
<div class="todo-list">
<form live-submit="add">
<input name="title" placeholder="Add todo..." required>
<button type="submit">Add</button>
</form>
<ul>
{{range .Todos}}
<li class="{{if .Completed}}completed{{end}}">
<input type="checkbox"
{{if .Completed}}checked{{end}}
live-click="toggle"
live-value-id="{{.ID}}">
<span>{{.Title}}</span>
<button live-click="delete" live-value-id="{{.ID}}">×</button>
</li>
{{end}}
</ul>
</div>
`
}