From f6556b579ffd54c22328b4851fbb78dd0f2b6ade Mon Sep 17 00:00:00 2001 From: maddalax Date: Thu, 31 Oct 2024 09:44:16 -0500 Subject: [PATCH] css form on blur validation --- framework/h/base.go | 6 +- htmgo-site/pages/examples/examples.go | 10 +++ .../examples/form-with-blur-validation.go | 10 +++ htmgo-site/pages/examples/form.go | 2 +- .../snippets/form-with-blur-validation.go | 90 +++++++++++++++++++ 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 htmgo-site/pages/examples/form-with-blur-validation.go create mode 100644 htmgo-site/partials/snippets/form-with-blur-validation.go diff --git a/framework/h/base.go b/framework/h/base.go index a26aa9e..f711dd9 100644 --- a/framework/h/base.go +++ b/framework/h/base.go @@ -71,8 +71,12 @@ func SwapPartial(ctx *RequestContext, swap *Element) *Partial { SwapMany(ctx, swap)) } +func IsEmptyPartial(partial *Partial) bool { + return partial.Root.tag == "" && len(partial.Root.children) == 0 +} + func EmptyPartial() *Partial { - return NewPartial(Fragment()) + return NewPartial(Empty()) } func SwapManyPartial(ctx *RequestContext, swaps ...*Element) *Partial { diff --git a/htmgo-site/pages/examples/examples.go b/htmgo-site/pages/examples/examples.go index 1f14d24..2e7aabc 100644 --- a/htmgo-site/pages/examples/examples.go +++ b/htmgo-site/pages/examples/examples.go @@ -11,6 +11,15 @@ var FormWithLoadingStateSnippet = Snippet{ partial: snippets.FormExample, } +var FormWithBlurValidationSnippet = Snippet{ + category: "Forms", + name: "Form", + description: "A simple form submission example with validation on blur", + sidebarName: "Form With Blur Validation", + path: "/examples/form-with-blur-validation", + partial: snippets.FormWithBlurValidation, +} + var UserAuthSnippet = Snippet{ category: "Projects", name: "User Authentication", @@ -90,6 +99,7 @@ var JsHideChildrenOnClick = Snippet{ var examples = []Snippet{ FormWithLoadingStateSnippet, + FormWithBlurValidationSnippet, ClickToEditSnippet, JsSetTextOnClick, diff --git a/htmgo-site/pages/examples/form-with-blur-validation.go b/htmgo-site/pages/examples/form-with-blur-validation.go new file mode 100644 index 0000000..8e1f579 --- /dev/null +++ b/htmgo-site/pages/examples/form-with-blur-validation.go @@ -0,0 +1,10 @@ +package examples + +import ( + "github.com/maddalax/htmgo/framework/h" +) + +func FormWithBlurValidation(ctx *h.RequestContext) *h.Page { + SetSnippet(ctx, &FormWithBlurValidationSnippet) + return Index(ctx) +} diff --git a/htmgo-site/pages/examples/form.go b/htmgo-site/pages/examples/form.go index 9ead363..63dcc1f 100644 --- a/htmgo-site/pages/examples/form.go +++ b/htmgo-site/pages/examples/form.go @@ -4,7 +4,7 @@ import ( "github.com/maddalax/htmgo/framework/h" ) -func FormExample(ctx *h.RequestContext) *h.Page { +func FormWithLoadingState(ctx *h.RequestContext) *h.Page { SetSnippet(ctx, &FormWithLoadingStateSnippet) return Index(ctx) } diff --git a/htmgo-site/partials/snippets/form-with-blur-validation.go b/htmgo-site/partials/snippets/form-with-blur-validation.go new file mode 100644 index 0000000..7779ce4 --- /dev/null +++ b/htmgo-site/partials/snippets/form-with-blur-validation.go @@ -0,0 +1,90 @@ +package snippets + +import ( + "github.com/maddalax/htmgo/framework/h" + "github.com/maddalax/htmgo/framework/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.TriggerChildren(), + 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.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.Response.WriteHeader(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")), + ), + ) +}