-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
139 lines (114 loc) · 4.17 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package formulate
import (
"net/url"
"reflect"
"golang.org/x/net/html"
)
// CustomEncoder allows for custom rendering behavior of a type to be implemented.
// If a type implements the CustomEncoder interface, BuildFormElement is called in place
// of any other formulate rendering behavior for inputs. The label and help text of the element
// will still be rendered within the row as normal.
type CustomEncoder interface {
// BuildFormElement is passed the key of the form element as computed by formulate,
// the parent node of the element, the field of the struct
// that is currently being rendered, and the form's decorator.
// Note that the built element must be appended to the parent or it will not be shown in the form!
// Errors returned from BuildFormElement propagate back through to the formulate.Encoder.Encode call.
BuildFormElement(key string, parent *html.Node, field StructField, decorator Decorator) error
}
// CustomDecoder allows for custom decoding behavior to be specified for an element. If
// a type implements the CustomDecoder interface, DecodeFormValue is called in place of
// any other decoding behavior.
type CustomDecoder interface {
// DecodeFormValue is passed the whole form values, the name of the element that it is decoding,
// and the values for that specific element. It must return a reflect.Value of equal type to the
// type which is implementing the CustomDecoder interface. If err != nil, the error will propagate
// back through to the Decode() call.
//
// By default, primitive types supported by formulate will remove the values from the form as the form is decoded.
// CustomDecoders may replicate this behaviour if needed, but formulate will not do it automatically.
// See PopFormValue and FormElementName for more information.
DecodeFormValue(form url.Values, name string, values []string) (reflect.Value, error)
}
type (
// Password represents an <input type="password">
Password string
// Email represents an <input type="email">
Email string
// URL represents an <input type="url">
URL string
// Tel represents an <input type="tel">
Tel string
)
// Select represents a HTML <select> element.
type Select interface {
// SelectMultiple indicates whether multiple options can be selected at once.
SelectMultiple() bool
// SelectOptions are the available options
SelectOptions() []Option
}
// Option represents an option in Select inputs and Radio inputs.
type Option struct {
Value interface{}
Label string
Group *string
Disabled bool
Checked *Condition
Attr []html.Attribute
}
func OptGroup(name string) *string {
return &name
}
// Condition are optional booleans for Options.
type Condition bool
// NewCondition creates a new condition based on a bool value.
func NewCondition(b bool) *Condition {
c := Condition(b)
return &c
}
// RadioList represents a list of <input type="radio">. Radio lists must implement their own decoder.
type RadioList interface {
CustomDecoder
RadioOptions() []Option
}
// BoolNumber represents an int (0 or 1) which should actually be rendered as a checkbox.
// It is provided here as a convenience, as many structures use 0 or 1 to represent booleans values.
type BoolNumber int
// DecodeFormValue implements the CustomDecoder interface.
func (bn BoolNumber) DecodeFormValue(form url.Values, name string, _ []string) (reflect.Value, error) {
val, _ := PopFormValue(form, FormElementName(name))
if val == "on" || val == "1" {
return reflect.ValueOf(BoolNumber(1)), nil
}
return reflect.ValueOf(BoolNumber(0)), nil
}
// Bool returns true if the underlying value is 1.
func (bn BoolNumber) Bool() bool {
return bn == 1
}
// Raw is byte data which should be rendered as a string inside a textarea.
type Raw []byte
// BuildFormElement implements the CustomEncoder interface.
func (r Raw) BuildFormElement(key string, parent *html.Node, field StructField, decorator Decorator) error {
n := &html.Node{
Type: html.ElementNode,
Data: "textarea",
Attr: []html.Attribute{
{
Key: "name",
Val: key,
},
{
Key: "id",
Val: key,
},
},
}
n.AppendChild(&html.Node{
Type: html.TextNode,
Data: string(r),
})
parent.AppendChild(n)
decorator.TextareaField(n, field)
return nil
}