mirror of
https://github.com/joerdav/go-htmx-examples.git
synced 2026-03-22 06:35:57 +00:00
feat: clicktoedit
This commit is contained in:
62
editrow/handlers.go
Normal file
62
editrow/handlers.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package editrow
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type user struct {
|
||||
name, email string
|
||||
}
|
||||
|
||||
var users = []user{
|
||||
{"Joe Smith", "joe@smith.org"},
|
||||
{"Angie MacDowell", "angie@macdowell.org"},
|
||||
{"Fuqua Tarkenton", "fuqua@tarkenton.org"},
|
||||
{"Kim Yee", "kim@yee.org"},
|
||||
}
|
||||
|
||||
func Handlers(prefix string, mux *http.ServeMux) {
|
||||
mux.HandleFunc(prefix+"/", index)
|
||||
mux.HandleFunc(prefix+"/edit/", editUser)
|
||||
mux.HandleFunc(prefix+"/contact/", contacts)
|
||||
}
|
||||
|
||||
func index(w http.ResponseWriter, r *http.Request) {
|
||||
// Load users
|
||||
Index(users).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func editUser(w http.ResponseWriter, r *http.Request) {
|
||||
segments := strings.Split(r.URL.Path, "/")
|
||||
userID, _ := strconv.Atoi(segments[len(segments)-1])
|
||||
form(userID, users[userID]).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func contacts(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
getRow(w, r)
|
||||
return
|
||||
}
|
||||
if r.Method == http.MethodPut {
|
||||
putUser(w, r)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
|
||||
func getRow(w http.ResponseWriter, r *http.Request) {
|
||||
segments := strings.Split(r.URL.Path, "/")
|
||||
userID, _ := strconv.Atoi(segments[len(segments)-1])
|
||||
row(userID, users[userID]).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func putUser(w http.ResponseWriter, r *http.Request) {
|
||||
segments := strings.Split(r.URL.Path, "/")
|
||||
userID, _ := strconv.Atoi(segments[len(segments)-1])
|
||||
r.ParseForm()
|
||||
name, email := r.FormValue("name"), r.FormValue("email")
|
||||
users[userID] = user{name, email}
|
||||
row(userID, users[userID]).Render(r.Context(), w)
|
||||
}
|
||||
45
editrow/templates.templ
Normal file
45
editrow/templates.templ
Normal file
@@ -0,0 +1,45 @@
|
||||
package editrow
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"examples/shared"
|
||||
)
|
||||
|
||||
templ demo(users []user) {
|
||||
<table class="table"><thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead><tbody hx-target="closest tr" hx-swap="outerHTML">
|
||||
for i, u := range users {
|
||||
@row(i, u)
|
||||
}
|
||||
</tbody></table>
|
||||
}
|
||||
|
||||
templ row(id int, u user) {
|
||||
<tr>
|
||||
<td>{ u.name }</td>
|
||||
<td>{ u.email }</td>
|
||||
<td><button class="button" hx-get={ fmt.Sprintf("/edit-row/edit/%d", id) }>Edit</button></td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
templ form(id int, u user) {
|
||||
<tr hx-trigger="cancel" class="editing" hx-get={ fmt.Sprintf("/edit-row/contact/%d", id) }>
|
||||
<td><input name="name" value={ u.name }/></td>
|
||||
<td><input name="email" value={ u.email }/></td>
|
||||
<td><button class="button" hx-get={ fmt.Sprintf("/edit-row/contact/%d", id) }>Cancel</button><button class="button is-black" hx-put={ fmt.Sprintf("/edit-row/contact/%d", id) } hx-include="closest tr">Save</button></td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
templ Index(users []user) {
|
||||
@shared.Layout("Delete Row") {
|
||||
<h2 class="title">Edit Row</h2>
|
||||
@demo(users)
|
||||
}
|
||||
}
|
||||
|
||||
550
editrow/templates_templ.go
Normal file
550
editrow/templates_templ.go
Normal file
@@ -0,0 +1,550 @@
|
||||
// Code generated by templ@(devel) DO NOT EDIT.
|
||||
|
||||
package editrow
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
// GoExpression
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"examples/shared"
|
||||
)
|
||||
|
||||
func demo(users []user) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_1 := templ.GetChildren(ctx)
|
||||
if var_1 == nil {
|
||||
var_1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<table")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" class=\"table\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<thead>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<tr>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_2 := `Name`
|
||||
_, err = templBuffer.WriteString(var_2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_3 := `Email`
|
||||
_, err = templBuffer.WriteString(var_3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</th>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</tr>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</thead>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<tbody")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" hx-target=\"closest tr\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-swap=\"outerHTML\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// For
|
||||
for i, u := range users {
|
||||
// TemplElement
|
||||
err = row(i, u).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = templBuffer.WriteString("</tbody>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</table>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func row(id int, u user) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_4 := templ.GetChildren(ctx)
|
||||
if var_4 == nil {
|
||||
var_4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<tr>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// StringExpression
|
||||
var var_5 string = u.name
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_5))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// StringExpression
|
||||
var var_6 string = u.email
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_6))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<button")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" class=\"button\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-get=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(fmt.Sprintf("/edit-row/edit/%d", id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_7 := `Edit`
|
||||
_, err = templBuffer.WriteString(var_7)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</button>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</tr>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func form(id int, u user) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_8 := templ.GetChildren(ctx)
|
||||
if var_8 == nil {
|
||||
var_8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<tr")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" hx-trigger=\"cancel\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" class=\"editing\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-get=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(fmt.Sprintf("/edit-row/contact/%d", id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (void)
|
||||
_, err = templBuffer.WriteString("<input")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" name=\"name\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" value=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(u.name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (void)
|
||||
_, err = templBuffer.WriteString("<input")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" name=\"email\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" value=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(u.email))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<button")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" class=\"button\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-get=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(fmt.Sprintf("/edit-row/contact/%d", id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_9 := `Cancel`
|
||||
_, err = templBuffer.WriteString(var_9)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</button>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<button")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" class=\"button is-black\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-put=")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(fmt.Sprintf("/edit-row/contact/%d", id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" hx-include=\"closest tr\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_10 := `Save`
|
||||
_, err = templBuffer.WriteString(var_10)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</button>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</td>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</tr>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func Index(users []user) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_11 := templ.GetChildren(ctx)
|
||||
if var_11 == nil {
|
||||
var_11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
// TemplElement
|
||||
var_12 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
// Element (standard)
|
||||
_, err = templBuffer.WriteString("<h2")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Element Attributes
|
||||
_, err = templBuffer.WriteString(" class=\"title\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Text
|
||||
var_13 := `Edit Row`
|
||||
_, err = templBuffer.WriteString(var_13)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</h2>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Whitespace (normalised)
|
||||
_, err = templBuffer.WriteString(` `)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TemplElement
|
||||
err = demo(users).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
err = shared.Layout("Delete Row").Render(templ.WithChildren(ctx, var_12), templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user