Input
An example of how you could build a re-usable input component
This should be your full legal name
package snippets
import (
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/hx"
)
// InputComponent wrapper to make the code snippet work, main code is the Input function
func InputComponent(ctx *h.RequestContext) *h.Partial {
return h.NewPartial(
h.Div(
h.Class("max-w-sm mx-auto flex flex-col gap-4"),
Input(
InputProps{
Id: "my-input",
Name: "my-input",
Label: "Input with label",
Type: "text",
Placeholder: "Type something",
Required: true,
},
h.Attribute("autocomplete", "off"),
h.MaxLength(50),
),
Input(
InputProps{
Id: "my-input",
Name: "my-input",
Label: "Input with default value",
Type: "text",
DefaultValue: "Default value",
},
),
Input(
InputProps{
Id: "my-input",
Name: "my-input",
Label: "Input with helper text",
Type: "text",
Placeholder: "Full name",
HelperText: "This should be your full legal name",
},
),
),
)
}
type InputProps struct {
Id string
Label string
Name string
Type string
DefaultValue string
Placeholder string
Required bool
ValidationPath string
HelperText string
}
func Input(props InputProps, children ...h.Ren) *h.Element {
validation := h.If(
props.ValidationPath != "",
h.Children(
h.Post(props.ValidationPath, hx.BlurEvent),
h.Attribute("hx-swap", "innerHTML transition:true"),
h.Attribute("hx-target", "next div"),
),
)
if props.Type == "" {
props.Type = "text"
}
input := h.Input(
props.Type,
h.Class("border p-2 rounded"),
h.If(
props.Id != "",
h.Id(props.Id),
),
h.If(
props.Name != "",
h.Name(props.Name),
),
h.If(
children != nil,
h.Children(children...),
),
h.If(
props.Required,
h.Required(),
),
h.If(
props.Placeholder != "",
h.Placeholder(props.Placeholder),
),
h.If(
props.DefaultValue != "",
h.Attribute("value", props.DefaultValue),
),
validation,
)
wrapped := h.Div(
h.Class("flex flex-col gap-1"),
h.If(
props.Label != "",
h.Label(
h.Text(props.Label),
),
),
input,
h.If(
props.HelperText != "",
h.Div(
h.Class("text-slate-600 text-sm"),
h.Text(props.HelperText),
),
),
h.Div(
h.Id(props.Id+"-error"),
h.Class("text-red-500"),
),
)
return wrapped
}
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}