diff --git a/internal/server/routes.go b/internal/server/routes.go
index f505ac6..0d19465 100644
--- a/internal/server/routes.go
+++ b/internal/server/routes.go
@@ -5,6 +5,7 @@ import (
"github.com/gofs-cli/template/internal/server/assets"
"github.com/gofs-cli/template/internal/server/handlers"
+ activesearch "github.com/gofs-cli/template/internal/ui/pages/active-search"
bulkupdate "github.com/gofs-cli/template/internal/ui/pages/bulk-update"
clicktoedit "github.com/gofs-cli/template/internal/ui/pages/click-to-edit"
clicktoload "github.com/gofs-cli/template/internal/ui/pages/click-to-load"
@@ -51,6 +52,10 @@ func (s *Server) Routes() {
routesMux.Handle("POST /inline-validation", inlinevalidation.Submit())
routesMux.Handle("POST /inline-validation/email", inlinevalidation.Validate())
+ // active search example
+ routesMux.Handle("GET /active-search", activesearch.Index())
+ routesMux.Handle("POST /active-search/search", activesearch.Search())
+
routesMux.Handle("GET /modal", home.Modal())
routesMux.Handle("GET /page1", page1.Index())
diff --git a/internal/ui/pages/active-search/handlers.go b/internal/ui/pages/active-search/handlers.go
new file mode 100644
index 0000000..4f83f59
--- /dev/null
+++ b/internal/ui/pages/active-search/handlers.go
@@ -0,0 +1,61 @@
+package activesearch
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/a-h/templ"
+ "github.com/gofs-cli/template/internal/ui"
+ "github.com/gofs-cli/template/internal/ui/components/header"
+)
+
+func Index() http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ templ.Handler(ui.IndexPage(layout(header.Header(), body()))).ServeHTTP(w, r)
+ })
+}
+
+var rows = []Row{
+ {
+ FirstName: "Rick",
+ LastName: "Grimes",
+ Email: "rick.grimes@email.com",
+ },
+ {
+ FirstName: "Thomas",
+ LastName: "Shelby",
+ Email: "thomas.shelby@email.com",
+ },
+ {
+ FirstName: "Harvey",
+ LastName: "Specter",
+ Email: "harvey.specter@email.com",
+ },
+ {
+ FirstName: "Rick",
+ LastName: "Astley",
+ Email: "rick.astley@email.com",
+ },
+ {
+ FirstName: "Thomas",
+ LastName: "cook",
+ Email: "thomas.cook@email.com",
+ },
+}
+
+func Search() http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ searchQuery := strings.ToLower(r.PostFormValue("search"))
+ filteredRows := []Row{}
+ for _, v := range rows {
+ if contains(v.FirstName, searchQuery) || contains(v.LastName, searchQuery) || contains(v.Email, searchQuery) {
+ filteredRows = append(filteredRows, v)
+ }
+ }
+ templ.Handler(searchResults(filteredRows)).ServeHTTP(w, r)
+ })
+}
+
+func contains(str, substr string) bool {
+ return strings.Contains(strings.ToLower(str), substr)
+}
diff --git a/internal/ui/pages/active-search/index.templ b/internal/ui/pages/active-search/index.templ
new file mode 100644
index 0000000..e2fff48
--- /dev/null
+++ b/internal/ui/pages/active-search/index.templ
@@ -0,0 +1,61 @@
+package activesearch
+
+type Row struct {
+ FirstName string
+ LastName string
+ Email string
+}
+
+css classLayout() {
+ display: grid;
+}
+
+templ layout(header, body templ.Component) {
+
+
+ @header
+
+
+ @body
+
+
+}
+
+templ body() {
+
Active Search:
+
+ Search Contacts
+
+
Searching...
+
+
+
+
+
+
+ | First Name |
+ Last Name |
+ Email |
+
+
+
+
+}
+
+templ searchResults(rows []Row) {
+ for _, v := range rows {
+
+ | { v.FirstName } |
+ { v.LastName } |
+ { v.Email } |
+
+ }
+}
diff --git a/internal/ui/pages/active-search/index_templ.go b/internal/ui/pages/active-search/index_templ.go
new file mode 100644
index 0000000..b1f5dcb
--- /dev/null
+++ b/internal/ui/pages/active-search/index_templ.go
@@ -0,0 +1,189 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.819
+package activesearch
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+type Row struct {
+ FirstName string
+ LastName string
+ Email string
+}
+
+func classLayout() templ.CSSClass {
+ templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
+ templ_7745c5c3_CSSBuilder.WriteString(`display:grid;`)
+ templ_7745c5c3_CSSID := templ.CSSID(`classLayout`, templ_7745c5c3_CSSBuilder.String())
+ return templ.ComponentCSSClass{
+ ID: templ_7745c5c3_CSSID,
+ Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
+ }
+}
+
+func layout(header, body templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ var templ_7745c5c3_Var2 = []any{classLayout()}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = header.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = body.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func body() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var4 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var4 == nil {
+ templ_7745c5c3_Var4 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Active Search:
Search Contacts
Searching...
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func searchResults(rows []Row) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var5 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var5 == nil {
+ templ_7745c5c3_Var5 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ for _, v := range rows {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "| ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var6 string
+ templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(v.FirstName)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/pages/active-search/index.templ`, Line: 56, Col: 20}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " | ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var7 string
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(v.LastName)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/pages/active-search/index.templ`, Line: 57, Col: 19}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " | ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var8 string
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(v.Email)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/pages/active-search/index.templ`, Line: 58, Col: 16}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " |
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate