add datastar examples
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/starfederation/datastar-go/datastar"
|
||||
"github.com/zepyrshut/hrender"
|
||||
)
|
||||
|
||||
type TodoList struct {
|
||||
ID int
|
||||
Name string
|
||||
Completed bool
|
||||
}
|
||||
|
||||
var todoList = []TodoList{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "Sacar a la perra",
|
||||
Completed: false,
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "Limpiar la casa",
|
||||
Completed: false,
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "Ir al supermercado",
|
||||
Completed: false,
|
||||
},
|
||||
}
|
||||
|
||||
type TodoSignals struct {
|
||||
NewTodoName string `json:"newtodo"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
templatesFS := os.DirFS("./templates")
|
||||
|
||||
h := hrender.NewHTMLRender(templatesFS, false)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("GET /", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
|
||||
err := h.RenderW(w, "pages/index", hrender.H{})
|
||||
if err != nil {
|
||||
http.Error(w, "error loading template", http.StatusInternalServerError)
|
||||
}
|
||||
}))
|
||||
|
||||
mux.Handle("GET /todo", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
sort.Slice(todoList, func(i, j int) bool {
|
||||
return todoList[i].ID > todoList[j].ID
|
||||
})
|
||||
|
||||
templ, err := h.RenderS("fragments/todo-widget", hrender.H{
|
||||
"TodoList": todoList,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "error loading template", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
sse := datastar.NewSSE(w, r)
|
||||
if err := sse.PatchElements(templ); err != nil {
|
||||
log.Println("error", err)
|
||||
}
|
||||
}))
|
||||
|
||||
mux.Handle("GET /todo/new", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
templ, err := h.RenderS("fragments/todo-row-edit", hrender.H{})
|
||||
if err != nil {
|
||||
http.Error(w, "error loading template", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
sse := datastar.NewSSE(w, r)
|
||||
if err := sse.PatchElements(templ,
|
||||
datastar.WithModePrepend(),
|
||||
datastar.WithSelectorID("todo-list-body"),
|
||||
); err != nil {
|
||||
log.Println("error", err)
|
||||
}
|
||||
}))
|
||||
|
||||
mux.Handle("POST /todo", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var signals TodoSignals
|
||||
if err := datastar.ReadSignals(r, &signals); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
newID := 0
|
||||
sort.Slice(todoList, func(i, j int) bool {
|
||||
return todoList[i].ID > todoList[j].ID
|
||||
})
|
||||
newID = todoList[0].ID + 1
|
||||
|
||||
newItem := TodoList{
|
||||
ID: newID,
|
||||
Name: signals.NewTodoName,
|
||||
Completed: false,
|
||||
}
|
||||
|
||||
todoList = append(todoList, newItem)
|
||||
|
||||
templ, _ := h.RenderS("fragments/todo-row", hrender.H{
|
||||
"ID": newID,
|
||||
"Name": newItem.Name,
|
||||
"Completed": false,
|
||||
})
|
||||
|
||||
sse := datastar.NewSSE(w, r)
|
||||
|
||||
if err := sse.PatchElements(templ,
|
||||
datastar.WithModeReplace(),
|
||||
datastar.WithSelectorID("new-todo-row"),
|
||||
); err != nil {
|
||||
http.Error(w, "bad request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
signals.NewTodoName = ""
|
||||
sse.MarshalAndPatchSignals(signals)
|
||||
}))
|
||||
|
||||
mux.Handle("PATCH /todo/{id}/completed", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("patch todo triggered")
|
||||
|
||||
idStr := r.PathValue("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var foundItem *TodoList
|
||||
for i := range todoList {
|
||||
if todoList[i].ID == id {
|
||||
todoList[i].Completed = true
|
||||
foundItem = &todoList[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if foundItem == nil {
|
||||
http.Error(w, "item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
templ, err := h.RenderS("fragments/todo-row", hrender.H{
|
||||
"ID": foundItem.ID,
|
||||
"Name": foundItem.Name,
|
||||
"Completed": true,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, "error loading template", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
sse := datastar.NewSSE(w, r)
|
||||
if err := sse.PatchElements(templ, datastar.WithModeOuter(),
|
||||
datastar.WithSelectorID(fmt.Sprintf("todo-%d", id)),
|
||||
); err != nil {
|
||||
http.Error(w, "error", http.StatusInternalServerError)
|
||||
}
|
||||
}))
|
||||
|
||||
log.Println("server started on port 8080")
|
||||
err := http.ListenAndServe(":8080", mux)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("server cannot start %v", err))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user