Form
A simple form submission example with validation on blur
package snippets
import (
"github.com/franchb/htmgo/framework/v2/h"
"github.com/franchb/htmgo/framework/v2/hx"
)
func FormWithBlurValidation(ctx *h.RequestContext) *h.Partial {
buttonClasses := "rounded items-center px-3 py-2 bg-slate-800 text-white w-full text-center"
validationPath := h.GetPartialPath(
Validate,
)
return h.NewPartial(
h.Form(
h.Id("my-form"),
// hx-swap: none is required so the traditional swap doesn't happen, only oob swap
h.NoSwap(),
h.PostPartial(SubmitFormExample),
h.Class("flex flex-col gap-2 max-w-[300px] mx-auto"),
h.LabelFor("name", "Your Name"),
h.Input(
"text",
h.Required(),
h.Class("p-4 rounded-md border border-slate-200"),
h.Name("name"),
h.Placeholder("Name"),
h.Post(validationPath, hx.BlurEvent),
),
h.Pf(
"type 'htmgo' to see validation errors",
h.Class("text-slate-600 text-sm"),
),
h.Div(
h.Id("name-error"),
h.Class("text-red-500"),
),
h.LabelFor("occupation", "Occupation"),
h.Input(
"text",
h.Required(),
h.Class("p-4 rounded-md border border-slate-200"),
h.Name("occupation"),
h.Placeholder("Software Developer"),
),
h.Button(
h.Type("submit"),
h.Class(buttonClasses),
h.Text("Submit"),
),
),
)
}
func Validate(ctx *h.RequestContext) *h.Partial {
name := ctx.FormValue("name")
if name == "htmgo" {
ctx.Fiber.Status(400)
return h.SwapPartial(
ctx,
h.Div(
h.Id("name-error"),
h.Text("Name is already taken"),
h.Class("p-4 bg-rose-400 text-white rounded-md"),
),
)
}
return h.EmptyPartial()
}
func SubmitFormExample(ctx *h.RequestContext) *h.Partial {
if !ctx.IsHttpPost() {
return h.EmptyPartial()
}
validate := Validate(ctx)
// if there is a validation error, swap it in
if !h.IsEmptyPartial(validate) {
return validate
}
// submit the form
return h.SwapPartial(
ctx,
h.Div(
h.Id("my-form"),
h.Text("Form submitted with name: "+ctx.FormValue("name")),
),
)
}
Copy
1package snippets
2
3import (
4 "github.com/franchb/htmgo/framework/v2/h"
5 "github.com/franchb/htmgo/framework/v2/hx"
6)
7
8func FormWithBlurValidation(ctx *h.RequestContext) *h.Partial {
9 buttonClasses := "rounded items-center px-3 py-2 bg-slate-800 text-white w-full text-center"
10 validationPath := h.GetPartialPath(
11 Validate,
12 )
13 return h.NewPartial(
14 h.Form(
15 h.Id("my-form"),
16 // hx-swap: none is required so the traditional swap doesn't happen, only oob swap
17 h.NoSwap(),
18 h.PostPartial(SubmitFormExample),
19 h.Class("flex flex-col gap-2 max-w-[300px] mx-auto"),
20 h.LabelFor("name", "Your Name"),
21 h.Input(
22 "text",
23 h.Required(),
24 h.Class("p-4 rounded-md border border-slate-200"),
25 h.Name("name"),
26 h.Placeholder("Name"),
27 h.Post(validationPath, hx.BlurEvent),
28 ),
29 h.Pf(
30 "type 'htmgo' to see validation errors",
31 h.Class("text-slate-600 text-sm"),
32 ),
33 h.Div(
34 h.Id("name-error"),
35 h.Class("text-red-500"),
36 ),
37 h.LabelFor("occupation", "Occupation"),
38 h.Input(
39 "text",
40 h.Required(),
41 h.Class("p-4 rounded-md border border-slate-200"),
42 h.Name("occupation"),
43 h.Placeholder("Software Developer"),
44 ),
45 h.Button(
46 h.Type("submit"),
47 h.Class(buttonClasses),
48 h.Text("Submit"),
49 ),
50 ),
51 )
52}
53
54func Validate(ctx *h.RequestContext) *h.Partial {
55 name := ctx.FormValue("name")
56
57 if name == "htmgo" {
58 ctx.Fiber.Status(400)
59 return h.SwapPartial(
60 ctx,
61 h.Div(
62 h.Id("name-error"),
63 h.Text("Name is already taken"),
64 h.Class("p-4 bg-rose-400 text-white rounded-md"),
65 ),
66 )
67 }
68
69 return h.EmptyPartial()
70}
71
72func SubmitFormExample(ctx *h.RequestContext) *h.Partial {
73
74 if !ctx.IsHttpPost() {
75 return h.EmptyPartial()
76 }
77
78 validate := Validate(ctx)
79
80 // if there is a validation error, swap it in
81 if !h.IsEmptyPartial(validate) {
82 return validate
83 }
84
85 // submit the form
86 return h.SwapPartial(
87 ctx,
88 h.Div(
89 h.Id("my-form"),
90 h.Text("Form submitted with name: "+ctx.FormValue("name")),
91 ),
92 )
93}