-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathselect.go
More file actions
122 lines (109 loc) · 2.71 KB
/
select.go
File metadata and controls
122 lines (109 loc) · 2.71 KB
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
package hmc
import (
"cmp"
"encoding/xml"
"iter"
"net/url"
)
type Option struct {
Label string `json:"label,omitempty"`
Value string `json:"value"`
Selected bool `json:"selected,omitempty"`
Disabled bool `json:"disabled,omitempty"`
}
func (o Option) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
start = xml.StartElement{Name: xml.Name{Local: "c:Option"}}
if o.Selected {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "selected"}})
}
if o.Disabled {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "disabled"}})
}
label := cmp.Or(o.Label, o.Value)
if o.Label != "" {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "value"}, Value: o.Value})
}
return e.EncodeElement(label, start)
}
type Select struct {
Multiple bool `json:"multiple,omitempty"`
Label string `json:"label"`
Name string `json:"name"`
Required bool `json:"required,omitempty"`
Options []Option `json:"options"`
Error string `json:"error,omitempty"`
}
func (s *Select) SetValues(values ...string) {
for i := range s.Options {
s.Options[i].Selected = false
}
for _, v := range values {
found := false
for i, o := range s.Options {
if o.Value == v {
s.Options[i].Selected = true
found = true
}
}
if !found {
s.Options = append([]Option{{
Value: v,
Selected: true,
}}, s.Options...)
}
}
}
func (s Select) Values() iter.Seq[string] {
return iter.Seq[string](func(yield func(string) bool) {
for _, o := range s.Options {
if o.Selected {
if !yield(o.Value) {
return
}
}
}
})
}
func (s Select) Value() string {
next, stop := iter.Pull(s.Values())
defer stop()
val, _ := next()
return val
}
func (s *Select) ExtractFormValue(form url.Values) {
formValue, ok := form[s.Name]
if !ok {
return
}
if s.Multiple {
s.SetValues(formValue...)
delete(form, s.Name)
} else {
s.SetValues(formValue[0])
if len(formValue[1:]) > 0 {
form[s.Name] = formValue[1:]
} else {
delete(form, s.Name)
}
}
}
func (i Select) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
start.Name.Local = "c:Select"
if i.Multiple {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "multiple"}})
}
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "label"}, Value: i.Label})
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "name"}, Value: i.Name})
if i.Required {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "required"}, Value: "true"})
}
if err := e.EncodeToken(start); err != nil {
return nil
}
for _, o := range i.Options {
if err := e.EncodeElement(o, start); err != nil {
return err
}
}
return e.EncodeToken(start.End())
}