-
Notifications
You must be signed in to change notification settings - Fork 1
/
range_input_filter.go
178 lines (166 loc) · 4.85 KB
/
range_input_filter.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package scopes
import (
"errors"
"fmt"
)
// RangeInputFilter is a range filter which allows a start and end value to be entered by user, and any of them is optional.
type RangeInputFilter struct {
filterBase
DefaultStartValue interface{}
DefaultEndValue interface{}
StartPrefixLabel string
StartPostfixLabel string
EndPrefixLabel string
EndPostfixLabel string
CentralLabel string
}
func checkRangeValidType(value interface{}) bool {
switch value.(type) {
case int, float64, nil:
return true
default:
return false
}
}
// NewRangeInputFilter creates a new range input filter.
func NewRangeInputFilter(id string, defaultStartValue, defaultEndValue interface{}, startPrefixLabel, startPostfixLabel, endPrefixLabel, endPostfixLabel, centralLabel string) *RangeInputFilter {
if !checkRangeValidType(defaultStartValue) {
panic("bad type for defaultStartValue")
}
if !checkRangeValidType(defaultEndValue) {
panic("bad type for defaultEndValue")
}
return &RangeInputFilter{
filterBase: filterBase{
Id: id,
DisplayHints: FilterDisplayDefault,
FilterType: "range_input",
},
DefaultStartValue: defaultStartValue,
DefaultEndValue: defaultEndValue,
StartPrefixLabel: startPrefixLabel,
StartPostfixLabel: startPostfixLabel,
EndPrefixLabel: endPrefixLabel,
EndPostfixLabel: endPostfixLabel,
CentralLabel: centralLabel,
}
}
// StartValue gets the start value of this filter from filter state object.
// If the value is not set for the filter it returns false as the second return statement,
// it returns true otherwise
func (f *RangeInputFilter) StartValue(state FilterState) (float64, bool) {
var start float64
var ok bool
slice_interface, ok := state[f.Id].([]interface{})
if ok {
if len(slice_interface) != 2 {
// something went really bad.
// we should have just 2 values
panic("RangeInputFilter:StartValue unexpected number of values found.")
}
switch v := slice_interface[0].(type) {
case float64:
return v, true
case int:
return float64(v), true
case nil:
return 0, false
default:
panic("RangeInputFilter:StartValue Unknown value type")
}
} else {
switch v := f.DefaultStartValue.(type) {
case float64:
return v, true
case int:
return float64(v), true
case nil:
return 0, false
}
}
return start, ok
}
// EndValue gets the end value of this filter from filter state object.
// If the value is not set for the filter it returns false as the second return statement,
// it returns true otherwise
func (f *RangeInputFilter) EndValue(state FilterState) (float64, bool) {
var end float64
var ok bool
slice_interface, ok := state[f.Id].([]interface{})
if ok {
if len(slice_interface) != 2 {
// something went really bad.
// we should have just 2 values
panic("RangeInputFilter:EndValue unexpected number of values found.")
}
switch v := slice_interface[1].(type) {
case float64:
return v, true
case int:
return float64(v), true
case nil:
return 0, false
default:
panic("RangeInputFilter:EndValue Unknown value type")
}
} else {
switch v := f.DefaultEndValue.(type) {
case float64:
return v, true
case int:
return float64(v), true
case nil:
return 0, false
}
}
return end, ok
}
func convertToFloat(value interface{}) float64 {
if value != nil {
fVal, ok := value.(float64)
if !ok {
iVal, ok := value.(int)
if !ok {
panic(fmt.Sprint("RangeInputFilter:convertToFloat unexpected type for given value %v", value))
}
return float64(iVal)
}
return fVal
} else {
panic("RangeInputFilter:convertToFloat nil values are not accepted")
}
}
// UpdateState updates the value of the filter
func (f *RangeInputFilter) UpdateState(state FilterState, start, end interface{}) error {
if !checkRangeValidType(start) {
return errors.New("RangeInputFilter:UpdateState: Bad type for start value. Valid types are int float64 and nil")
}
if !checkRangeValidType(end) {
return errors.New("RangeInputFilter:UpdateState: Bad type for end value. Valid types are int float64 and nil")
}
if start == nil && end == nil {
// remove the state
delete(state, f.Id)
return nil
}
if start != nil && end != nil {
fStart := convertToFloat(start)
fEnd := convertToFloat(end)
if fStart >= fEnd {
return errors.New(fmt.Sprintf("RangeInputFilter::UpdateState(): start_value %v is greater or equal to end_value %v for filter %s", start, end, f.Id))
}
}
state[f.Id] = []interface{}{start, end}
return nil
}
func (f *RangeInputFilter) serializeFilter() map[string]interface{} {
v := f.filterBase.serializeFilter()
v["default_start_value"] = f.DefaultStartValue
v["default_end_value"] = f.DefaultEndValue
v["start_prefix_label"] = f.StartPrefixLabel
v["start_postfix_label"] = f.StartPostfixLabel
v["end_prefix_label"] = f.EndPrefixLabel
v["end_postfix_label"] = f.EndPostfixLabel
v["central_label"] = f.CentralLabel
return v
}