-
Notifications
You must be signed in to change notification settings - Fork 6
/
list_radiogroup.go
148 lines (129 loc) · 4.61 KB
/
list_radiogroup.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
140
141
142
143
144
145
146
147
148
package control
import (
"context"
"github.com/goradd/goradd/pkg/bootstrap/config"
"github.com/goradd/goradd/pkg/page"
"github.com/goradd/goradd/pkg/page/action"
"github.com/goradd/goradd/pkg/page/control"
"github.com/goradd/goradd/pkg/page/control/list"
"github.com/goradd/goradd/pkg/page/event"
"github.com/goradd/html5tag"
)
type RadioListGroupI interface {
RadioListI
SetButtonStyle(string) RadioListGroupI
}
// RadioListGroup is a RadioList styled as a group.
//
// See https://getbootstrap.com/docs/4.4/components/buttons/#checkbox-and-radio-buttons
type RadioListGroup struct {
RadioList
buttonStyle string
}
func NewRadioListGroup(parent page.ControlI, id string) *RadioListGroup {
l := new(RadioListGroup)
l.Init(l, parent, id)
return l
}
func (l *RadioListGroup) Init(self any, parent page.ControlI, id string) {
l.RadioList.Init(self, parent, id)
l.SetLabelDrawingMode(html5tag.LabelWrapAfter)
l.SetRowClass("")
l.buttonStyle = ButtonStyleSecondary
config.LoadBootstrap(l.ParentForm())
}
func (l *RadioListGroup) this() RadioListGroupI {
return l.Self().(RadioListGroupI)
}
func (l *RadioListGroup) SetButtonStyle(buttonStyle string) RadioListGroupI {
l.buttonStyle = buttonStyle
return l
}
// DrawingAttributes retrieves the tag's attributes at draw time. You should not normally need to call this, and the
// attributes are disposed of after drawing, so they are essentially read-only.
func (l *RadioListGroup) DrawingAttributes(ctx context.Context) html5tag.Attributes {
a := l.ControlBase.DrawingAttributes(ctx) // skip default checkbox list attributes
a.SetData("grctl", "bs-RadioListGroup")
a.AddClass("btn-group btn-group-toggle")
a.SetData("toggle", "buttons")
return a
}
// RenderItem is called by the framework to render a single item in the list.
func (l *RadioListGroup) RenderItem(item *list.Item) (h string) {
selected := l.SelectedItem().ID() == item.ID()
attributes := html5tag.NewAttributes()
attributes.SetID(item.ID())
attributes.Set("name", l.ID())
attributes.Set("value", item.Value())
attributes.Set("type", "radio")
if selected {
attributes.Set("checked", "")
}
ctrl := html5tag.RenderVoidTag("input", attributes)
labelAttributes := html5tag.NewAttributes().Set("for", item.ID()).AddClass("btn").AddClass(l.buttonStyle)
if selected {
labelAttributes.AddClass("active")
}
return html5tag.RenderLabel(labelAttributes, item.Label(), ctrl, html5tag.LabelWrapAfter)
}
func (l *RadioListGroup) Serialize(e page.Encoder) {
l.RadioList.Serialize(e)
if err := e.Encode(l.buttonStyle); err != nil {
panic(err)
}
}
func (l *RadioListGroup) Deserialize(d page.Decoder) {
l.RadioList.Deserialize(d)
if err := d.Decode(&l.buttonStyle); err != nil {
panic(err)
}
return
}
type RadioListGroupCreator struct {
ID string
// Items is a static list of labels and values that will be in the list. Or, use a DataProvider to dynamically generate the items.
Items []list.ListValue
// DataProvider is the control that will dynamically provide the data for the list and that implements the DataBinder interface.
DataProvider control.DataBinder
// DataProviderID is the id of a control that will dynamically provide the data for the list and that implements the DataBinder interface.
DataProviderID string
// Value is the initial value of the radio list. Often its best to load the value in a separate Load step after creating the control.
Value string
// SaveState saves the selected value so that it is restored if the form is returned to.
ButtonStyle string
// OnChange is the action to take when any of the radio buttons in the list change
OnChange action.ActionI
SaveState bool
page.ControlOptions
}
// Create is called by the framework to create a new control from the Creator. You
// do not normally need to call this.
func (c RadioListGroupCreator) Create(ctx context.Context, parent page.ControlI) page.ControlI {
ctrl := NewRadioListGroup(parent, c.ID)
c.Init(ctx, ctrl)
return ctrl
}
func (c RadioListGroupCreator) Init(ctx context.Context, ctrl RadioListGroupI) {
sub := RadioListCreator{
ID: c.ID,
Items: c.Items,
DataProvider: c.DataProvider,
Value: c.Value,
SaveState: c.SaveState,
ControlOptions: c.ControlOptions,
}
sub.Init(ctx, ctrl)
if c.ButtonStyle != "" {
ctrl.SetButtonStyle(c.ButtonStyle)
}
if c.OnChange != nil {
ctrl.On(event.Change(), c.OnChange)
}
}
// GetRadioListGroup is a convenience method to return the control with the given id from the page.
func GetRadioListGroup(c page.ControlI, id string) *RadioListGroup {
return c.Page().GetControl(id).(*RadioListGroup)
}
func init() {
page.RegisterControl(&RadioListGroup{})
}