diff --git a/clicktoload/handlers.go b/clicktoload/handlers.go new file mode 100644 index 0000000..e4aa09d --- /dev/null +++ b/clicktoload/handlers.go @@ -0,0 +1,41 @@ +package clicktoload + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "github.com/rs/xid" +) + +type user struct { + name, email, id string +} + +func Handlers(prefix string, mux *http.ServeMux) { + mux.HandleFunc(prefix+"/", index) + mux.HandleFunc(prefix+"/contacts/", getPage) +} + +func index(w http.ResponseWriter, r *http.Request) { + // Load users + Index(getUsers(1)).Render(r.Context(), w) +} + +func getPage(w http.ResponseWriter, r *http.Request) { + page, _ := strconv.Atoi(r.URL.Query().Get("page")) + tbody(getUsers(page), page).Render(r.Context(), w) +} + +func getUsers(page int) []user { + var users []user + for i := 0; i < 10; i++ { + users = append(users, user{ + "Agent Smith", + fmt.Sprintf("void%d@null.org", (page*10)+i), + xid.NewWithTime(time.Now()).String(), + }) + } + return users +} diff --git a/clicktoload/templates.templ b/clicktoload/templates.templ new file mode 100644 index 0000000..fcccfc7 --- /dev/null +++ b/clicktoload/templates.templ @@ -0,0 +1,52 @@ +package clicktoload + +import ( + "fmt" + + "examples/shared" +) + +templ demo(users []user, page int) { + + + + + + + + @tbody(users, page) +
NameEmailID
+} + +templ tbody(users []user, page int) { + for _, u := range users { + + { u.name } + { u.email } + { u.id } + + } + @replaceMe(page) +} + +templ replaceMe(page int) { + + + +} + +templ Index(users []user) { + @shared.Layout("Click to Load") { +

Click to Load

+

This example shows how to implement click-to-load the next page in a table of data. The crux of the demo is the final row:

+

+	@shared.Raw() {
+		@replaceMe(1)
+	}
+
+

This row contains a button that will replace the entire row with the next page of results (which will contain a button to load the next page of results). And so on.

+

Demo

+ @demo(users, 1) + } +} + diff --git a/clicktoload/templates_templ.go b/clicktoload/templates_templ.go new file mode 100644 index 0000000..0cc17a0 --- /dev/null +++ b/clicktoload/templates_templ.go @@ -0,0 +1,511 @@ +// Code generated by templ@(devel) DO NOT EDIT. + +package clicktoload + +//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, page int) 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("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Text + var_2 := `Name` + _, err = templBuffer.WriteString(var_2) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Text + var_3 := `Email` + _, err = templBuffer.WriteString(var_3) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Text + var_4 := `ID` + _, err = templBuffer.WriteString(var_4) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + 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("") + if err != nil { + return err + } + // TemplElement + err = tbody(users, page).Render(ctx, templBuffer) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + if !templIsBuffer { + _, err = io.Copy(w, templBuffer) + } + return err + }) +} + +func tbody(users []user, page int) 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_5 := templ.GetChildren(ctx) + if var_5 == nil { + var_5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + // For + for _, u := range users { + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // StringExpression + var var_6 string = u.name + _, err = templBuffer.WriteString(templ.EscapeString(var_6)) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // StringExpression + var var_7 string = u.email + _, err = templBuffer.WriteString(templ.EscapeString(var_7)) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // StringExpression + var var_8 string = u.id + _, err = templBuffer.WriteString(templ.EscapeString(var_8)) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + } + // TemplElement + err = replaceMe(page).Render(ctx, templBuffer) + if err != nil { + return err + } + if !templIsBuffer { + _, err = io.Copy(w, templBuffer) + } + return err + }) +} + +func replaceMe(page int) 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_9 := templ.GetChildren(ctx) + if var_9 == nil { + var_9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Text + var_10 := `Load More Agents...` + _, err = templBuffer.WriteString(var_10) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + 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("") + if err != nil { + return err + } + // Text + var_13 := `Click to Load` + _, err = templBuffer.WriteString(var_13) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Whitespace (normalised) + _, err = templBuffer.WriteString(` `) + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("

