datagrid 0.9.3 → 1.0.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.
- data/Readme.markdown +6 -4
- data/VERSION +1 -1
- data/app/assets/stylesheets/datagrid.css.sass +132 -0
- data/app/views/datagrid/_form.html.erb +5 -2
- data/app/views/datagrid/_order_for.html.erb +2 -2
- data/app/views/datagrid/_table.html.erb +1 -1
- data/datagrid.gemspec +10 -3
- data/lib/datagrid.rb +1 -0
- data/lib/datagrid/column_names_attribute.rb +38 -7
- data/lib/datagrid/columns.rb +38 -4
- data/lib/datagrid/columns/column.rb +29 -1
- data/lib/datagrid/drivers/abstract_driver.rb +8 -0
- data/lib/datagrid/drivers/active_record.rb +29 -1
- data/lib/datagrid/drivers/array.rb +14 -2
- data/lib/datagrid/drivers/mongo_mapper.rb +8 -0
- data/lib/datagrid/drivers/mongoid.rb +9 -1
- data/lib/datagrid/filters.rb +24 -6
- data/lib/datagrid/filters/base_filter.rb +42 -14
- data/lib/datagrid/filters/boolean_enum_filter.rb +1 -1
- data/lib/datagrid/filters/dynamic_filter.rb +57 -0
- data/lib/datagrid/filters/enum_filter.rb +4 -21
- data/lib/datagrid/filters/select_options.rb +26 -0
- data/lib/datagrid/form_builder.rb +41 -8
- data/lib/datagrid/helper.rb +2 -1
- data/lib/datagrid/i18n.rb +0 -0
- data/lib/datagrid/locale/en.yml +28 -0
- data/lib/datagrid/ordering.rb +33 -19
- data/lib/datagrid/utils.rb +8 -9
- data/spec/datagrid/column_names_attribute_spec.rb +44 -1
- data/spec/datagrid/columns_spec.rb +16 -0
- data/spec/datagrid/filters/dynamic_filter_spec.rb +37 -0
- data/spec/datagrid/filters/integer_filter_spec.rb +18 -0
- data/spec/datagrid/filters/string_filter_spec.rb +25 -0
- data/spec/datagrid/filters_spec.rb +15 -1
- data/spec/datagrid/form_builder_spec.rb +83 -0
- data/spec/datagrid/helper_spec.rb +1 -0
- data/spec/datagrid/ordering_spec.rb +41 -1
- data/spec/datagrid/utils_spec.rb +7 -2
- metadata +11 -4
@@ -66,6 +66,14 @@ module Datagrid
|
|
66
66
|
raise NotImplementedError
|
67
67
|
end
|
68
68
|
|
69
|
+
def contains(scope, field, value)
|
70
|
+
raise NotImplementedError
|
71
|
+
end
|
72
|
+
|
73
|
+
def column_names(scope)
|
74
|
+
raise NotImplementedError
|
75
|
+
end
|
76
|
+
|
69
77
|
protected
|
70
78
|
def timestamp_class?(klass)
|
71
79
|
TIMESTAMP_CLASSES.include?(klass)
|
@@ -40,6 +40,10 @@ module Datagrid
|
|
40
40
|
scope.reorder(order).reverse_order
|
41
41
|
end
|
42
42
|
|
43
|
+
def reverse_order(scope)
|
44
|
+
scope.reverse_order
|
45
|
+
end
|
46
|
+
|
43
47
|
def default_order(scope, column_name)
|
44
48
|
has_column?(scope, column_name) ? [scope.table_name, column_name].join(".") : nil
|
45
49
|
end
|
@@ -58,8 +62,22 @@ module Datagrid
|
|
58
62
|
false
|
59
63
|
end
|
60
64
|
|
65
|
+
def column_names(scope)
|
66
|
+
scope.column_names
|
67
|
+
end
|
68
|
+
|
61
69
|
def is_timestamp?(scope, field)
|
62
|
-
|
70
|
+
column_type(scope, field) == :datetime
|
71
|
+
end
|
72
|
+
|
73
|
+
def contains(scope, field, value)
|
74
|
+
if column_type(scope, field) == :string
|
75
|
+
field = prefix_table_name(scope, field)
|
76
|
+
scope.where("#{field} #{contains_predicate} ?", "%#{value}%")
|
77
|
+
else
|
78
|
+
# dont support contains operation by non-varchar column now
|
79
|
+
scope.where("1=0")
|
80
|
+
end
|
63
81
|
end
|
64
82
|
|
65
83
|
protected
|
@@ -67,6 +85,16 @@ module Datagrid
|
|
67
85
|
def prefix_table_name(scope, field)
|
68
86
|
has_column?(scope, field) ? [scope.table_name, field].join(".") : field
|
69
87
|
end
|
88
|
+
|
89
|
+
def contains_predicate
|
90
|
+
defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) &&
|
91
|
+
::ActiveRecord::Base.connection.is_a?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) ?
|
92
|
+
'ilike' : 'like'
|
93
|
+
end
|
94
|
+
|
95
|
+
def column_type(scope, field)
|
96
|
+
has_column?(scope, field) ? scope.columns_hash[field.to_s].type : nil
|
97
|
+
end
|
70
98
|
end
|
71
99
|
end
|
72
100
|
end
|
@@ -34,13 +34,15 @@ module Datagrid
|
|
34
34
|
|
35
35
|
def greater_equal(scope, field, value)
|
36
36
|
scope.select do |object|
|
37
|
-
object.send(field)
|
37
|
+
compare_value = object.send(field)
|
38
|
+
compare_value.respond_to?(:>=) && compare_value >= value
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
41
42
|
def less_equal(scope, field, value)
|
42
43
|
scope.select do |object|
|
43
|
-
object.send(field)
|
44
|
+
compare_value = object.send(field)
|
45
|
+
compare_value.respond_to?(:<=) && compare_value <= value
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
@@ -52,6 +54,16 @@ module Datagrid
|
|
52
54
|
has_column?(scope, column_name) &&
|
53
55
|
timestamp_class?(scope.first.send(column_name).class)
|
54
56
|
end
|
57
|
+
|
58
|
+
def contains(scope, field, value)
|
59
|
+
scope.select do |object|
|
60
|
+
object.send(field).to_s.include?(value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def column_names(scope)
|
65
|
+
[]
|
66
|
+
end
|
55
67
|
end
|
56
68
|
end
|
57
69
|
end
|
@@ -47,6 +47,14 @@ module Datagrid
|
|
47
47
|
#TODO implement the support
|
48
48
|
false
|
49
49
|
end
|
50
|
+
|
51
|
+
def contains(scope, field, value)
|
52
|
+
scope(field => Regexp.compile(Regexp.escape(value)))
|
53
|
+
end
|
54
|
+
|
55
|
+
def column_names(scope)
|
56
|
+
[] # TODO: implement support
|
57
|
+
end
|
50
58
|
end
|
51
59
|
end
|
52
60
|
end
|
@@ -43,13 +43,21 @@ module Datagrid
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def has_column?(scope, column_name)
|
46
|
-
|
46
|
+
column_names(scope).include?(column_name.to_s)
|
47
47
|
end
|
48
48
|
|
49
49
|
def is_timestamp?(scope, column_name)
|
50
50
|
has_column?(scope, column_name) &&
|
51
51
|
timestamp_class?(to_scope(scope).klass.fields[column_name.to_s].type)
|
52
52
|
end
|
53
|
+
|
54
|
+
def contains(scope, field, value)
|
55
|
+
scope(field => Regexp.compile(Regexp.escape(value)))
|
56
|
+
end
|
57
|
+
|
58
|
+
def column_names(scope)
|
59
|
+
to_scope(scope).klass.fields.keys
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
55
63
|
end
|
data/lib/datagrid/filters.rb
CHANGED
@@ -13,6 +13,7 @@ module Datagrid
|
|
13
13
|
require "datagrid/filters/composite_filters"
|
14
14
|
require "datagrid/filters/string_filter"
|
15
15
|
require "datagrid/filters/float_filter"
|
16
|
+
require "datagrid/filters/dynamic_filter"
|
16
17
|
|
17
18
|
FILTER_TYPES = {
|
18
19
|
:date => Filters::DateFilter,
|
@@ -23,6 +24,7 @@ module Datagrid
|
|
23
24
|
:integer => Filters::IntegerFilter,
|
24
25
|
:enum => Filters::EnumFilter,
|
25
26
|
:float => Filters::FloatFilter,
|
27
|
+
:dynamic => Filters::DynamicFilter
|
26
28
|
}
|
27
29
|
|
28
30
|
def self.included(base) #:nodoc:
|
@@ -72,7 +74,7 @@ module Datagrid
|
|
72
74
|
# * <tt>:dummy</tt> - if true, this filter will not be applied automatically
|
73
75
|
# and will just be displayed in form. In case you may want to apply it manually.
|
74
76
|
#
|
75
|
-
# See: https://github.com/bogdan/datagrid/wiki/
|
77
|
+
# See: https://github.com/bogdan/datagrid/wiki/Filters for examples
|
76
78
|
def filter(name, type = :default, options = {}, &block)
|
77
79
|
if type.is_a?(Hash)
|
78
80
|
options = type
|
@@ -111,11 +113,7 @@ module Datagrid
|
|
111
113
|
end
|
112
114
|
|
113
115
|
def assets # :nodoc:
|
114
|
-
|
115
|
-
self.class.filters.each do |filter|
|
116
|
-
result = filter.apply(self, result, filter_value(filter))
|
117
|
-
end
|
118
|
-
result
|
116
|
+
apply_filters(super, self.class.filters)
|
119
117
|
end
|
120
118
|
|
121
119
|
# Returns all defined filters Array
|
@@ -128,11 +126,31 @@ module Datagrid
|
|
128
126
|
self[filter.name]
|
129
127
|
end
|
130
128
|
|
129
|
+
# Returns string representation of filter value
|
130
|
+
def filter_value_as_string(filter)
|
131
|
+
value = filter_value(filter)
|
132
|
+
value = value.is_a?(Array) ? value.join(filter.separator) : value.to_s
|
133
|
+
value.blank? ? nil : value
|
134
|
+
end
|
135
|
+
|
131
136
|
# Returns filter object with the given name
|
132
137
|
def filter_by_name(name)
|
133
138
|
self.class.filter_by_name(name)
|
134
139
|
end
|
135
140
|
|
141
|
+
# Returns assets filtered only by specified filters
|
142
|
+
# Allows partial filtering
|
143
|
+
def filter_by(*filters)
|
144
|
+
apply_filters(scope, filters.map{|f| filter_by_name(f)})
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
|
149
|
+
def apply_filters(current_scope, filters)
|
150
|
+
filters.inject(current_scope) do |result, filter|
|
151
|
+
filter.apply(self, result, filter_value(filter))
|
152
|
+
end
|
153
|
+
end
|
136
154
|
end # InstanceMethods
|
137
155
|
|
138
156
|
end
|
@@ -16,14 +16,15 @@ class Datagrid::Filters::BaseFilter
|
|
16
16
|
raise NotImplementedError, "#parse(value) suppose to be overwritten"
|
17
17
|
end
|
18
18
|
|
19
|
+
|
20
|
+
def unapplicable_value?(value)
|
21
|
+
value.nil? ? !allow_nil? : value.blank? && !allow_blank?
|
22
|
+
end
|
23
|
+
|
19
24
|
def apply(grid_object, scope, value)
|
20
|
-
if value
|
21
|
-
return scope if !allow_nil?
|
22
|
-
else
|
23
|
-
return scope if value.blank? && !allow_blank?
|
24
|
-
end
|
25
|
+
return scope if unapplicable_value?(value)
|
25
26
|
|
26
|
-
result = execute(value, scope, grid_object
|
27
|
+
result = execute(value, scope, grid_object)
|
27
28
|
return scope unless result
|
28
29
|
unless grid_object.driver.match?(result)
|
29
30
|
raise Datagrid::FilteringError, "Can not apply #{name.inspect} filter: result #{result.inspect} no longer match #{grid_object.driver.class}."
|
@@ -32,14 +33,20 @@ class Datagrid::Filters::BaseFilter
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def parse_values(value)
|
35
|
-
if
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
if multiple?
|
37
|
+
normalize_multiple_value(value).map do |v|
|
38
|
+
parse(v)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
if value.is_a?(Array)
|
42
|
+
raise Datagrid::ArgumentError, "#{grid_class}##{name} filter can not accept Array argument. Use :multiple option."
|
43
|
+
end
|
44
|
+
parse(value)
|
41
45
|
end
|
42
|
-
|
46
|
+
end
|
47
|
+
|
48
|
+
def separator
|
49
|
+
options[:multiple].is_a?(String) ? options[:multiple] : default_separator
|
43
50
|
end
|
44
51
|
|
45
52
|
def header
|
@@ -53,6 +60,11 @@ class Datagrid::Filters::BaseFilter
|
|
53
60
|
end
|
54
61
|
|
55
62
|
def multiple
|
63
|
+
Datagrid::Utils.warn_once("Filter#multiple method is deprecated. Use Filter#multiple? instead")
|
64
|
+
multiple?
|
65
|
+
end
|
66
|
+
|
67
|
+
def multiple?
|
56
68
|
self.options[:multiple]
|
57
69
|
end
|
58
70
|
|
@@ -102,7 +114,7 @@ class Datagrid::Filters::BaseFilter
|
|
102
114
|
driver.where(scope, name, value)
|
103
115
|
end
|
104
116
|
|
105
|
-
def execute(value, scope, grid_object
|
117
|
+
def execute(value, scope, grid_object)
|
106
118
|
if block.arity == 1
|
107
119
|
scope.instance_exec(value, &block)
|
108
120
|
else
|
@@ -110,5 +122,21 @@ class Datagrid::Filters::BaseFilter
|
|
110
122
|
end
|
111
123
|
end
|
112
124
|
|
125
|
+
def normalize_multiple_value(value)
|
126
|
+
case value
|
127
|
+
when String
|
128
|
+
#TODO: write tests and doc
|
129
|
+
value.split(separator)
|
130
|
+
when Array
|
131
|
+
value
|
132
|
+
else
|
133
|
+
Array.wrap(value)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def default_separator
|
138
|
+
','
|
139
|
+
end
|
140
|
+
|
113
141
|
end
|
114
142
|
|
@@ -5,7 +5,7 @@ class Datagrid::Filters::BooleanEnumFilter < Datagrid::Filters::EnumFilter
|
|
5
5
|
|
6
6
|
def initialize(report, attribute, options = {}, &block)
|
7
7
|
options[:select] = [YES, NO].map do |key, value|
|
8
|
-
[I18n.t("datagrid.filters.eboolean.#{key.downcase}"
|
8
|
+
[I18n.t("datagrid.filters.eboolean.#{key.downcase}"), key]
|
9
9
|
end
|
10
10
|
super(report, attribute, options, &block)
|
11
11
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "datagrid/filters/select_options"
|
2
|
+
|
3
|
+
class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
|
4
|
+
|
5
|
+
include Datagrid::Filters::SelectOptions
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
options[:multiple] = true
|
10
|
+
options[:select] ||= default_select
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse(value)
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def unapplicable_value?(filter)
|
18
|
+
field, operation, value = filter
|
19
|
+
field.blank? || operation.blank? || super(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_filter_where(driver, scope, filter)
|
23
|
+
field, operation, value = filter
|
24
|
+
driver.to_scope(scope)
|
25
|
+
case operation
|
26
|
+
when '='
|
27
|
+
driver.where(scope, field, value)
|
28
|
+
when '=~'
|
29
|
+
driver.contains(scope, field, value)
|
30
|
+
when '>='
|
31
|
+
driver.greater_equal(scope, field, value)
|
32
|
+
when '<='
|
33
|
+
driver.less_equal(scope, field, value)
|
34
|
+
else
|
35
|
+
raise "unknown operation: #{operation.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def operations_select
|
40
|
+
%w(= =~ >= <=).map do |operation|
|
41
|
+
I18n.t(operation, :scope => "datagrid.filters.dynamic.operations")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def default_select
|
48
|
+
proc {|grid|
|
49
|
+
grid.driver.column_names(grid.scope).map do |name|
|
50
|
+
# Mongodb/Rails problem:
|
51
|
+
# '_id'.humanize returns ''
|
52
|
+
[name.gsub(/^_/, '').humanize.strip, name]
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
|
+
require "datagrid/filters/select_options"
|
2
|
+
|
1
3
|
class Datagrid::Filters::EnumFilter < Datagrid::Filters::BaseFilter
|
2
4
|
|
5
|
+
include Datagrid::Filters::SelectOptions
|
6
|
+
|
3
7
|
def initialize(*args)
|
4
8
|
super(*args)
|
5
9
|
raise Datagrid::ConfigurationError, ":select option not specified" unless options[:select]
|
@@ -10,27 +14,6 @@ class Datagrid::Filters::EnumFilter < Datagrid::Filters::BaseFilter
|
|
10
14
|
value
|
11
15
|
end
|
12
16
|
|
13
|
-
def select(object = nil)
|
14
|
-
select = self.options[:select]
|
15
|
-
if select.is_a?(Symbol)
|
16
|
-
object.send(select)
|
17
|
-
elsif select.respond_to?(:call)
|
18
|
-
Datagrid::Utils.apply_args(object, &select)
|
19
|
-
else
|
20
|
-
select
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def include_blank
|
25
|
-
unless self.prompt
|
26
|
-
self.options.has_key?(:include_blank) ? options[:include_blank] : !multiple
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def prompt
|
31
|
-
self.options.has_key?(:prompt) ? options[:prompt] : false
|
32
|
-
end
|
33
|
-
|
34
17
|
def strict
|
35
18
|
self.options[:strict]
|
36
19
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Datagrid::Filters::SelectOptions
|
2
|
+
|
3
|
+
def select(object = nil)
|
4
|
+
#unless object
|
5
|
+
#Datagrid::Utils.warn_once("#{self.class.name}#select without argument is deprecated")
|
6
|
+
#end
|
7
|
+
select = self.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
|
15
|
+
end
|
16
|
+
|
17
|
+
def include_blank
|
18
|
+
unless prompt
|
19
|
+
options.has_key?(:include_blank) ? options[:include_blank] : !multiple?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def prompt
|
24
|
+
options.has_key?(:prompt) ? options[:prompt] : false
|
25
|
+
end
|
26
|
+
end
|
@@ -3,12 +3,14 @@ require "action_view"
|
|
3
3
|
module Datagrid
|
4
4
|
module FormBuilder
|
5
5
|
|
6
|
+
# Returns a form input html for the corresponding filter name
|
6
7
|
def datagrid_filter(filter_or_attribute, options = {})
|
7
8
|
filter = datagrid_get_filter(filter_or_attribute)
|
8
|
-
options =
|
9
|
+
options = add_html_classes(options, filter.name, datagrid_filter_html_class(filter))
|
9
10
|
self.send(filter.form_builder_helper_name, filter, options)
|
10
11
|
end
|
11
12
|
|
13
|
+
# Returns a form label html for the corresponding filter name
|
12
14
|
def datagrid_label(filter_or_attribute, options = {})
|
13
15
|
filter = datagrid_get_filter(filter_or_attribute)
|
14
16
|
self.label(filter.name, filter.header, options)
|
@@ -28,25 +30,52 @@ module Datagrid
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def datagrid_default_filter(attribute_or_filter, options = {})
|
31
|
-
|
33
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
34
|
+
value = object.filter_value_as_string(filter)
|
35
|
+
text_field filter.name, options.merge(:value => object.filter_value_as_string(filter))
|
32
36
|
end
|
33
37
|
|
34
38
|
def datagrid_enum_filter(attribute_or_filter, options = {})
|
35
39
|
filter = datagrid_get_filter(attribute_or_filter)
|
36
|
-
if !options.has_key?(:multiple) && filter.multiple
|
40
|
+
if !options.has_key?(:multiple) && filter.multiple?
|
37
41
|
options[:multiple] = true
|
38
42
|
end
|
39
|
-
select filter.name, filter.select(object) || [], {:include_blank => filter.include_blank, :prompt => filter.prompt}, options
|
43
|
+
select filter.name, filter.select(object) || [], {:include_blank => filter.include_blank, :prompt => filter.prompt, :include_hidden => false}, options
|
40
44
|
end
|
41
45
|
|
42
46
|
def datagrid_integer_filter(attribute_or_filter, options = {})
|
43
47
|
filter = datagrid_get_filter(attribute_or_filter)
|
44
|
-
if filter.multiple && self.object[filter.name].blank?
|
48
|
+
if filter.multiple? && self.object[filter.name].blank?
|
45
49
|
options[:value] = ""
|
46
50
|
end
|
47
51
|
datagrid_range_filter(:integer, filter, options)
|
48
52
|
end
|
49
53
|
|
54
|
+
def datagrid_dynamic_filter(attribute_or_filter, options = {})
|
55
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
56
|
+
input_name = "#{object_name}[#{filter.name.to_s}][]"
|
57
|
+
field, operation, value = object.filter_value(filter)
|
58
|
+
options = options.merge(:name => input_name)
|
59
|
+
field_input = select(
|
60
|
+
filter.name,
|
61
|
+
filter.select(object) || [],
|
62
|
+
{
|
63
|
+
:include_blank => filter.include_blank,
|
64
|
+
:prompt => filter.prompt,
|
65
|
+
:include_hidden => false,
|
66
|
+
:selected => field
|
67
|
+
},
|
68
|
+
add_html_classes(options, "field")
|
69
|
+
)
|
70
|
+
operation_input = select(
|
71
|
+
filter.name, filter.operations_select,
|
72
|
+
{:include_blank => false, :include_hidden => false, :prompt => false, :selected => operation },
|
73
|
+
add_html_classes(options, "operation")
|
74
|
+
)
|
75
|
+
value_input = text_field(filter.name, add_html_classes(options, "value").merge(:value => value))
|
76
|
+
[field_input, operation_input, value_input].join("\n").html_safe
|
77
|
+
end
|
78
|
+
|
50
79
|
def datagrid_range_filter(type, attribute_or_filter, options = {})
|
51
80
|
filter = datagrid_get_filter(attribute_or_filter)
|
52
81
|
if filter.range?
|
@@ -58,18 +87,18 @@ module Datagrid
|
|
58
87
|
# 2 inputs: "from date" and "to date" to specify a range
|
59
88
|
[
|
60
89
|
text_field(filter.name, from_options),
|
61
|
-
I18n.t("datagrid.
|
90
|
+
I18n.t("datagrid.filters.#{type}.range_separator"),
|
62
91
|
text_field(filter.name, to_options)
|
63
92
|
].join.html_safe
|
64
93
|
else
|
65
|
-
|
94
|
+
datagrid_default_filter(filter, options)
|
66
95
|
end
|
67
96
|
end
|
68
97
|
|
69
98
|
|
70
99
|
def datagrid_range_filter_options(object, filter, type, options)
|
71
100
|
type_method_map = {:from => :first, :to => :last}
|
72
|
-
options =
|
101
|
+
options = add_html_classes(options, type)
|
73
102
|
options[:value] = filter.format(object[filter.name].try(type_method_map[type]))
|
74
103
|
# In case of datagrid ranged filter
|
75
104
|
# from and to input will have same id
|
@@ -110,6 +139,10 @@ module Datagrid
|
|
110
139
|
filter.class.to_s.demodulize.underscore
|
111
140
|
end
|
112
141
|
|
142
|
+
def add_html_classes(options, *classes)
|
143
|
+
Datagrid::Utils.add_html_classes(options, *classes)
|
144
|
+
end
|
145
|
+
|
113
146
|
class Error < StandardError
|
114
147
|
end
|
115
148
|
end
|