forms almost done

This commit is contained in:
Pedro Pérez 2025-12-12 03:37:19 +01:00
parent 72741c9027
commit 5dcff81cab
5 changed files with 58 additions and 28 deletions

View File

@ -18,6 +18,7 @@ type TodoList struct {
ID int ID int
Name string Name string
Completed bool Completed bool
Error string
ui.CRUDActions ui.CRUDActions
} }
@ -89,7 +90,7 @@ func main() {
mux.HandleFunc("/todo", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/todo", func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
http.Error(w, "bad request", http.StatusBadRequest) http.Error(w, fmt.Sprintf("error loading template, err: %v", err), http.StatusInternalServerError)
return return
} }
@ -99,12 +100,12 @@ func main() {
if name == "" { if name == "" {
w.Header().Set("HX-Retarget", "#create-todo-form") w.Header().Set("HX-Retarget", "#create-todo-form")
w.Header().Set("HX-Reswap", "outerHTML") w.Header().Set("HX-Reswap", "outerHTML")
err := h.RenderW(w, "fragments/todo-row-form", hrender.H{ err := h.RenderW(w, "fragments/todo-new-form", hrender.H{
"Name": name, "Name": name,
"Error": "El nombre es obligatorio", "Error": "El nombre es obligatorio",
}) })
if err != nil { if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError) http.Error(w, fmt.Sprintf("error loading template, err: %v", err), http.StatusInternalServerError)
} }
return return
} }
@ -133,7 +134,7 @@ func main() {
"Completed": false, "Completed": false,
}) })
if err != nil { if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError) http.Error(w, fmt.Sprintf("error loading template, err: %v", err), http.StatusInternalServerError)
} }
}, "POST") }, "POST")
@ -141,7 +142,7 @@ func main() {
idStr := r.PathValue("id") idStr := r.PathValue("id")
id, err := strconv.Atoi(idStr) id, err := strconv.Atoi(idStr)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) http.Error(w, fmt.Sprintf("error loading template, err: %v", err), http.StatusInternalServerError)
return return
} }
@ -155,7 +156,7 @@ func main() {
} }
if foundItem == nil { if foundItem == nil {
http.Error(w, "item not found", http.StatusNotFound) http.Error(w, fmt.Sprintf("error loading template, err: %v", err), http.StatusInternalServerError)
return return
} }
@ -184,6 +185,20 @@ func main() {
} }
newName := r.FormValue("name") newName := r.FormValue("name")
if newName == "" {
w.Header().Set("HX-Retarget", fmt.Sprintf("#todo-edit-form-%d", id))
w.Header().Set("HX-Reswap", "outerHTML")
err := h.RenderW(w, "fragments/todo-edit-form", hrender.H{
"ID": id,
"Name": newName,
"Error": "El nombre es obligatorio",
})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
return
}
if newName == "some error" { if newName == "some error" {
log.Println("error triggered") log.Println("error triggered")
http.Error(w, "bad request", http.StatusBadRequest) http.Error(w, "bad request", http.StatusBadRequest)

View File

@ -0,0 +1,31 @@
<form
id="todo-edit-form-{{.ID}}"
class="flex w-full gap-2 items-start"
hx-put="/todo/{{.ID}}"
hx-target="closest li"
hx-swap="outerHTML"
hx-target-error="this"
x-data="{
hasError: {{ if .Error }}true{{ else }}false{{ end }}
}"
@edit-cancelled="hasError = false"
>
<div class="flex-grow form-control space-y-1.5">
<input
type="text"
name="name"
class="input input-sm input-bordered w-full"
:class="{ 'input-error': hasError }"
x-model="form.name"
x-init="$el.focus()"
@input="hasError = false"
/>
{{ if .Error }}
<p class="text-error text-xs" x-show="hasError">{{ .Error }}</p>
{{ end }}
</div>
<button type="button" class="btn btn-sm btn-ghost" @click="cancelEdit()">
Cancelar
</button>
<button type="submit" class="btn btn-sm btn-primary">Guardar</button>
</form>

View File

@ -7,7 +7,7 @@
hx-target-error="this" hx-target-error="this"
x-data="{ x-data="{
hasError: {{ if .Error }}true{{ else }}false{{ end }} hasError: {{ if .Error }}true{{ else }}false{{ end }}
}" }"
@htmx:after-request=" @htmx:after-request="
if($event.detail.successful && $event.detail.target.id === 'todo-list-body') { if($event.detail.successful && $event.detail.target.id === 'todo-list-body') {
$el.reset(); $el.reset();

View File

@ -9,6 +9,7 @@
cancelEdit() { cancelEdit() {
this.isEditing = false; this.isEditing = false;
this.form.name = '{{ .Name }}'; this.form.name = '{{ .Name }}';
this.$dispatch('edit-cancelled');
} }
}" }"
> >
@ -49,24 +50,7 @@
<div <div
class="card-body p-4 flex-row items-center justify-between gap-4" class="card-body p-4 flex-row items-center justify-between gap-4"
x-show="isEditing" x-show="isEditing"
style="display: none"
> >
<form {{ template "fragments/todo-edit-form" . }}
class="flex w-full gap-2"
hx-put="/todo/{{.ID}}"
hx-target="closest li"
hx-swap="outerHTML"
>
<input
type="text"
name="name"
class="input input-sm input-bordered flex-grow"
x-model="form.name"
/>
<button type="button" class="btn btn-sm btn-ghost" @click="cancelEdit()">
Cancelar
</button>
<button type="submit" class="btn btn-sm btn-primary">Guardar</button>
</form>
</div> </div>
</li> </li>

View File

@ -13,8 +13,8 @@
</button> </button>
</div> </div>
<div x-show="creating" class="w-full pb-4"> <div x-show="creating" class="w-full pb-2">
{{ template "fragments/todo-row-form" .}} {{ template "fragments/todo-new-form" .}}
</div> </div>
<ol id="todo-list-body" class="space-y-3"> <ol id="todo-list-body" class="space-y-3">