Form

A simple form submission example with a loading state

Source Code

Copy
 1package snippets
 2
 3import (
 4	"github.com/franchb/htmgo/framework/v2/h"
 5	"github.com/franchb/htmgo/framework/v2/hx"
 6	"github.com/franchb/htmgo/framework/v2/js"
 7	"time"
 8)
 9
10func FormExample(ctx *h.RequestContext) *h.Partial {
11	return h.NewPartial(
12		h.Form(
13			h.PostPartial(SubmitForm),
14			h.Class("flex flex-col gap-2 max-w-[300px] mx-auto"),
15			h.LabelFor("name", "Your Name"),
16			h.Input(
17				"text",
18				h.Required(),
19				h.Class("p-4 rounded-md border border-slate-200"),
20				h.Name("name"),
21				h.Placeholder("Name"),
22				h.OnEvent(
23					hx.KeyDownEvent,
24					js.SubmitFormOnEnter(),
25				),
26			),
27			SubmitButton(),
28		),
29	)
30}
31
32func SubmitButton() *h.Element {
33	buttonClasses := "rounded items-center px-3 py-2 bg-slate-800 text-white w-full text-center"
34	return h.Div(
35		h.HxBeforeRequest(
36			js.RemoveClassOnChildren(".loading", "hidden"),
37			js.SetClassOnChildren(".submit", "hidden"),
38		),
39		h.HxAfterRequest(
40			js.SetClassOnChildren(".loading", "hidden"),
41			js.RemoveClassOnChildren(".submit", "hidden"),
42		),
43		h.Class("flex gap-2 justify-center"),
44		h.Button(
45			h.Class("loading hidden relative text-center", buttonClasses),
46			Spinner(),
47			h.Disabled(),
48			h.Text("Submitting..."),
49		),
50		h.Button(
51			h.Type("submit"),
52			h.Class("submit", buttonClasses),
53			h.Text("Submit"),
54		),
55	)
56}
57
58func Spinner(children ...h.Ren) *h.Element {
59	return h.Div(
60		h.Children(children...),
61		h.Class("absolute left-1 spinner spinner-border animate-spin "+
62			"inline-block w-6 h-6 border-4 rounded-full border-slate-200 border-t-transparent"),
63		h.Attribute("role", "status"),
64	)
65}
66
67func SubmitForm(ctx *h.RequestContext) *h.Partial {
68	name := ctx.FormValue("name")
69	time.Sleep(time.Second * 2)
70	return h.NewPartial(
71		h.Div(
72			h.TextF("Form submitted with name: %s", name),
73		),
74	)
75}