") + if err != nil { + return err + } + // Text + var_14 := `This example shows how to implement click-to-load the next page in a table of data. The crux of the demo is the final row:` + _, err = templBuffer.WriteString(var_14) + if err != nil { + return err + } + _, err = templBuffer.WriteString("

") + if err != nil { + return err + } + // Whitespace (normalised) + _, err = templBuffer.WriteString(` `) + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("
")
+			if err != nil {
+				return err
+			}
+			// Element (standard)
+			_, err = templBuffer.WriteString("")
+			if err != nil {
+				return err
+			}
+			// TemplElement
+			var_15 := 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)
+				}
+				// TemplElement
+				err = replaceMe(1).Render(ctx, templBuffer)
+				if err != nil {
+					return err
+				}
+				if !templIsBuffer {
+					_, err = io.Copy(w, templBuffer)
+				}
+				return err
+			})
+			err = shared.Raw().Render(templ.WithChildren(ctx, var_15), templBuffer)
+			if err != nil {
+				return err
+			}
+			_, err = templBuffer.WriteString("")
+			if err != nil {
+				return err
+			}
+			_, err = templBuffer.WriteString("
") + if err != nil { + return err + } + // Whitespace (normalised) + _, err = templBuffer.WriteString(` `) + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("

") + if err != nil { + return err + } + // Text + var_16 := `This row contains a button that will replace the entire row with the next page of results (which will contain a button to load the next page of results). And so on.` + _, err = templBuffer.WriteString(var_16) + if err != nil { + return err + } + _, err = templBuffer.WriteString("

") + if err != nil { + return err + } + // Whitespace (normalised) + _, err = templBuffer.WriteString(` `) + if err != nil { + return err + } + // Element (standard) + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Text + var_17 := `Demo` + _, err = templBuffer.WriteString(var_17) + if err != nil { + return err + } + _, err = templBuffer.WriteString("") + if err != nil { + return err + } + // Whitespace (normalised) + _, err = templBuffer.WriteString(` `) + if err != nil { + return err + } + // TemplElement + err = demo(users, 1).Render(ctx, templBuffer) + if err != nil { + return err + } + if !templIsBuffer { + _, err = io.Copy(w, templBuffer) + } + return err + }) + err = shared.Layout("Click to Load").Render(templ.WithChildren(ctx, var_12), templBuffer) + if err != nil { + return err + } + if !templIsBuffer { + _, err = io.Copy(w, templBuffer) + } + return err + }) +} + diff --git a/go.mod b/go.mod index 8e2c193..851cafb 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,10 @@ module examples go 1.21 -require github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5 - require ( - github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 // indirect - golang.org/x/net v0.9.0 // indirect + github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5 + github.com/rs/xid v1.5.0 + github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 ) + +require golang.org/x/net v0.9.0 // indirect diff --git a/go.sum b/go.sum index 482aab9..cad4968 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/a-h/templ v0.2.233 h1:EnZqZmtV0YICqWG6MtLNmTcWuFkl2ImyQ63SIpWaM2Y= github.com/a-h/templ v0.2.233/go.mod h1:h1DdzFMWVApvTcZBNmM6+mD6EPq6uYkncMNF7zdLj9I= github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5 h1:NeF/iw7KU9W7CYYJimd5x7ooOXCLrfo8FcHdFPUU+2w= github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5/go.mod h1:nqma2qb9ViAJOP4MBucyH+SPbOyNDZaRQyusfpK4PjY= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts= github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= diff --git a/main.go b/main.go index aaccedc..c51da31 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "examples/bulkupdate" "examples/clicktoedit" + "examples/clicktoload" "log" "net/http" @@ -44,4 +45,10 @@ var examples = []Example{ Slug: "bulk-update", Handlers: bulkupdate.Handlers, }, + { + Name: "Click to Load", + Desc: "Demonstrates clicking to load more rows in a table", + Slug: "click-to-load", + Handlers: clicktoload.Handlers, + }, }