Input

An example of how you could build a re-usable input component

This should be your full legal name

Source Code

Copy
  1package snippets
  2
  3import (
  4	"github.com/maddalax/htmgo/framework/h"
  5	"github.com/maddalax/htmgo/framework/hx"
  6)
  7
  8// InputComponent wrapper to make the code snippet work, main code is the Input function
  9func InputComponent(ctx *h.RequestContext) *h.Partial {
 10
 11	return h.NewPartial(
 12		h.Div(
 13			h.Class("max-w-sm mx-auto flex flex-col gap-4"),
 14			Input(
 15				InputProps{
 16					Id:          "my-input",
 17					Name:        "my-input",
 18					Label:       "Input with label",
 19					Type:        "text",
 20					Placeholder: "Type something",
 21					Required:    true,
 22				},
 23				h.Attribute("autocomplete", "off"),
 24				h.MaxLength(50),
 25			),
 26			Input(
 27				InputProps{
 28					Id:           "my-input",
 29					Name:         "my-input",
 30					Label:        "Input with default value",
 31					Type:         "text",
 32					DefaultValue: "Default value",
 33				},
 34			),
 35			Input(
 36				InputProps{
 37					Id:          "my-input",
 38					Name:        "my-input",
 39					Label:       "Input with helper text",
 40					Type:        "text",
 41					Placeholder: "Full name",
 42					HelperText:  "This should be your full legal name",
 43				},
 44			),
 45		),
 46	)
 47}
 48
 49type InputProps struct {
 50	Id             string
 51	Label          string
 52	Name           string
 53	Type           string
 54	DefaultValue   string
 55	Placeholder    string
 56	Required       bool
 57	ValidationPath string
 58	HelperText     string
 59}
 60
 61func Input(props InputProps, children ...h.Ren) *h.Element {
 62	validation := h.If(
 63		props.ValidationPath != "",
 64		h.Children(
 65			h.Post(props.ValidationPath, hx.BlurEvent),
 66			h.Attribute("hx-swap", "innerHTML transition:true"),
 67			h.Attribute("hx-target", "next div"),
 68		),
 69	)
 70
 71	if props.Type == "" {
 72		props.Type = "text"
 73	}
 74
 75	input := h.Input(
 76		props.Type,
 77		h.Class("border p-2 rounded"),
 78		h.If(
 79			props.Id != "",
 80			h.Id(props.Id),
 81		),
 82		h.If(
 83			props.Name != "",
 84			h.Name(props.Name),
 85		),
 86		h.If(
 87			children != nil,
 88			h.Children(children...),
 89		),
 90		h.If(
 91			props.Required,
 92			h.Required(),
 93		),
 94		h.If(
 95			props.Placeholder != "",
 96			h.Placeholder(props.Placeholder),
 97		),
 98		h.If(
 99			props.DefaultValue != "",
100			h.Attribute("value", props.DefaultValue),
101		),
102		validation,
103	)
104
105	wrapped := h.Div(
106		h.Class("flex flex-col gap-1"),
107		h.If(
108			props.Label != "",
109			h.Label(
110				h.Text(props.Label),
111			),
112		),
113		input,
114		h.If(
115			props.HelperText != "",
116			h.Div(
117				h.Class("text-slate-600 text-sm"),
118				h.Text(props.HelperText),
119			),
120		),
121		h.Div(
122			h.Id(props.Id+"-error"),
123			h.Class("text-red-500"),
124		),
125	)
126
127	return wrapped
128}