datagrid 1.8.2 → 2.0.0.pre.alpha
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 +11 -1
- data/{Readme.markdown → README.md} +44 -27
- 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 -4
- 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 +6 -6
- data/lib/datagrid/active_model.rb +9 -17
- data/lib/datagrid/base.rb +39 -0
- data/lib/datagrid/column_names_attribute.rb +9 -11
- data/lib/datagrid/columns/column.rb +155 -133
- data/lib/datagrid/columns.rb +254 -45
- data/lib/datagrid/configuration.rb +23 -10
- data/lib/datagrid/core.rb +89 -54
- data/lib/datagrid/deprecated_object.rb +20 -0
- data/lib/datagrid/drivers/abstract_driver.rb +12 -23
- data/lib/datagrid/drivers/active_record.rb +24 -26
- data/lib/datagrid/drivers/array.rb +22 -14
- data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
- data/lib/datagrid/drivers/mongoid.rb +15 -17
- 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 -30
- 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 +190 -57
- 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 +26 -29
- data/lib/datagrid/rspec.rb +6 -10
- data/lib/datagrid/utils.rb +37 -30
- data/lib/datagrid/version.rb +3 -1
- data/lib/datagrid.rb +18 -28
- data/templates/base.rb.erb +6 -4
- data/templates/grid.rb.erb +1 -1
- metadata +15 -16
- 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,49 +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, default: []
|
162
|
+
extend ActiveSupport::Concern
|
42
163
|
|
43
|
-
|
164
|
+
# @!visibility private
|
165
|
+
included do
|
166
|
+
include Datagrid::Core
|
167
|
+
class_attribute :filters_array, default: []
|
44
168
|
end
|
45
169
|
|
170
|
+
# Grid class methods related to filters
|
46
171
|
module ClassMethods
|
47
|
-
|
48
|
-
# Returns filter definition object by name
|
172
|
+
# @return [Datagrid::Filters::BaseFilter, nil] filter definition object by name
|
49
173
|
def filter_by_name(attribute)
|
50
174
|
if attribute.is_a?(Datagrid::Filters::BaseFilter)
|
51
175
|
unless ancestors.include?(attribute.grid_class)
|
52
|
-
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}"
|
53
177
|
end
|
178
|
+
|
54
179
|
return attribute
|
55
180
|
end
|
56
|
-
|
181
|
+
filters.find do |filter|
|
57
182
|
filter.name == attribute.to_sym
|
58
183
|
end
|
59
184
|
end
|
@@ -62,18 +187,20 @@ module Datagrid
|
|
62
187
|
# This method automatically generates <tt>attr_accessor</tt> for filter name
|
63
188
|
# and adds it to the list of datagrid attributes.
|
64
189
|
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
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
|
71
196
|
#
|
72
197
|
# Available options:
|
73
198
|
#
|
74
199
|
# * <tt>:header</tt> - determines the header of the filter
|
75
|
-
# * <tt>:default</tt> - the default filter value.
|
76
|
-
#
|
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.
|
77
204
|
# Not all of the filter types support this option. Here are the list of types that do:
|
78
205
|
# <tt>:integer</tt>, <tt>:float</tt>, <tt>:date</tt>, <tt>:datetime</tt>, <tt>:string</tt>
|
79
206
|
# * <tt>:multiple</tt> - if true multiple values can be assigned to this filter.
|
@@ -82,9 +209,9 @@ module Datagrid
|
|
82
209
|
# * <tt>:allow_nil</tt> - determines if the value can be nil
|
83
210
|
# * <tt>:allow_blank</tt> - determines if the value can be blank
|
84
211
|
# * <tt>:before</tt> - determines the position of this filter,
|
85
|
-
# 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)
|
86
213
|
# * <tt>:after</tt> - determines the position of this filter,
|
87
|
-
# 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)
|
88
215
|
# * <tt>:dummy</tt> - if true, this filter will not be applied automatically
|
89
216
|
# and will be just displayed in form. In case you may want to apply it manually.
|
90
217
|
# * <tt>:if</tt> - specify the condition when the filter can be dislayed and used.
|
@@ -94,29 +221,31 @@ module Datagrid
|
|
94
221
|
# * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
|
95
222
|
# Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
|
96
223
|
# * <tt>:label_options</tt> - options passed when rendering html label tag attributes
|
97
|
-
#
|
98
|
-
# See: https://github.com/bogdan/datagrid/wiki/Filters for examples
|
99
224
|
def filter(name, type = :default, **options, &block)
|
100
225
|
klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
|
101
226
|
raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
|
102
227
|
|
103
228
|
position = Datagrid::Utils.extract_position_from_options(filters_array, options)
|
104
|
-
filter = klass.new(self, name, options, &block)
|
229
|
+
filter = klass.new(self, name, **options, &block)
|
105
230
|
filters_array.insert(position, filter)
|
106
231
|
|
107
232
|
datagrid_attribute(name) do |value|
|
108
233
|
filter.parse_values(value)
|
109
234
|
end
|
235
|
+
filter
|
110
236
|
end
|
111
237
|
|
238
|
+
# @!visibility private
|
112
239
|
def default_filter
|
113
240
|
DEFAULT_FILTER_BLOCK
|
114
241
|
end
|
115
242
|
|
243
|
+
# @!visibility private
|
116
244
|
def inspect
|
117
245
|
"#{super}(#{filters_inspection})"
|
118
246
|
end
|
119
247
|
|
248
|
+
# @return [Array<Datagrid::Filters::BaseFilter>] all defined filters
|
120
249
|
def filters
|
121
250
|
filters_array
|
122
251
|
end
|
@@ -124,26 +253,27 @@ module Datagrid
|
|
124
253
|
protected
|
125
254
|
|
126
255
|
def inherited(child_class)
|
127
|
-
super
|
128
|
-
child_class.filters_array =
|
256
|
+
super
|
257
|
+
child_class.filters_array = filters_array.clone
|
129
258
|
end
|
130
259
|
|
131
260
|
def filters_inspection
|
132
261
|
return "no filters" if filters.empty?
|
262
|
+
|
133
263
|
filters.map do |filter|
|
134
264
|
"#{filter.name}: #{filter.type}"
|
135
265
|
end.join(", ")
|
136
266
|
end
|
137
267
|
end
|
138
268
|
|
139
|
-
|
140
269
|
# @!visibility private
|
141
|
-
def initialize(
|
270
|
+
def initialize(...)
|
142
271
|
self.filters_array = self.class.filters_array.clone
|
143
|
-
|
144
|
-
|
272
|
+
filters_array.each do |filter|
|
273
|
+
value = filter.default(self)
|
274
|
+
self[filter.name] = value unless value.nil?
|
145
275
|
end
|
146
|
-
super
|
276
|
+
super
|
147
277
|
end
|
148
278
|
|
149
279
|
# @!visibility private
|
@@ -151,68 +281,71 @@ module Datagrid
|
|
151
281
|
apply_filters(super, filters)
|
152
282
|
end
|
153
283
|
|
154
|
-
#
|
284
|
+
# @return [Object] filter value for given filter definition
|
155
285
|
def filter_value(filter)
|
156
286
|
self[filter.name]
|
157
287
|
end
|
158
288
|
|
159
|
-
#
|
289
|
+
# @return [String] string representation of filter value
|
160
290
|
def filter_value_as_string(name)
|
161
291
|
filter = filter_by_name(name)
|
162
292
|
value = filter_value(filter)
|
163
293
|
if value.is_a?(Array)
|
164
|
-
value.map {|v| filter.format(v) }.join(filter.separator)
|
294
|
+
value.map { |v| filter.format(v) }.join(filter.separator)
|
165
295
|
else
|
166
296
|
filter.format(value)
|
167
297
|
end
|
168
298
|
end
|
169
299
|
|
170
|
-
#
|
300
|
+
# @return [Datagrid::Filters::BaseFilter, nil] filter object with the given name
|
171
301
|
def filter_by_name(name)
|
172
302
|
self.class.filter_by_name(name)
|
173
303
|
end
|
174
304
|
|
175
|
-
#
|
176
|
-
# Allows partial filtering
|
305
|
+
# @return [Array<Object>] assets filtered only by specified filters
|
177
306
|
def filter_by(*filters)
|
178
|
-
apply_filters(scope, filters.map{|f| filter_by_name(f)})
|
307
|
+
apply_filters(scope, filters.map { |f| filter_by_name(f) })
|
179
308
|
end
|
180
309
|
|
181
|
-
#
|
182
|
-
#
|
310
|
+
# @return [Array] the select options for the filter
|
311
|
+
# @raise [ArgumentError] if the filter doesn't support select options
|
183
312
|
def select_options(filter)
|
184
313
|
find_select_filter(filter).select(self)
|
185
314
|
end
|
186
315
|
|
187
|
-
#
|
316
|
+
# @return [void] sets all options as selected for a filter that has options
|
188
317
|
def select_all(filter)
|
189
318
|
filter = find_select_filter(filter)
|
190
319
|
self[filter.name] = select_values(filter)
|
191
320
|
end
|
192
321
|
|
193
|
-
#
|
322
|
+
# @return [Array] all possible values for the filter
|
194
323
|
def select_values(filter)
|
195
324
|
find_select_filter(filter).select_values(self)
|
196
325
|
end
|
197
326
|
|
198
|
-
|
199
|
-
self.class.default_filter
|
200
|
-
end
|
201
|
-
|
202
|
-
# Returns all currently enabled filters
|
327
|
+
# @return [Array<Datagrid::Filters::BaseFilter>] all currently enabled filters
|
203
328
|
def filters
|
204
329
|
self.class.filters.select do |filter|
|
205
330
|
filter.enabled?(self)
|
206
331
|
end
|
207
332
|
end
|
208
333
|
|
334
|
+
# @!visibility private
|
335
|
+
def default_filter
|
336
|
+
self.class.default_filter
|
337
|
+
end
|
338
|
+
|
209
339
|
protected
|
210
340
|
|
211
341
|
def find_select_filter(filter)
|
212
342
|
filter = filter_by_name(filter)
|
213
343
|
unless filter.class.included_modules.include?(::Datagrid::Filters::SelectOptions)
|
214
|
-
|
215
|
-
|
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
|
+
)
|
216
349
|
end
|
217
350
|
filter
|
218
351
|
end
|