datagrid 1.6.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/Readme.markdown +2 -2
- data/datagrid.gemspec +10 -14
- data/lib/datagrid/active_model.rb +25 -29
- data/lib/datagrid/column_names_attribute.rb +9 -7
- data/lib/datagrid/columns/column.rb +3 -1
- data/lib/datagrid/columns.rb +139 -171
- data/lib/datagrid/configuration.rb +6 -1
- data/lib/datagrid/core.rb +43 -22
- data/lib/datagrid/drivers/abstract_driver.rb +2 -1
- data/lib/datagrid/drivers/active_record.rb +2 -1
- data/lib/datagrid/drivers/array.rb +2 -1
- data/lib/datagrid/drivers/mongo_mapper.rb +2 -1
- data/lib/datagrid/drivers/mongoid.rb +3 -2
- data/lib/datagrid/drivers/sequel.rb +2 -1
- data/lib/datagrid/drivers.rb +2 -1
- data/lib/datagrid/engine.rb +3 -2
- data/lib/datagrid/filters/base_filter.rb +5 -2
- data/lib/datagrid/filters/boolean_enum_filter.rb +5 -3
- data/lib/datagrid/filters/boolean_filter.rb +2 -1
- data/lib/datagrid/filters/composite_filters.rb +5 -11
- data/lib/datagrid/filters/extended_boolean_filter.rb +2 -1
- data/lib/datagrid/filters/select_options.rb +34 -1
- data/lib/datagrid/filters.rb +38 -15
- data/lib/datagrid/form_builder.rb +10 -3
- data/lib/datagrid/helper.rb +47 -21
- data/lib/datagrid/ordering.rb +14 -14
- data/lib/datagrid/renderer.rb +2 -1
- data/lib/datagrid/scaffold.rb +1 -1
- data/lib/datagrid/utils.rb +1 -0
- data/lib/datagrid/version.rb +1 -1
- data/lib/datagrid.rb +2 -1
- metadata +8 -8
data/lib/datagrid/core.rb
CHANGED
@@ -4,6 +4,7 @@ require "active_support/core_ext/class/attribute"
|
|
4
4
|
module Datagrid
|
5
5
|
module Core
|
6
6
|
|
7
|
+
# @!visibility private
|
7
8
|
def self.included(base)
|
8
9
|
base.extend ClassMethods
|
9
10
|
base.class_eval do
|
@@ -12,7 +13,7 @@ module Datagrid
|
|
12
13
|
class_attribute :datagrid_attributes, instance_writer: false
|
13
14
|
self.datagrid_attributes = []
|
14
15
|
|
15
|
-
class_attribute :dynamic_block, :
|
16
|
+
class_attribute :dynamic_block, instance_writer: false
|
16
17
|
class_attribute :forbidden_attributes_protection, instance_writer: false
|
17
18
|
self.forbidden_attributes_protection = false
|
18
19
|
if defined?(::ActiveModel::AttributeAssignment)
|
@@ -20,11 +21,12 @@ module Datagrid
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
base.send :include, InstanceMethods
|
23
|
-
end
|
24
|
+
end
|
24
25
|
|
25
26
|
module ClassMethods
|
26
27
|
|
27
|
-
|
28
|
+
# @!visibility private
|
29
|
+
def datagrid_attribute(name, &block)
|
28
30
|
unless datagrid_attributes.include?(name)
|
29
31
|
block ||= lambda do |value|
|
30
32
|
value
|
@@ -41,6 +43,11 @@ module Datagrid
|
|
41
43
|
end
|
42
44
|
|
43
45
|
# Defines a scope at class level
|
46
|
+
# @return [void]
|
47
|
+
# @example
|
48
|
+
# scope { User }
|
49
|
+
# scope { Project.where(deleted: false) }
|
50
|
+
# scope { Project.preload(:stages) }
|
44
51
|
def scope(&block)
|
45
52
|
if block
|
46
53
|
current_scope = scope_value
|
@@ -54,12 +61,17 @@ module Datagrid
|
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
57
|
-
|
64
|
+
# @!visibility private
|
65
|
+
def driver
|
58
66
|
@driver ||= Drivers::AbstractDriver.guess_driver(scope).new
|
59
67
|
end
|
60
68
|
|
61
69
|
# Allows dynamic columns definition, that could not be defined at class level
|
62
|
-
#
|
70
|
+
# Columns that depend on the database state or third party service
|
71
|
+
# can be defined this way.
|
72
|
+
# @param block [Proc] block that defines dynamic columns
|
73
|
+
# @return [void]
|
74
|
+
# @example
|
63
75
|
# class MerchantsGrid
|
64
76
|
#
|
65
77
|
# scope { Merchant }
|
@@ -69,12 +81,15 @@ module Datagrid
|
|
69
81
|
# dynamic do
|
70
82
|
# PurchaseCategory.all.each do |category|
|
71
83
|
# column(:"#{category.name.underscore}_sales") do |merchant|
|
72
|
-
# merchant.purchases.where(:
|
84
|
+
# merchant.purchases.where(category_id: category.id).count
|
73
85
|
# end
|
74
86
|
# end
|
75
87
|
# end
|
76
88
|
# end
|
77
89
|
#
|
90
|
+
# ProductCategory.create!(name: 'Swimwear')
|
91
|
+
# ProductCategory.create!(name: 'Sportswear')
|
92
|
+
#
|
78
93
|
# grid = MerchantsGrid.new
|
79
94
|
# grid.data # => [
|
80
95
|
# # [ "Name", "Swimwear Sales", "Sportswear Sales", ... ]
|
@@ -95,6 +110,7 @@ module Datagrid
|
|
95
110
|
end
|
96
111
|
|
97
112
|
protected
|
113
|
+
|
98
114
|
def check_scope_defined!(message = nil)
|
99
115
|
message ||= "#{self}.scope is not defined"
|
100
116
|
raise(Datagrid::ConfigurationError, message) unless scope_value
|
@@ -105,7 +121,7 @@ module Datagrid
|
|
105
121
|
child_class.datagrid_attributes = self.datagrid_attributes.clone
|
106
122
|
end
|
107
123
|
|
108
|
-
end
|
124
|
+
end
|
109
125
|
|
110
126
|
module InstanceMethods
|
111
127
|
|
@@ -122,8 +138,7 @@ module Datagrid
|
|
122
138
|
end
|
123
139
|
end
|
124
140
|
|
125
|
-
#
|
126
|
-
# and ordering values
|
141
|
+
# @return [Hash<Symbol, Object>] grid attributes including filter values and ordering values
|
127
142
|
def attributes
|
128
143
|
result = {}
|
129
144
|
self.datagrid_attributes.each do |name|
|
@@ -132,21 +147,24 @@ module Datagrid
|
|
132
147
|
result
|
133
148
|
end
|
134
149
|
|
135
|
-
#
|
150
|
+
# @return [Object] Any datagrid attribute value
|
136
151
|
def [](attribute)
|
137
152
|
self.send(attribute)
|
138
153
|
end
|
139
154
|
|
155
|
+
# Assigns any datagrid attribute
|
156
|
+
# @param attribute [Symbol, String] Datagrid attribute name
|
157
|
+
# @param value [Object] Datagrid attribute value
|
158
|
+
# @return [void]
|
140
159
|
def []=(attribute, value)
|
141
160
|
self.send(:"#{attribute}=", value)
|
142
161
|
end
|
143
162
|
|
144
|
-
#
|
163
|
+
# @return [Object] a scope relation (e.g ActiveRecord::Relation) with all applied filters
|
145
164
|
def assets
|
146
165
|
driver.to_scope(scope)
|
147
166
|
end
|
148
167
|
|
149
|
-
|
150
168
|
# Updates datagrid attributes with a passed hash argument
|
151
169
|
def attributes=(attributes)
|
152
170
|
if respond_to?(:assign_attributes)
|
@@ -163,7 +181,7 @@ module Datagrid
|
|
163
181
|
end
|
164
182
|
|
165
183
|
# Returns serializable query arguments skipping all nil values
|
166
|
-
#
|
184
|
+
# @example
|
167
185
|
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
168
186
|
# grid.as_query # => {category: 'dresses', available: true}
|
169
187
|
def as_query
|
@@ -174,8 +192,8 @@ module Datagrid
|
|
174
192
|
attributes
|
175
193
|
end
|
176
194
|
|
177
|
-
#
|
178
|
-
#
|
195
|
+
# @return [Hash<Symbol, Hash<Symbol, Object>>] query parameters to link this grid from a page
|
196
|
+
# @example
|
179
197
|
# grid = ProductsGrid.new(category: 'dresses', available: true)
|
180
198
|
# Rails.application.routes.url_helpers.products_path(grid.query_params)
|
181
199
|
# # => "/products?products_grid[category]=dresses&products_grid[available]=true"
|
@@ -184,19 +202,18 @@ module Datagrid
|
|
184
202
|
end
|
185
203
|
|
186
204
|
# Redefines scope at instance level
|
187
|
-
#
|
205
|
+
# @example
|
188
206
|
# class MyGrid
|
189
207
|
# scope { Article.order('created_at desc') }
|
190
208
|
# end
|
191
209
|
#
|
192
210
|
# grid = MyGrid.new
|
193
211
|
# grid.scope do |scope|
|
194
|
-
# scope.where(:
|
212
|
+
# scope.where(author_id: current_user.id)
|
195
213
|
# end
|
196
214
|
# grid.assets
|
197
215
|
# # => SELECT * FROM articles WHERE author_id = ?
|
198
216
|
# # ORDER BY created_at desc
|
199
|
-
#
|
200
217
|
def scope(&block)
|
201
218
|
if block_given?
|
202
219
|
current_scope = scope
|
@@ -211,23 +228,27 @@ module Datagrid
|
|
211
228
|
end
|
212
229
|
|
213
230
|
# Resets current instance scope to default scope defined in a class
|
231
|
+
# @return [void]
|
214
232
|
def reset_scope
|
215
233
|
self.scope_value = self.class.scope_value
|
216
234
|
end
|
217
235
|
|
218
|
-
#
|
236
|
+
# @return [Boolean] true if the scope was redefined for this instance of grid object
|
219
237
|
def redefined_scope?
|
220
238
|
self.class.scope_value != scope_value
|
221
239
|
end
|
222
240
|
|
223
|
-
|
241
|
+
# @!visibility private
|
242
|
+
def driver
|
224
243
|
self.class.driver
|
225
244
|
end
|
226
245
|
|
227
|
-
|
246
|
+
# @!visibility private
|
247
|
+
def check_scope_defined!(message = nil)
|
228
248
|
self.class.send :check_scope_defined!, message
|
229
249
|
end
|
230
250
|
|
251
|
+
# @return [String] a datagrid attributes and their values in inspection form
|
231
252
|
def inspect
|
232
253
|
attrs = attributes.map do |key, value|
|
233
254
|
"#{key}: #{value.inspect}"
|
@@ -240,6 +261,6 @@ module Datagrid
|
|
240
261
|
attributes == other.attributes &&
|
241
262
|
scope == other.scope
|
242
263
|
end
|
243
|
-
end
|
264
|
+
end
|
244
265
|
end
|
245
266
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Datagrid
|
2
2
|
module Drivers
|
3
|
-
|
3
|
+
# @!visibility private
|
4
|
+
class Mongoid < AbstractDriver
|
4
5
|
|
5
6
|
def self.match?(scope)
|
6
7
|
return false unless defined?(::Mongoid)
|
@@ -63,7 +64,7 @@ module Datagrid
|
|
63
64
|
return nil unless type
|
64
65
|
{
|
65
66
|
[BigDecimal , String, Symbol, Range, Array, Hash, ] => :string,
|
66
|
-
[Boolean] => :boolean,
|
67
|
+
[::Mongoid::Boolean] => :boolean,
|
67
68
|
|
68
69
|
[Date] => :date,
|
69
70
|
|
data/lib/datagrid/drivers.rb
CHANGED
data/lib/datagrid/engine.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require "rails/engine"
|
2
2
|
|
3
3
|
module Datagrid
|
4
|
+
# @!private
|
4
5
|
class Engine < ::Rails::Engine
|
5
6
|
initializer "datagrid.helpers" do
|
6
7
|
#TODO: check why it doesn't work
|
7
8
|
ActiveSupport.on_load :action_view do
|
8
9
|
include Datagrid::Helper
|
9
|
-
end
|
10
|
-
end
|
10
|
+
end
|
11
|
+
end
|
11
12
|
end
|
12
13
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# An error raise when datagrid filter is defined incorrectly and
|
2
|
+
# causes filtering chain to be broken
|
1
3
|
class Datagrid::FilteringError < StandardError
|
2
4
|
end
|
3
5
|
|
4
|
-
|
6
|
+
# @!visibility private
|
7
|
+
class Datagrid::Filters::BaseFilter
|
5
8
|
|
6
9
|
attr_accessor :grid_class, :options, :block, :name
|
7
10
|
|
@@ -26,7 +29,7 @@ class Datagrid::Filters::BaseFilter #:nodoc:
|
|
26
29
|
result = execute(value, scope, grid_object)
|
27
30
|
|
28
31
|
return scope unless result
|
29
|
-
if result
|
32
|
+
if result == Datagrid::Filters::DEFAULT_FILTER_BLOCK
|
30
33
|
result = default_filter(value, scope, grid_object)
|
31
34
|
end
|
32
35
|
unless grid_object.driver.match?(result)
|
@@ -1,17 +1,19 @@
|
|
1
|
-
|
1
|
+
# @!visibility private
|
2
|
+
class Datagrid::Filters::BooleanEnumFilter < Datagrid::Filters::EnumFilter
|
2
3
|
|
3
4
|
YES = "YES"
|
4
5
|
NO = "NO"
|
5
6
|
|
6
7
|
def initialize(report, attribute, options = {}, &block)
|
8
|
+
Datagrid::Utils.warn_once("Datagrid eboolean filter is deprecated in favor of xboolean filter")
|
7
9
|
options[:select] = [YES, NO].map do |key, value|
|
8
|
-
[I18n.t("datagrid.filters.eboolean.#{key.downcase}", :
|
10
|
+
[I18n.t("datagrid.filters.eboolean.#{key.downcase}", default: key.downcase.capitalize), key]
|
9
11
|
end
|
10
12
|
super(report, attribute, options, &block)
|
11
13
|
end
|
12
14
|
|
13
15
|
|
14
16
|
def checkbox_id(value)
|
15
|
-
[object_name, name, value].join('_').underscore
|
17
|
+
[object_name, name, value].join('_').underscore
|
16
18
|
end
|
17
19
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Datagrid
|
2
2
|
module Filters
|
3
|
-
|
3
|
+
# @!visibility private
|
4
|
+
module CompositeFilters
|
4
5
|
|
5
6
|
def self.included(base)
|
6
7
|
base.extend ClassMethods
|
7
8
|
base.class_eval do
|
8
|
-
|
9
9
|
end
|
10
|
-
|
11
|
-
end # self.included
|
10
|
+
end
|
12
11
|
|
12
|
+
# @!visibility private
|
13
13
|
module ClassMethods
|
14
14
|
|
15
15
|
def date_range_filters(field, from_options = {}, to_options = {})
|
@@ -41,13 +41,7 @@ module Datagrid
|
|
41
41
|
end
|
42
42
|
options
|
43
43
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
module InstanceMethods
|
47
|
-
|
48
|
-
|
49
|
-
end # InstanceMethods
|
50
|
-
|
44
|
+
end
|
51
45
|
end
|
52
46
|
end
|
53
47
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Datagrid::Filters::SelectOptions
|
2
|
-
|
3
2
|
def select(object)
|
4
3
|
select = self.options[:select]
|
5
4
|
if select.is_a?(Symbol)
|
@@ -11,6 +10,18 @@ module Datagrid::Filters::SelectOptions
|
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
13
|
+
def select_values(object)
|
14
|
+
options = select(object)
|
15
|
+
groups_used = grouped_choices?(options)
|
16
|
+
options.map do |option|
|
17
|
+
if groups_used
|
18
|
+
option[1].map {|o| option_text_and_value(o)}
|
19
|
+
else
|
20
|
+
option_text_and_value(option)
|
21
|
+
end
|
22
|
+
end.map(&:last)
|
23
|
+
end
|
24
|
+
|
14
25
|
def include_blank
|
15
26
|
unless prompt
|
16
27
|
options.has_key?(:include_blank) ?
|
@@ -21,4 +32,26 @@ module Datagrid::Filters::SelectOptions
|
|
21
32
|
def prompt
|
22
33
|
options.has_key?(:prompt) ? Datagrid::Utils.callable(options[:prompt]) : false
|
23
34
|
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
# Rails built-in method:
|
39
|
+
# https://github.com/rails/rails/blob/94e80269e36caf7b2d22a7ab68e6898d3a824122/actionview/lib/action_view/helpers/form_options_helper.rb#L789
|
40
|
+
# Code reuse is difficult, so it is easier to duplicate it
|
41
|
+
def option_text_and_value(option)
|
42
|
+
# Options are [text, value] pairs or strings used for both.
|
43
|
+
if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
|
44
|
+
option = option.reject { |e| Hash === e } if Array === option
|
45
|
+
[option.first, option.last]
|
46
|
+
else
|
47
|
+
[option, option]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Rails built-in method:
|
52
|
+
# https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/actionview/lib/action_view/helpers/tags/select.rb#L36
|
53
|
+
# Code reuse is difficult, so it is easier to duplicate it
|
54
|
+
def grouped_choices?(choices)
|
55
|
+
!choices.blank? && choices.first.respond_to?(:last) && Array === choices.first.last
|
56
|
+
end
|
24
57
|
end
|
data/lib/datagrid/filters.rb
CHANGED
@@ -31,10 +31,10 @@ module Datagrid
|
|
31
31
|
:dynamic => Filters::DynamicFilter
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
end
|
34
|
+
DEFAULT_FILTER_BLOCK = Object.new
|
36
35
|
|
37
|
-
|
36
|
+
# @!visibility private
|
37
|
+
def self.included(base)
|
38
38
|
base.extend ClassMethods
|
39
39
|
base.class_eval do
|
40
40
|
|
@@ -45,13 +45,18 @@ module Datagrid
|
|
45
45
|
|
46
46
|
end
|
47
47
|
base.send :include, InstanceMethods
|
48
|
-
end
|
48
|
+
end
|
49
49
|
|
50
50
|
module ClassMethods
|
51
51
|
|
52
52
|
# Returns filter definition object by name
|
53
53
|
def filter_by_name(attribute)
|
54
|
-
|
54
|
+
if attribute.is_a?(Datagrid::Filters::BaseFilter)
|
55
|
+
unless ancestors.include?(attribute.grid_class)
|
56
|
+
raise "#{attribute.grid_class}##{attribute.name} filter doen't belong to #{self.class}"
|
57
|
+
end
|
58
|
+
return attribute
|
59
|
+
end
|
55
60
|
self.filters.find do |filter|
|
56
61
|
filter.name == attribute.to_sym
|
57
62
|
end
|
@@ -108,7 +113,7 @@ module Datagrid
|
|
108
113
|
end
|
109
114
|
|
110
115
|
def default_filter
|
111
|
-
|
116
|
+
DEFAULT_FILTER_BLOCK
|
112
117
|
end
|
113
118
|
|
114
119
|
def inspect
|
@@ -132,11 +137,12 @@ module Datagrid
|
|
132
137
|
"#{filter.name}: #{filter.type}"
|
133
138
|
end.join(", ")
|
134
139
|
end
|
135
|
-
end
|
140
|
+
end
|
136
141
|
|
137
142
|
module InstanceMethods
|
138
143
|
|
139
|
-
|
144
|
+
# @!visibility private
|
145
|
+
def initialize(*args, &block)
|
140
146
|
self.filters_array = self.class.filters_array.clone
|
141
147
|
self.filters_array.each do |filter|
|
142
148
|
self[filter.name] = filter.default(self)
|
@@ -144,7 +150,8 @@ module Datagrid
|
|
144
150
|
super(*args, &block)
|
145
151
|
end
|
146
152
|
|
147
|
-
|
153
|
+
# @!visibility private
|
154
|
+
def assets
|
148
155
|
apply_filters(super, filters)
|
149
156
|
end
|
150
157
|
|
@@ -178,11 +185,18 @@ module Datagrid
|
|
178
185
|
# Returns select options for specific filter or filter name
|
179
186
|
# If given filter doesn't support select options raises `ArgumentError`
|
180
187
|
def select_options(filter)
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
188
|
+
find_select_filter(filter).select(self)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Sets all options as selected for a filter that has options
|
192
|
+
def select_all(filter)
|
193
|
+
filter = find_select_filter(filter)
|
194
|
+
self[filter.name] = select_values(filter)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns all values that can be set to a filter with select options
|
198
|
+
def select_values(filter)
|
199
|
+
find_select_filter(filter).select_values(self)
|
186
200
|
end
|
187
201
|
|
188
202
|
def default_filter
|
@@ -198,12 +212,21 @@ module Datagrid
|
|
198
212
|
|
199
213
|
protected
|
200
214
|
|
215
|
+
def find_select_filter(filter)
|
216
|
+
filter = filter_by_name(filter)
|
217
|
+
unless filter.class.included_modules.include?(::Datagrid::Filters::SelectOptions)
|
218
|
+
raise ::Datagrid::ArgumentError,
|
219
|
+
"#{self.class.name}##{filter.name} with type #{FILTER_TYPES.invert[filter.class].inspect} can not have select options"
|
220
|
+
end
|
221
|
+
filter
|
222
|
+
end
|
223
|
+
|
201
224
|
def apply_filters(current_scope, filters)
|
202
225
|
filters.inject(current_scope) do |result, filter|
|
203
226
|
filter.apply(self, result, filter_value(filter))
|
204
227
|
end
|
205
228
|
end
|
206
|
-
end
|
229
|
+
end
|
207
230
|
|
208
231
|
end
|
209
232
|
end
|
@@ -2,8 +2,12 @@ require "action_view"
|
|
2
2
|
|
3
3
|
module Datagrid
|
4
4
|
module FormBuilder
|
5
|
-
|
6
|
-
#
|
5
|
+
# @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
|
6
|
+
# @param options [Hash] options of rails form input helper
|
7
|
+
# @return [String] a form input html for the corresponding filter name
|
8
|
+
# * <tt>select</tt> for enum, xboolean filter types
|
9
|
+
# * <tt>check_box</tt> for boolean filter type
|
10
|
+
# * <tt>text_field</tt> for other filter types
|
7
11
|
def datagrid_filter(filter_or_attribute, options = {}, &block)
|
8
12
|
filter = datagrid_get_filter(filter_or_attribute)
|
9
13
|
options = {
|
@@ -15,7 +19,10 @@ module Datagrid
|
|
15
19
|
self.send(filter.form_builder_helper_name, filter, options, &block)
|
16
20
|
end
|
17
21
|
|
18
|
-
#
|
22
|
+
# @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
|
23
|
+
# @param text [String, nil] label text, defaults to <tt>filter.header</tt>
|
24
|
+
# @param options [Hash] options of rails <tt>label</tt> helper
|
25
|
+
# @return [String] a form label html for the corresponding filter name
|
19
26
|
def datagrid_label(filter_or_attribute, text = nil, **options, &block)
|
20
27
|
filter = datagrid_get_filter(filter_or_attribute)
|
21
28
|
label(filter.name, text || filter.header, **filter.label_options, **options, &block)
|