datagrid 1.8.0 → 1.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -6
- data/Readme.markdown +4 -4
- data/app/assets/stylesheets/datagrid.sass +1 -1
- data/app/views/datagrid/_form.html.erb +0 -1
- data/datagrid.gemspec +3 -3
- data/lib/datagrid/column_names_attribute.rb +3 -1
- data/lib/datagrid/columns.rb +268 -264
- data/lib/datagrid/core.rb +132 -133
- data/lib/datagrid/drivers/abstract_driver.rb +1 -2
- data/lib/datagrid/drivers/array.rb +10 -9
- data/lib/datagrid/drivers/mongoid.rb +1 -1
- data/lib/datagrid/filters/base_filter.rb +3 -3
- data/lib/datagrid/filters/date_filter.rb +1 -1
- data/lib/datagrid/filters/extended_boolean_filter.rb +6 -3
- data/lib/datagrid/filters.rb +67 -72
- data/lib/datagrid/form_builder.rb +4 -8
- data/lib/datagrid/ordering.rb +71 -74
- data/lib/datagrid/rspec.rb +2 -2
- data/lib/datagrid/scaffold.rb +3 -3
- data/lib/datagrid/utils.rb +7 -10
- data/lib/datagrid/version.rb +1 -1
- data/templates/base.rb.erb +27 -3
- metadata +8 -8
data/lib/datagrid/core.rb
CHANGED
@@ -1,26 +1,20 @@
|
|
1
1
|
require "datagrid/drivers"
|
2
2
|
require "active_support/core_ext/class/attribute"
|
3
|
+
require "active_model/attribute_assignment"
|
3
4
|
|
4
5
|
module Datagrid
|
5
6
|
module Core
|
7
|
+
include ::ActiveModel::AttributeAssignment
|
6
8
|
|
7
9
|
# @!visibility private
|
8
10
|
def self.included(base)
|
9
11
|
base.extend ClassMethods
|
10
12
|
base.class_eval do
|
11
13
|
class_attribute :scope_value
|
12
|
-
|
13
|
-
class_attribute :datagrid_attributes, instance_writer: false
|
14
|
-
self.datagrid_attributes = []
|
15
|
-
|
14
|
+
class_attribute :datagrid_attributes, instance_writer: false, default: []
|
16
15
|
class_attribute :dynamic_block, instance_writer: false
|
17
|
-
class_attribute :forbidden_attributes_protection, instance_writer: false
|
18
|
-
self.forbidden_attributes_protection = false
|
19
|
-
if defined?(::ActiveModel::AttributeAssignment)
|
20
|
-
include ::ActiveModel::AttributeAssignment
|
21
|
-
end
|
16
|
+
class_attribute :forbidden_attributes_protection, instance_writer: false, default: false
|
22
17
|
end
|
23
|
-
base.include InstanceMethods
|
24
18
|
end
|
25
19
|
|
26
20
|
module ClassMethods
|
@@ -129,150 +123,155 @@ module Datagrid
|
|
129
123
|
|
130
124
|
end
|
131
125
|
|
132
|
-
|
133
|
-
|
134
|
-
def initialize(attributes = nil, &block)
|
135
|
-
super()
|
136
|
-
|
137
|
-
if attributes
|
138
|
-
self.attributes = attributes
|
139
|
-
end
|
126
|
+
def initialize(attributes = nil, &block)
|
127
|
+
super()
|
140
128
|
|
141
|
-
|
142
|
-
|
143
|
-
self.scope(&block)
|
144
|
-
end
|
129
|
+
if attributes
|
130
|
+
self.attributes = attributes
|
145
131
|
end
|
146
132
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
self.datagrid_attributes.each do |name|
|
151
|
-
result[name] = self[name]
|
152
|
-
end
|
153
|
-
result
|
133
|
+
instance_eval(&dynamic_block) if dynamic_block
|
134
|
+
if block_given?
|
135
|
+
self.scope(&block)
|
154
136
|
end
|
137
|
+
end
|
155
138
|
|
156
|
-
# @return [Object] Any datagrid attribute value
|
157
|
-
def [](attribute)
|
158
|
-
self.send(attribute)
|
159
|
-
end
|
160
139
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
self.send(:"#{attribute}=", value)
|
140
|
+
# @return [Hash<Symbol, Object>] grid attributes including filter values and ordering values
|
141
|
+
def attributes
|
142
|
+
result = {}
|
143
|
+
self.datagrid_attributes.each do |name|
|
144
|
+
result[name] = self[name]
|
167
145
|
end
|
146
|
+
result
|
147
|
+
end
|
168
148
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
149
|
+
# Updates datagrid attributes with a passed hash argument
|
150
|
+
# @param attributes [Hash<Symbol, Object>]
|
151
|
+
# @example
|
152
|
+
# grid = MyGrid.new
|
153
|
+
# grid.attributes = {first_name: 'John', last_name: 'Smith'}
|
154
|
+
# grid.first_name # => 'John'
|
155
|
+
# grid.last_name # => 'Smith'
|
156
|
+
def attributes=(attributes)
|
157
|
+
super(attributes)
|
158
|
+
end
|
173
159
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
attributes.permit!
|
179
|
-
end
|
180
|
-
assign_attributes(attributes)
|
181
|
-
else
|
182
|
-
attributes.each do |name, value|
|
183
|
-
self[name] = value
|
184
|
-
end
|
185
|
-
self
|
186
|
-
end
|
187
|
-
end
|
160
|
+
# @return [Object] Any datagrid attribute value
|
161
|
+
def [](attribute)
|
162
|
+
self.public_send(attribute)
|
163
|
+
end
|
188
164
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
attributes.delete(key) if value.nil?
|
197
|
-
end
|
198
|
-
attributes
|
199
|
-
end
|
165
|
+
# Assigns any datagrid attribute
|
166
|
+
# @param attribute [Symbol, String] Datagrid attribute name
|
167
|
+
# @param value [Object] Datagrid attribute value
|
168
|
+
# @return [void]
|
169
|
+
def []=(attribute, value)
|
170
|
+
self.public_send(:"#{attribute}=", value)
|
171
|
+
end
|
200
172
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
# # => "/products?products_grid[category]=dresses&products_grid[available]=true"
|
206
|
-
def query_params(attributes = {})
|
207
|
-
{ param_name.to_sym => as_query.merge(attributes) }
|
208
|
-
end
|
173
|
+
# @return [Object] a scope relation (e.g ActiveRecord::Relation) with all applied filters
|
174
|
+
def assets
|
175
|
+
scope
|
176
|
+
end
|
209
177
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
# scope.where(author_id: current_user.id)
|
219
|
-
# end
|
220
|
-
# grid.assets
|
221
|
-
# # => SELECT * FROM articles WHERE author_id = ?
|
222
|
-
# # ORDER BY created_at desc
|
223
|
-
def scope(&block)
|
224
|
-
if block_given?
|
225
|
-
current_scope = scope
|
226
|
-
self.scope_value = proc {
|
227
|
-
Datagrid::Utils.apply_args(current_scope, &block)
|
228
|
-
}
|
229
|
-
self
|
230
|
-
else
|
231
|
-
scope = original_scope
|
232
|
-
driver.to_scope(scope)
|
233
|
-
end
|
178
|
+
# Returns serializable query arguments skipping all nil values
|
179
|
+
# @example
|
180
|
+
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
181
|
+
# grid.as_query # => {category: 'dresses', available: true}
|
182
|
+
def as_query
|
183
|
+
attributes = self.attributes.clone
|
184
|
+
attributes.each do |key, value|
|
185
|
+
attributes.delete(key) if value.nil?
|
234
186
|
end
|
187
|
+
attributes
|
188
|
+
end
|
235
189
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
190
|
+
# @return [Hash<Symbol, Hash<Symbol, Object>>] query parameters to link this grid from a page
|
191
|
+
# @example
|
192
|
+
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
193
|
+
# Rails.application.routes.url_helpers.products_path(grid.query_params)
|
194
|
+
# # => "/products?products_grid[category]=dresses&products_grid[available]=true"
|
195
|
+
def query_params(attributes = {})
|
196
|
+
{ param_name.to_sym => as_query.merge(attributes) }
|
197
|
+
end
|
241
198
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
199
|
+
# Redefines scope at instance level
|
200
|
+
# @example
|
201
|
+
# class MyGrid
|
202
|
+
# scope { Article.order('created_at desc') }
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# grid = MyGrid.new
|
206
|
+
# grid.scope do |scope|
|
207
|
+
# scope.where(author_id: current_user.id)
|
208
|
+
# end
|
209
|
+
# grid.assets
|
210
|
+
# # => SELECT * FROM articles WHERE author_id = ?
|
211
|
+
# # ORDER BY created_at desc
|
212
|
+
def scope(&block)
|
213
|
+
if block_given?
|
214
|
+
current_scope = scope
|
215
|
+
self.scope_value = proc {
|
216
|
+
Datagrid::Utils.apply_args(current_scope, &block)
|
217
|
+
}
|
218
|
+
self
|
219
|
+
else
|
220
|
+
scope = original_scope
|
221
|
+
driver.to_scope(scope)
|
246
222
|
end
|
223
|
+
end
|
247
224
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
225
|
+
# @!visibility private
|
226
|
+
def original_scope
|
227
|
+
check_scope_defined!
|
228
|
+
scope_value.call
|
229
|
+
end
|
252
230
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
231
|
+
# Resets current instance scope to default scope defined in a class
|
232
|
+
# @return [void]
|
233
|
+
def reset_scope
|
234
|
+
self.scope_value = self.class.scope_value
|
235
|
+
end
|
257
236
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
237
|
+
# @return [Boolean] true if the scope was redefined for this instance of grid object
|
238
|
+
def redefined_scope?
|
239
|
+
self.class.scope_value != scope_value
|
240
|
+
end
|
262
241
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
end.join(", ")
|
268
|
-
"#<#{self.class} #{attrs}>"
|
269
|
-
end
|
242
|
+
# @!visibility private
|
243
|
+
def driver
|
244
|
+
self.class.driver
|
245
|
+
end
|
270
246
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
247
|
+
# @!visibility private
|
248
|
+
def check_scope_defined!(message = nil)
|
249
|
+
self.class.send :check_scope_defined!, message
|
250
|
+
end
|
251
|
+
|
252
|
+
# @return [String] a datagrid attributes and their values in inspection form
|
253
|
+
def inspect
|
254
|
+
attrs = attributes.map do |key, value|
|
255
|
+
"#{key}: #{value.inspect}"
|
256
|
+
end.join(", ")
|
257
|
+
"#<#{self.class} #{attrs}>"
|
258
|
+
end
|
259
|
+
|
260
|
+
def ==(other)
|
261
|
+
self.class == other.class &&
|
262
|
+
attributes == other.attributes &&
|
263
|
+
scope == other.scope
|
264
|
+
end
|
265
|
+
|
266
|
+
# Resets loaded assets and column values cache
|
267
|
+
# @return [void]
|
268
|
+
def reset
|
269
|
+
assets.reset
|
270
|
+
end
|
271
|
+
|
272
|
+
protected
|
273
|
+
def sanitize_for_mass_assignment(attributes)
|
274
|
+
forbidden_attributes_protection ? super(attributes) : attributes
|
276
275
|
end
|
277
276
|
end
|
278
277
|
end
|
@@ -5,11 +5,10 @@ module Datagrid
|
|
5
5
|
|
6
6
|
TIMESTAMP_CLASSES = [DateTime, Time, ActiveSupport::TimeWithZone]
|
7
7
|
|
8
|
-
class_attribute :subclasses
|
8
|
+
class_attribute :subclasses, default: []
|
9
9
|
|
10
10
|
def self.inherited(base)
|
11
11
|
super(base)
|
12
|
-
self.subclasses ||= []
|
13
12
|
self.subclasses << base
|
14
13
|
end
|
15
14
|
|
@@ -4,7 +4,10 @@ module Datagrid
|
|
4
4
|
class Array < AbstractDriver
|
5
5
|
|
6
6
|
def self.match?(scope)
|
7
|
-
!Datagrid::Drivers::ActiveRecord.match?(scope) && (
|
7
|
+
!Datagrid::Drivers::ActiveRecord.match?(scope) && (
|
8
|
+
scope.is_a?(::Array) || scope.is_a?(Enumerator) ||
|
9
|
+
(defined?(::ActiveRecord::Result) && scope.is_a?(::ActiveRecord::Result))
|
10
|
+
)
|
8
11
|
end
|
9
12
|
|
10
13
|
def to_scope(scope)
|
@@ -13,7 +16,7 @@ module Datagrid
|
|
13
16
|
|
14
17
|
def where(scope, attribute, value)
|
15
18
|
scope.select do |object|
|
16
|
-
object.
|
19
|
+
object.public_send(attribute) == value
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
@@ -21,7 +24,7 @@ module Datagrid
|
|
21
24
|
return scope unless order
|
22
25
|
return scope if order.empty?
|
23
26
|
scope.sort_by do |object|
|
24
|
-
object.
|
27
|
+
object.public_send(order)
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -39,15 +42,13 @@ module Datagrid
|
|
39
42
|
|
40
43
|
def greater_equal(scope, field, value)
|
41
44
|
scope.select do |object|
|
42
|
-
|
43
|
-
compare_value.respond_to?(:>=) && compare_value >= value
|
45
|
+
object.public_send(field) >= value
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
def less_equal(scope, field, value)
|
48
50
|
scope.select do |object|
|
49
|
-
|
50
|
-
compare_value.respond_to?(:<=) && compare_value <= value
|
51
|
+
object.public_send(field) <= value
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -57,12 +58,12 @@ module Datagrid
|
|
57
58
|
|
58
59
|
def is_timestamp?(scope, column_name)
|
59
60
|
has_column?(scope, column_name) &&
|
60
|
-
timestamp_class?(scope.first.
|
61
|
+
timestamp_class?(scope.first.public_send(column_name).class)
|
61
62
|
end
|
62
63
|
|
63
64
|
def contains(scope, field, value)
|
64
65
|
scope.select do |object|
|
65
|
-
object.
|
66
|
+
object.public_send(field).to_s.include?(value)
|
66
67
|
end
|
67
68
|
end
|
68
69
|
|
@@ -60,7 +60,7 @@ module Datagrid
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def normalized_column_type(scope, field)
|
63
|
-
type = to_scope(scope).klass.fields[field.to_s]
|
63
|
+
type = to_scope(scope).klass.fields[field.to_s]&.type
|
64
64
|
return nil unless type
|
65
65
|
{
|
66
66
|
[BigDecimal , String, Symbol, Range, Array, Hash, ] => :string,
|
@@ -155,7 +155,7 @@ class Datagrid::Filters::BaseFilter
|
|
155
155
|
when String
|
156
156
|
value.split(separator)
|
157
157
|
when Range
|
158
|
-
[value.
|
158
|
+
[value.begin, value.end]
|
159
159
|
when Array
|
160
160
|
value
|
161
161
|
else
|
@@ -173,8 +173,8 @@ class Datagrid::Filters::BaseFilter
|
|
173
173
|
|
174
174
|
def default_filter(value, scope, grid)
|
175
175
|
return nil if dummy?
|
176
|
-
if !driver.has_column?(scope, name) && scope.respond_to?(name)
|
177
|
-
scope.
|
176
|
+
if !driver.has_column?(scope, name) && scope.respond_to?(name, true)
|
177
|
+
scope.public_send(name, value)
|
178
178
|
else
|
179
179
|
default_filter_where(scope, value)
|
180
180
|
end
|
@@ -6,7 +6,7 @@ class Datagrid::Filters::DateFilter < Datagrid::Filters::BaseFilter
|
|
6
6
|
|
7
7
|
def apply(grid_object, scope, value)
|
8
8
|
if value.is_a?(Range)
|
9
|
-
value = value.
|
9
|
+
value = value.begin&.beginning_of_day..value.end&.end_of_day
|
10
10
|
end
|
11
11
|
super(grid_object, scope, value)
|
12
12
|
end
|
@@ -3,6 +3,8 @@ class Datagrid::Filters::ExtendedBooleanFilter < Datagrid::Filters::EnumFilter
|
|
3
3
|
|
4
4
|
YES = "YES"
|
5
5
|
NO = "NO"
|
6
|
+
TRUTH_VALUES = [true, 'true', "y", "yes"]
|
7
|
+
FALSE_VALUES = [false, 'false', "n", "no"]
|
6
8
|
|
7
9
|
def initialize(report, attribute, options = {}, &block)
|
8
10
|
options[:select] = -> { boolean_select }
|
@@ -15,10 +17,11 @@ class Datagrid::Filters::ExtendedBooleanFilter < Datagrid::Filters::EnumFilter
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def parse(value)
|
18
|
-
|
19
|
-
|
20
|
+
value = value.downcase if value.is_a?(String)
|
21
|
+
case value
|
22
|
+
when *TRUTH_VALUES
|
20
23
|
YES
|
21
|
-
when
|
24
|
+
when *FALSE_VALUES
|
22
25
|
NO
|
23
26
|
when value.blank?
|
24
27
|
nil
|
data/lib/datagrid/filters.rb
CHANGED
@@ -38,11 +38,9 @@ module Datagrid
|
|
38
38
|
|
39
39
|
include Datagrid::Core
|
40
40
|
include Datagrid::Filters::CompositeFilters
|
41
|
-
class_attribute :filters_array
|
42
|
-
self.filters_array = []
|
41
|
+
class_attribute :filters_array, default: []
|
43
42
|
|
44
43
|
end
|
45
|
-
base.include InstanceMethods
|
46
44
|
end
|
47
45
|
|
48
46
|
module ClassMethods
|
@@ -138,94 +136,91 @@ module Datagrid
|
|
138
136
|
end
|
139
137
|
end
|
140
138
|
|
141
|
-
module InstanceMethods
|
142
139
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
super(*args, &block)
|
140
|
+
# @!visibility private
|
141
|
+
def initialize(*args, &block)
|
142
|
+
self.filters_array = self.class.filters_array.clone
|
143
|
+
self.filters_array.each do |filter|
|
144
|
+
self[filter.name] = filter.default(self)
|
150
145
|
end
|
146
|
+
super(*args, &block)
|
147
|
+
end
|
151
148
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
149
|
+
# @!visibility private
|
150
|
+
def assets
|
151
|
+
apply_filters(super, filters)
|
152
|
+
end
|
156
153
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
154
|
+
# Returns filter value for given filter definition
|
155
|
+
def filter_value(filter)
|
156
|
+
self[filter.name]
|
157
|
+
end
|
161
158
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
159
|
+
# Returns string representation of filter value
|
160
|
+
def filter_value_as_string(name)
|
161
|
+
filter = filter_by_name(name)
|
162
|
+
value = filter_value(filter)
|
163
|
+
if value.is_a?(Array)
|
164
|
+
value.map {|v| filter.format(v) }.join(filter.separator)
|
165
|
+
else
|
166
|
+
filter.format(value)
|
171
167
|
end
|
168
|
+
end
|
172
169
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
170
|
+
# Returns filter object with the given name
|
171
|
+
def filter_by_name(name)
|
172
|
+
self.class.filter_by_name(name)
|
173
|
+
end
|
177
174
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
175
|
+
# Returns assets filtered only by specified filters
|
176
|
+
# Allows partial filtering
|
177
|
+
def filter_by(*filters)
|
178
|
+
apply_filters(scope, filters.map{|f| filter_by_name(f)})
|
179
|
+
end
|
183
180
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
181
|
+
# Returns select options for specific filter or filter name
|
182
|
+
# If given filter doesn't support select options raises `ArgumentError`
|
183
|
+
def select_options(filter)
|
184
|
+
find_select_filter(filter).select(self)
|
185
|
+
end
|
189
186
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
187
|
+
# Sets all options as selected for a filter that has options
|
188
|
+
def select_all(filter)
|
189
|
+
filter = find_select_filter(filter)
|
190
|
+
self[filter.name] = select_values(filter)
|
191
|
+
end
|
195
192
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
# Returns all values that can be set to a filter with select options
|
194
|
+
def select_values(filter)
|
195
|
+
find_select_filter(filter).select_values(self)
|
196
|
+
end
|
200
197
|
|
201
|
-
|
202
|
-
|
203
|
-
|
198
|
+
def default_filter
|
199
|
+
self.class.default_filter
|
200
|
+
end
|
204
201
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
202
|
+
# Returns all currently enabled filters
|
203
|
+
def filters
|
204
|
+
self.class.filters.select do |filter|
|
205
|
+
filter.enabled?(self)
|
210
206
|
end
|
207
|
+
end
|
211
208
|
|
212
|
-
|
209
|
+
protected
|
213
210
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
end
|
220
|
-
filter
|
211
|
+
def find_select_filter(filter)
|
212
|
+
filter = filter_by_name(filter)
|
213
|
+
unless filter.class.included_modules.include?(::Datagrid::Filters::SelectOptions)
|
214
|
+
raise ::Datagrid::ArgumentError,
|
215
|
+
"#{self.class.name}##{filter.name} with type #{FILTER_TYPES.invert[filter.class].inspect} can not have select options"
|
221
216
|
end
|
217
|
+
filter
|
218
|
+
end
|
222
219
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
end
|
220
|
+
def apply_filters(current_scope, filters)
|
221
|
+
filters.inject(current_scope) do |result, filter|
|
222
|
+
filter.apply(self, result, filter_value(filter))
|
227
223
|
end
|
228
224
|
end
|
229
|
-
|
230
225
|
end
|
231
226
|
end
|
@@ -10,12 +10,8 @@ module Datagrid
|
|
10
10
|
# * <tt>text_field</tt> for other filter types
|
11
11
|
def datagrid_filter(filter_or_attribute, partials: nil, **options, &block)
|
12
12
|
filter = datagrid_get_filter(filter_or_attribute)
|
13
|
-
|
14
|
-
|
15
|
-
**filter.input_options,
|
16
|
-
**add_html_classes(options, filter.name, datagrid_filter_html_class(filter)),
|
17
|
-
&block
|
18
|
-
)
|
13
|
+
options = add_html_classes({**filter.input_options, **options}, filter.name, datagrid_filter_html_class(filter))
|
14
|
+
self.send( filter.form_builder_helper_name, filter, **options, &block)
|
19
15
|
end
|
20
16
|
|
21
17
|
# @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
|
@@ -93,7 +89,7 @@ module Datagrid
|
|
93
89
|
end
|
94
90
|
|
95
91
|
def enum_checkbox_checked?(filter, option_value)
|
96
|
-
current_value = object.
|
92
|
+
current_value = object.public_send(filter.name)
|
97
93
|
if current_value.respond_to?(:include?)
|
98
94
|
# Typecast everything to string
|
99
95
|
# to remove difference between String and Symbol
|
@@ -170,7 +166,7 @@ module Datagrid
|
|
170
166
|
def datagrid_range_filter_options(object, filter, type, options)
|
171
167
|
type_method_map = {from: :first, to: :last}
|
172
168
|
options = add_html_classes(options, type)
|
173
|
-
options[:value] = filter.format(object[filter.name]
|
169
|
+
options[:value] = filter.format(object[filter.name]&.public_send(type_method_map[type]))
|
174
170
|
# In case of datagrid ranged filter
|
175
171
|
# from and to input will have same id
|
176
172
|
if !options.key?(:id)
|