datagrid 1.8.1 → 2.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -7
- data/{Readme.markdown → README.md} +46 -29
- data/app/assets/stylesheets/datagrid.css +145 -0
- data/app/views/datagrid/_enum_checkboxes.html.erb +5 -3
- data/app/views/datagrid/_form.html.erb +4 -5
- data/app/views/datagrid/_head.html.erb +26 -3
- data/app/views/datagrid/_range_filter.html.erb +5 -3
- data/app/views/datagrid/_row.html.erb +12 -1
- data/app/views/datagrid/_table.html.erb +4 -4
- data/datagrid.gemspec +8 -8
- data/lib/datagrid/active_model.rb +9 -17
- data/lib/datagrid/base.rb +39 -0
- data/lib/datagrid/column_names_attribute.rb +12 -12
- data/lib/datagrid/columns/column.rb +155 -133
- data/lib/datagrid/columns.rb +495 -282
- data/lib/datagrid/configuration.rb +23 -10
- data/lib/datagrid/core.rb +184 -150
- data/lib/datagrid/deprecated_object.rb +20 -0
- data/lib/datagrid/drivers/abstract_driver.rb +13 -25
- data/lib/datagrid/drivers/active_record.rb +24 -26
- data/lib/datagrid/drivers/array.rb +26 -17
- data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
- data/lib/datagrid/drivers/mongoid.rb +16 -18
- data/lib/datagrid/drivers/sequel.rb +14 -19
- data/lib/datagrid/drivers.rb +2 -1
- data/lib/datagrid/engine.rb +11 -3
- data/lib/datagrid/filters/base_filter.rb +166 -142
- data/lib/datagrid/filters/boolean_filter.rb +19 -5
- data/lib/datagrid/filters/date_filter.rb +33 -35
- data/lib/datagrid/filters/date_time_filter.rb +24 -16
- data/lib/datagrid/filters/default_filter.rb +9 -3
- data/lib/datagrid/filters/dynamic_filter.rb +151 -105
- data/lib/datagrid/filters/enum_filter.rb +43 -19
- data/lib/datagrid/filters/extended_boolean_filter.rb +39 -27
- data/lib/datagrid/filters/float_filter.rb +16 -5
- data/lib/datagrid/filters/integer_filter.rb +21 -10
- data/lib/datagrid/filters/ranged_filter.rb +66 -45
- data/lib/datagrid/filters/select_options.rb +58 -49
- data/lib/datagrid/filters/string_filter.rb +9 -4
- data/lib/datagrid/filters.rb +234 -106
- data/lib/datagrid/form_builder.rb +116 -128
- data/lib/datagrid/generators/scaffold.rb +185 -0
- data/lib/datagrid/generators/views.rb +20 -0
- data/lib/datagrid/helper.rb +397 -22
- data/lib/datagrid/ordering.rb +81 -87
- data/lib/datagrid/rspec.rb +8 -12
- data/lib/datagrid/utils.rb +42 -38
- data/lib/datagrid/version.rb +3 -1
- data/lib/datagrid.rb +18 -28
- data/templates/base.rb.erb +33 -7
- data/templates/grid.rb.erb +1 -1
- metadata +18 -19
- data/app/assets/stylesheets/datagrid.sass +0 -134
- data/lib/datagrid/filters/composite_filters.rb +0 -49
- data/lib/datagrid/renderer.rb +0 -157
- data/lib/datagrid/scaffold.rb +0 -129
- data/lib/tasks/datagrid_tasks.rake +0 -15
- data/templates/controller.rb.erb +0 -6
- data/templates/index.html.erb +0 -5
@@ -1,57 +1,66 @@
|
|
1
|
-
|
2
|
-
def select(object)
|
3
|
-
select = self.options[:select]
|
4
|
-
if select.is_a?(Symbol)
|
5
|
-
object.send(select)
|
6
|
-
elsif select.respond_to?(:call)
|
7
|
-
Datagrid::Utils.apply_args(object, &select)
|
8
|
-
else
|
9
|
-
select
|
10
|
-
end
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
12
2
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
3
|
+
module Datagrid
|
4
|
+
module Filters
|
5
|
+
module SelectOptions
|
6
|
+
def select(object)
|
7
|
+
select = options[:select]
|
8
|
+
if select.is_a?(Symbol)
|
9
|
+
object.send(select)
|
10
|
+
elsif select.respond_to?(:call)
|
11
|
+
Datagrid::Utils.apply_args(object, &select)
|
12
|
+
else
|
13
|
+
select
|
14
|
+
end
|
21
15
|
end
|
22
|
-
end.map(&:last)
|
23
|
-
end
|
24
16
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
def select_values(object)
|
18
|
+
options = select(object)
|
19
|
+
groups_used = grouped_choices?(options)
|
20
|
+
options.map do |option|
|
21
|
+
if groups_used
|
22
|
+
option[1].map { |o| option_text_and_value(o) }
|
23
|
+
else
|
24
|
+
option_text_and_value(option)
|
25
|
+
end
|
26
|
+
end.map(&:last)
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
29
|
+
def include_blank
|
30
|
+
return if prompt
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
32
|
+
if options.key?(:include_blank)
|
33
|
+
Datagrid::Utils.callable(options[:include_blank])
|
34
|
+
else
|
35
|
+
!multiple?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def prompt
|
40
|
+
options.key?(:prompt) ? Datagrid::Utils.callable(options[:prompt]) : false
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
# Rails built-in method:
|
46
|
+
# https://github.com/rails/rails/blob/94e80269e36caf7b2d22a7ab68e6898d3a824122/actionview/lib/action_view/helpers/form_options_helper.rb#L789
|
47
|
+
# Code reuse is difficult, so it is easier to duplicate it
|
48
|
+
def option_text_and_value(option)
|
49
|
+
# Options are [text, value] pairs or strings used for both.
|
50
|
+
if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
|
51
|
+
option = option.reject { |e| e.is_a?(Hash) } if option.is_a?(Array)
|
52
|
+
[option.first, option.last]
|
53
|
+
else
|
54
|
+
[option, option]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Rails built-in method:
|
59
|
+
# https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/actionview/lib/action_view/helpers/tags/select.rb#L36
|
60
|
+
# Code reuse is difficult, so it is easier to duplicate it
|
61
|
+
def grouped_choices?(choices)
|
62
|
+
!choices.blank? && choices.first.respond_to?(:last) && choices.first.last.is_a?(Array)
|
63
|
+
end
|
64
|
+
end
|
56
65
|
end
|
57
66
|
end
|
@@ -1,8 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
module Datagrid
|
4
|
+
module Filters
|
5
|
+
class StringFilter < Datagrid::Filters::BaseFilter
|
6
|
+
include Datagrid::Filters::RangedFilter
|
4
7
|
|
5
|
-
|
6
|
-
|
8
|
+
def parse(value)
|
9
|
+
value&.to_s
|
10
|
+
end
|
11
|
+
end
|
7
12
|
end
|
8
13
|
end
|
data/lib/datagrid/filters.rb
CHANGED
@@ -1,8 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/class/attribute"
|
2
4
|
|
3
5
|
module Datagrid
|
6
|
+
# Defines the accessible attribute that is used to filter
|
7
|
+
# the scope by the specified value with specified code.
|
8
|
+
#
|
9
|
+
# class UserGrid < ApplicationGrid
|
10
|
+
# scope do
|
11
|
+
# User
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# filter(:name)
|
15
|
+
# filter(:posts_count, :integer) do |value|
|
16
|
+
# self.where(["posts_count >= ?", value])
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Each filter becomes a grid attribute.
|
21
|
+
#
|
22
|
+
# To create a grid displaying all users with the name 'John' who have more than zero posts:
|
23
|
+
#
|
24
|
+
# grid = UserGrid.new(posts_count: 1, name: "John")
|
25
|
+
# grid.assets # SELECT * FROM users WHERE users.posts_count > 1 AND name = 'John'
|
26
|
+
#
|
27
|
+
# # Filter Block
|
28
|
+
#
|
29
|
+
# Filter blocks should always return a chainable ORM object (e.g., `ActiveRecord::Relation`) rather than an `Array`.
|
30
|
+
#
|
31
|
+
# Filter blocks should have at least one argument representing the value assigned to the grid object attribute:
|
32
|
+
#
|
33
|
+
# filter(:name, :string) # { |value| where(name: value) }
|
34
|
+
#
|
35
|
+
# You can pass additional arguments:
|
36
|
+
#
|
37
|
+
# filter(:name, :string) { |value, scope| scope.where("name ilike ?", "%#{value}%") }
|
38
|
+
# filter(:name, :string) do |value, scope, grid|
|
39
|
+
# scope.where("name #{grid.predicate} ?", "%#{value}%")
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # Filter Types
|
43
|
+
#
|
44
|
+
# Filters perform automatic type conversion. Supported filter types include:
|
45
|
+
#
|
46
|
+
# - `default`
|
47
|
+
# - `date`
|
48
|
+
# - `datetime`
|
49
|
+
# - `enum`
|
50
|
+
# - `boolean`
|
51
|
+
# - `xboolean`
|
52
|
+
# - `integer`
|
53
|
+
# - `float`
|
54
|
+
# - `string`
|
55
|
+
# - `dynamic`
|
56
|
+
#
|
57
|
+
# ## Default
|
58
|
+
#
|
59
|
+
# `:default` - Leaves the value as is.
|
60
|
+
#
|
61
|
+
# ## Date
|
62
|
+
#
|
63
|
+
# `:date` - Converts value to a date. Supports the `:range` option to accept date ranges.
|
64
|
+
#
|
65
|
+
# filter(:created_at, :date, range: true, default: proc { 1.month.ago.to_date..Date.today })
|
66
|
+
#
|
67
|
+
# ## Datetime
|
68
|
+
#
|
69
|
+
# `:datetime` - Converts value to a timestamp. Supports the `:range` option to accept time ranges.
|
70
|
+
#
|
71
|
+
# filter(:created_at, :datetime, range: true, default: proc { 1.hour.ago..Time.now })
|
72
|
+
#
|
73
|
+
# ## Enum
|
74
|
+
#
|
75
|
+
# `:enum` - For collection selection with options like `:select` and `:multiple`.
|
76
|
+
#
|
77
|
+
# filter(:user_type, :enum, select: ['Admin', 'Customer', 'Manager'])
|
78
|
+
# filter(:category_id, :enum, select: proc { Category.all.map { |c| [c.name, c.id] } }, multiple: true)
|
79
|
+
#
|
80
|
+
# ## Boolean
|
81
|
+
#
|
82
|
+
# `:boolean` - Converts value to `true` or `false`.
|
83
|
+
#
|
84
|
+
# ## Xboolean
|
85
|
+
#
|
86
|
+
# `:xboolean` - Subtype of `enum` filter that provides "Yes", "No", and "Any" options.
|
87
|
+
#
|
88
|
+
# filter(:active, :xboolean)
|
89
|
+
#
|
90
|
+
# ## Integer
|
91
|
+
#
|
92
|
+
# `:integer` - Converts value to an integer. Supports the `:range` option.
|
93
|
+
#
|
94
|
+
# filter(:posts_count, :integer, range: true, default: (1..nil))
|
95
|
+
#
|
96
|
+
# ## String
|
97
|
+
#
|
98
|
+
# `:string` - Converts value to a string.
|
99
|
+
#
|
100
|
+
# filter(:email, :string)
|
101
|
+
#
|
102
|
+
# ## Dynamic
|
103
|
+
#
|
104
|
+
# Provides a builder for dynamic SQL conditions.
|
105
|
+
#
|
106
|
+
# filter(:condition1, :dynamic)
|
107
|
+
# filter(:condition2, :dynamic)
|
108
|
+
# UsersGrid.new(condition1: [:name, "=~", "John"], condition2: [:posts_count, ">=", 1])
|
109
|
+
# UsersGrid.assets # SELECT * FROM users WHERE name like '%John%' and posts_count >= 1
|
110
|
+
#
|
111
|
+
# # Filter Options
|
112
|
+
#
|
113
|
+
# Options that can be passed to any filter:
|
114
|
+
#
|
115
|
+
# - `:header` - Human-readable filter name (default: generated from the filter name).
|
116
|
+
# - `:default` - Default filter value (default: `nil`).
|
117
|
+
# - `:multiple` - Allows multiple values (default: `false`).
|
118
|
+
# - `:allow_nil` - Whether to apply the filter when the value is `nil` (default: `false`).
|
119
|
+
# - `:allow_blank` - Whether to apply the filter when the value is blank (default: `false`).
|
120
|
+
#
|
121
|
+
# Example:
|
122
|
+
#
|
123
|
+
# filter(:id, :integer, header: "Identifier")
|
124
|
+
# filter(:created_at, :date, range: true, default: proc { 1.month.ago.to_date..Date.today })
|
125
|
+
#
|
126
|
+
# # Localization
|
127
|
+
#
|
128
|
+
# Filter labels can be localized or specified via the `:header` option:
|
129
|
+
#
|
130
|
+
# filter(:created_at, :date, header: "Creation date")
|
131
|
+
# filter(:created_at, :date, header: proc { I18n.t("creation_date") })
|
4
132
|
module Filters
|
5
|
-
|
6
133
|
require "datagrid/filters/base_filter"
|
7
134
|
require "datagrid/filters/enum_filter"
|
8
135
|
require "datagrid/filters/extended_boolean_filter"
|
@@ -11,51 +138,47 @@ module Datagrid
|
|
11
138
|
require "datagrid/filters/date_time_filter"
|
12
139
|
require "datagrid/filters/default_filter"
|
13
140
|
require "datagrid/filters/integer_filter"
|
14
|
-
require "datagrid/filters/composite_filters"
|
15
141
|
require "datagrid/filters/string_filter"
|
16
142
|
require "datagrid/filters/float_filter"
|
17
143
|
require "datagrid/filters/dynamic_filter"
|
18
144
|
|
145
|
+
# @!visibility private
|
19
146
|
FILTER_TYPES = {
|
20
147
|
date: Filters::DateFilter,
|
21
148
|
datetime: Filters::DateTimeFilter,
|
22
149
|
string: Filters::StringFilter,
|
23
150
|
default: Filters::DefaultFilter,
|
24
|
-
xboolean: Filters::ExtendedBooleanFilter
|
25
|
-
boolean: Filters::BooleanFilter
|
151
|
+
xboolean: Filters::ExtendedBooleanFilter,
|
152
|
+
boolean: Filters::BooleanFilter,
|
26
153
|
integer: Filters::IntegerFilter,
|
27
154
|
enum: Filters::EnumFilter,
|
28
155
|
float: Filters::FloatFilter,
|
29
|
-
dynamic: Filters::DynamicFilter
|
30
|
-
}
|
31
|
-
|
32
|
-
DEFAULT_FILTER_BLOCK = Object.new
|
156
|
+
dynamic: Filters::DynamicFilter,
|
157
|
+
}.freeze
|
33
158
|
|
34
159
|
# @!visibility private
|
35
|
-
|
36
|
-
base.extend ClassMethods
|
37
|
-
base.class_eval do
|
160
|
+
DEFAULT_FILTER_BLOCK = Object.new
|
38
161
|
|
39
|
-
|
40
|
-
include Datagrid::Filters::CompositeFilters
|
41
|
-
class_attribute :filters_array
|
42
|
-
self.filters_array = []
|
162
|
+
extend ActiveSupport::Concern
|
43
163
|
|
44
|
-
|
45
|
-
|
164
|
+
# @!visibility private
|
165
|
+
included do
|
166
|
+
include Datagrid::Core
|
167
|
+
class_attribute :filters_array, default: []
|
46
168
|
end
|
47
169
|
|
170
|
+
# Grid class methods related to filters
|
48
171
|
module ClassMethods
|
49
|
-
|
50
|
-
# Returns filter definition object by name
|
172
|
+
# @return [Datagrid::Filters::BaseFilter, nil] filter definition object by name
|
51
173
|
def filter_by_name(attribute)
|
52
174
|
if attribute.is_a?(Datagrid::Filters::BaseFilter)
|
53
175
|
unless ancestors.include?(attribute.grid_class)
|
54
|
-
raise "#{attribute.grid_class}##{attribute.name} filter doen't belong to #{self.class}"
|
176
|
+
raise ArgumentError, "#{attribute.grid_class}##{attribute.name} filter doen't belong to #{self.class}"
|
55
177
|
end
|
178
|
+
|
56
179
|
return attribute
|
57
180
|
end
|
58
|
-
|
181
|
+
filters.find do |filter|
|
59
182
|
filter.name == attribute.to_sym
|
60
183
|
end
|
61
184
|
end
|
@@ -64,18 +187,20 @@ module Datagrid
|
|
64
187
|
# This method automatically generates <tt>attr_accessor</tt> for filter name
|
65
188
|
# and adds it to the list of datagrid attributes.
|
66
189
|
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
190
|
+
# @param [Symbol] name filter name
|
191
|
+
# @param [Symbol] type filter type that defines type case and GUI representation of a filter
|
192
|
+
# @param [Hash] options hash of options
|
193
|
+
# @param [Proc] block proc to apply the filter
|
194
|
+
# @return [Datagrid::Filters::BaseFilter] Filter definition object
|
195
|
+
# @see https://github.com/bogdan/datagrid/wiki/Filters
|
73
196
|
#
|
74
197
|
# Available options:
|
75
198
|
#
|
76
199
|
# * <tt>:header</tt> - determines the header of the filter
|
77
|
-
# * <tt>:default</tt> - the default filter value.
|
78
|
-
#
|
200
|
+
# * <tt>:default</tt> - the default filter value.
|
201
|
+
# Can be a <tt>Proc</tt> in case default should be recalculated.
|
202
|
+
# * <tt>:range</tt> - if true, filter can accept two values that are treated
|
203
|
+
# as a range that will be used for filtering.
|
79
204
|
# Not all of the filter types support this option. Here are the list of types that do:
|
80
205
|
# <tt>:integer</tt>, <tt>:float</tt>, <tt>:date</tt>, <tt>:datetime</tt>, <tt>:string</tt>
|
81
206
|
# * <tt>:multiple</tt> - if true multiple values can be assigned to this filter.
|
@@ -84,9 +209,9 @@ module Datagrid
|
|
84
209
|
# * <tt>:allow_nil</tt> - determines if the value can be nil
|
85
210
|
# * <tt>:allow_blank</tt> - determines if the value can be blank
|
86
211
|
# * <tt>:before</tt> - determines the position of this filter,
|
87
|
-
# by adding it before the filter passed here (when using
|
212
|
+
# by adding it before the filter passed here (when using datagrid_form_with helper)
|
88
213
|
# * <tt>:after</tt> - determines the position of this filter,
|
89
|
-
# by adding it after the filter passed here (when using
|
214
|
+
# by adding it after the filter passed here (when using datagrid_form_with helper)
|
90
215
|
# * <tt>:dummy</tt> - if true, this filter will not be applied automatically
|
91
216
|
# and will be just displayed in form. In case you may want to apply it manually.
|
92
217
|
# * <tt>:if</tt> - specify the condition when the filter can be dislayed and used.
|
@@ -96,29 +221,31 @@ module Datagrid
|
|
96
221
|
# * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
|
97
222
|
# Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
|
98
223
|
# * <tt>:label_options</tt> - options passed when rendering html label tag attributes
|
99
|
-
#
|
100
|
-
# See: https://github.com/bogdan/datagrid/wiki/Filters for examples
|
101
224
|
def filter(name, type = :default, **options, &block)
|
102
225
|
klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
|
103
226
|
raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
|
104
227
|
|
105
228
|
position = Datagrid::Utils.extract_position_from_options(filters_array, options)
|
106
|
-
filter = klass.new(self, name, options, &block)
|
229
|
+
filter = klass.new(self, name, **options, &block)
|
107
230
|
filters_array.insert(position, filter)
|
108
231
|
|
109
232
|
datagrid_attribute(name) do |value|
|
110
233
|
filter.parse_values(value)
|
111
234
|
end
|
235
|
+
filter
|
112
236
|
end
|
113
237
|
|
238
|
+
# @!visibility private
|
114
239
|
def default_filter
|
115
240
|
DEFAULT_FILTER_BLOCK
|
116
241
|
end
|
117
242
|
|
243
|
+
# @!visibility private
|
118
244
|
def inspect
|
119
245
|
"#{super}(#{filters_inspection})"
|
120
246
|
end
|
121
247
|
|
248
|
+
# @return [Array<Datagrid::Filters::BaseFilter>] all defined filters
|
122
249
|
def filters
|
123
250
|
filters_array
|
124
251
|
end
|
@@ -126,106 +253,107 @@ module Datagrid
|
|
126
253
|
protected
|
127
254
|
|
128
255
|
def inherited(child_class)
|
129
|
-
super
|
130
|
-
child_class.filters_array =
|
256
|
+
super
|
257
|
+
child_class.filters_array = filters_array.clone
|
131
258
|
end
|
132
259
|
|
133
260
|
def filters_inspection
|
134
261
|
return "no filters" if filters.empty?
|
262
|
+
|
135
263
|
filters.map do |filter|
|
136
264
|
"#{filter.name}: #{filter.type}"
|
137
265
|
end.join(", ")
|
138
266
|
end
|
139
267
|
end
|
140
268
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
self.
|
147
|
-
self[filter.name] = filter.default(self)
|
148
|
-
end
|
149
|
-
super(*args, &block)
|
269
|
+
# @!visibility private
|
270
|
+
def initialize(...)
|
271
|
+
self.filters_array = self.class.filters_array.clone
|
272
|
+
filters_array.each do |filter|
|
273
|
+
value = filter.default(self)
|
274
|
+
self[filter.name] = value unless value.nil?
|
150
275
|
end
|
276
|
+
super
|
277
|
+
end
|
151
278
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
279
|
+
# @!visibility private
|
280
|
+
def assets
|
281
|
+
apply_filters(super, filters)
|
282
|
+
end
|
156
283
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
284
|
+
# @return [Object] filter value for given filter definition
|
285
|
+
def filter_value(filter)
|
286
|
+
self[filter.name]
|
287
|
+
end
|
161
288
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
289
|
+
# @return [String] string representation of filter value
|
290
|
+
def filter_value_as_string(name)
|
291
|
+
filter = filter_by_name(name)
|
292
|
+
value = filter_value(filter)
|
293
|
+
if value.is_a?(Array)
|
294
|
+
value.map { |v| filter.format(v) }.join(filter.separator)
|
295
|
+
else
|
296
|
+
filter.format(value)
|
171
297
|
end
|
298
|
+
end
|
172
299
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
300
|
+
# @return [Datagrid::Filters::BaseFilter, nil] filter object with the given name
|
301
|
+
def filter_by_name(name)
|
302
|
+
self.class.filter_by_name(name)
|
303
|
+
end
|
177
304
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
end
|
305
|
+
# @return [Array<Object>] assets filtered only by specified filters
|
306
|
+
def filter_by(*filters)
|
307
|
+
apply_filters(scope, filters.map { |f| filter_by_name(f) })
|
308
|
+
end
|
183
309
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
310
|
+
# @return [Array] the select options for the filter
|
311
|
+
# @raise [ArgumentError] if the filter doesn't support select options
|
312
|
+
def select_options(filter)
|
313
|
+
find_select_filter(filter).select(self)
|
314
|
+
end
|
189
315
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
316
|
+
# @return [void] sets all options as selected for a filter that has options
|
317
|
+
def select_all(filter)
|
318
|
+
filter = find_select_filter(filter)
|
319
|
+
self[filter.name] = select_values(filter)
|
320
|
+
end
|
195
321
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
322
|
+
# @return [Array] all possible values for the filter
|
323
|
+
def select_values(filter)
|
324
|
+
find_select_filter(filter).select_values(self)
|
325
|
+
end
|
200
326
|
|
201
|
-
|
202
|
-
|
327
|
+
# @return [Array<Datagrid::Filters::BaseFilter>] all currently enabled filters
|
328
|
+
def filters
|
329
|
+
self.class.filters.select do |filter|
|
330
|
+
filter.enabled?(self)
|
203
331
|
end
|
332
|
+
end
|
204
333
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
210
|
-
end
|
334
|
+
# @!visibility private
|
335
|
+
def default_filter
|
336
|
+
self.class.default_filter
|
337
|
+
end
|
211
338
|
|
212
|
-
|
339
|
+
protected
|
213
340
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
341
|
+
def find_select_filter(filter)
|
342
|
+
filter = filter_by_name(filter)
|
343
|
+
unless filter.class.included_modules.include?(::Datagrid::Filters::SelectOptions)
|
344
|
+
type = FILTER_TYPES.invert[filter.class].inspect
|
345
|
+
raise(
|
346
|
+
::Datagrid::ArgumentError,
|
347
|
+
"#{self.class.name}##{filter.name} with type #{type} can not have select options",
|
348
|
+
)
|
221
349
|
end
|
350
|
+
filter
|
351
|
+
end
|
222
352
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
end
|
353
|
+
def apply_filters(current_scope, filters)
|
354
|
+
filters.inject(current_scope) do |result, filter|
|
355
|
+
filter.apply(self, result, filter_value(filter))
|
227
356
|
end
|
228
357
|
end
|
229
|
-
|
230
358
|
end
|
231
359
|
end
|