datagrid 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -1
- data/Readme.markdown +7 -5
- data/VERSION +1 -1
- data/datagrid.gemspec +5 -5
- data/lib/datagrid/columns.rb +22 -11
- data/lib/datagrid/columns/column.rb +11 -4
- data/lib/datagrid/core.rb +1 -1
- data/lib/datagrid/drivers/abstract_driver.rb +4 -0
- data/lib/datagrid/drivers/active_record.rb +2 -2
- data/lib/datagrid/filters.rb +0 -13
- data/lib/datagrid/filters/base_filter.rb +26 -6
- data/lib/datagrid/filters/date_filter.rb +15 -1
- data/lib/datagrid/filters/integer_filter.rb +6 -0
- data/lib/datagrid/filters/ranged_filter.rb +55 -0
- data/lib/datagrid/form_builder.rb +32 -14
- data/lib/datagrid/helper.rb +2 -2
- data/lib/datagrid/ordering.rb +37 -7
- data/lib/datagrid/renderer.rb +14 -5
- data/lib/datagrid/utils.rb +16 -0
- data/spec/datagrid/columns_spec.rb +19 -7
- data/spec/datagrid/filters/date_filter_spec.rb +96 -0
- data/spec/datagrid/filters/integer_filter_spec.rb +96 -0
- data/spec/datagrid/filters_spec.rb +2 -1
- data/spec/datagrid/form_builder_spec.rb +92 -0
- data/spec/datagrid/helper_spec.rb +89 -5
- data/spec/datagrid/ordering_spec.rb +20 -10
- data/spec/spec_helper.rb +0 -1
- data/spec/support/active_record.rb +2 -0
- data/spec/support/simple_report.rb +6 -0
- metadata +6 -19
data/Gemfile
CHANGED
data/Readme.markdown
CHANGED
@@ -21,6 +21,8 @@ Ruby library that helps you to build and represent table-like data with:
|
|
21
21
|
[Datagrid DEMO application](http://datagrid.heroku.com) is available live!
|
22
22
|
[Demo source code](https://github.com/bogdan/datagrid-demo).
|
23
23
|
|
24
|
+
<img src="http://datagrid.heroku.com/datagrid_demo_screenshot.png" style="margin: 7px; border: 1px solid black">
|
25
|
+
|
24
26
|
### Example
|
25
27
|
|
26
28
|
In order to create a grid:
|
@@ -38,7 +40,7 @@ class SimpleReport
|
|
38
40
|
filter(:disabled, :eboolean)
|
39
41
|
filter(:confirmed, :boolean)
|
40
42
|
filter(:group_id, :integer, :multiple => true)
|
41
|
-
|
43
|
+
filter(:logins_count, :integer, :range => true)
|
42
44
|
filter(:group_name, :string, :header => "Group") do |value|
|
43
45
|
self.joins(:group).where(:groups => {:name => value})
|
44
46
|
end
|
@@ -67,11 +69,11 @@ report = SimpleReport.new(
|
|
67
69
|
report.assets # => Array of User instances:
|
68
70
|
# SELECT * FROM users WHERE users.group_id in (1,2) AND users.logins_count >= 1 AND users.category = 'first' ORDER BY groups.name DESC
|
69
71
|
|
70
|
-
report.header # => ["
|
72
|
+
report.header # => ["Name", "Group", "Activated"]
|
71
73
|
report.rows # => [
|
72
|
-
# ["Steve", "Spammers",
|
73
|
-
# [ "John", "Spoilers",
|
74
|
-
# ["Berry", "Good people",
|
74
|
+
# ["Steve", "Spammers", false],
|
75
|
+
# [ "John", "Spoilers", false],
|
76
|
+
# ["Berry", "Good people", true]
|
75
77
|
# ]
|
76
78
|
report.data # => [ header, *rows]
|
77
79
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
data/datagrid.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "datagrid"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.7.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bogdan Gusiev"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-12-15"
|
13
13
|
s.description = "This allows you to easily build datagrid aka data tables with sortable columns and filters"
|
14
14
|
s.email = "agresso@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
|
|
48
48
|
"lib/datagrid/filters/enum_filter.rb",
|
49
49
|
"lib/datagrid/filters/float_filter.rb",
|
50
50
|
"lib/datagrid/filters/integer_filter.rb",
|
51
|
+
"lib/datagrid/filters/ranged_filter.rb",
|
51
52
|
"lib/datagrid/filters/string_filter.rb",
|
52
53
|
"lib/datagrid/form_builder.rb",
|
53
54
|
"lib/datagrid/helper.rb",
|
@@ -64,8 +65,10 @@ Gem::Specification.new do |s|
|
|
64
65
|
"spec/datagrid/drivers/mongoid_spec.rb",
|
65
66
|
"spec/datagrid/filters/boolean_enum_filter_spec.rb",
|
66
67
|
"spec/datagrid/filters/composite_filters_spec.rb",
|
68
|
+
"spec/datagrid/filters/date_filter_spec.rb",
|
67
69
|
"spec/datagrid/filters/enum_filter_spec.rb",
|
68
70
|
"spec/datagrid/filters/float_filter_spec.rb",
|
71
|
+
"spec/datagrid/filters/integer_filter_spec.rb",
|
69
72
|
"spec/datagrid/filters_spec.rb",
|
70
73
|
"spec/datagrid/form_builder_spec.rb",
|
71
74
|
"spec/datagrid/helper_spec.rb",
|
@@ -96,7 +99,6 @@ Gem::Specification.new do |s|
|
|
96
99
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
97
100
|
s.add_development_dependency(%q<debugger>, [">= 0"])
|
98
101
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
99
|
-
s.add_development_dependency(%q<accept_values_for>, [">= 0"])
|
100
102
|
s.add_development_dependency(%q<nokogiri>, [">= 0"])
|
101
103
|
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
102
104
|
s.add_development_dependency(%q<mongoid>, ["= 2.2.2"])
|
@@ -111,7 +113,6 @@ Gem::Specification.new do |s|
|
|
111
113
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
112
114
|
s.add_dependency(%q<debugger>, [">= 0"])
|
113
115
|
s.add_dependency(%q<rspec>, [">= 0"])
|
114
|
-
s.add_dependency(%q<accept_values_for>, [">= 0"])
|
115
116
|
s.add_dependency(%q<nokogiri>, [">= 0"])
|
116
117
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
117
118
|
s.add_dependency(%q<mongoid>, ["= 2.2.2"])
|
@@ -127,7 +128,6 @@ Gem::Specification.new do |s|
|
|
127
128
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
128
129
|
s.add_dependency(%q<debugger>, [">= 0"])
|
129
130
|
s.add_dependency(%q<rspec>, [">= 0"])
|
130
|
-
s.add_dependency(%q<accept_values_for>, [">= 0"])
|
131
131
|
s.add_dependency(%q<nokogiri>, [">= 0"])
|
132
132
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
133
133
|
s.add_dependency(%q<mongoid>, ["= 2.2.2"])
|
data/lib/datagrid/columns.rb
CHANGED
@@ -20,6 +20,13 @@ module Datagrid
|
|
20
20
|
|
21
21
|
module ClassMethods
|
22
22
|
|
23
|
+
# Returns a list of columns defined.
|
24
|
+
# You can limit the output with only columns you need like:
|
25
|
+
#
|
26
|
+
# grid.columns(:id, :name)
|
27
|
+
#
|
28
|
+
# Supported options:
|
29
|
+
# * :data - if true returns only non-html columns. Default: false.
|
23
30
|
def columns(*args)
|
24
31
|
options = args.extract_options!
|
25
32
|
args.compact!
|
@@ -29,6 +36,7 @@ module Datagrid
|
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
39
|
+
# Defines new datagrid column
|
32
40
|
def column(name, options = {}, &block)
|
33
41
|
check_scope_defined!("Scope should be defined before columns")
|
34
42
|
block ||= lambda do |model|
|
@@ -53,13 +61,13 @@ module Datagrid
|
|
53
61
|
module InstanceMethods
|
54
62
|
|
55
63
|
# Returns <tt>Array</tt> of human readable column names. See also "Localization" section
|
56
|
-
def header
|
57
|
-
|
64
|
+
def header(*column_names)
|
65
|
+
data_columns(*column_names).map(&:header)
|
58
66
|
end
|
59
67
|
|
60
68
|
# Returns <tt>Array</tt> column values for given asset
|
61
|
-
def row_for(asset)
|
62
|
-
|
69
|
+
def row_for(asset, *column_names)
|
70
|
+
data_columns(*column_names).map do |column|
|
63
71
|
column.value(asset, self)
|
64
72
|
end
|
65
73
|
end
|
@@ -74,9 +82,10 @@ module Datagrid
|
|
74
82
|
end
|
75
83
|
|
76
84
|
# Returns Array of Arrays with data for each row in datagrid assets without header.
|
77
|
-
def rows
|
85
|
+
def rows(*column_names)
|
86
|
+
#TODO: find in batches
|
78
87
|
self.assets.map do |asset|
|
79
|
-
self.row_for(asset)
|
88
|
+
self.row_for(asset, *column_names)
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
@@ -92,7 +101,8 @@ module Datagrid
|
|
92
101
|
end
|
93
102
|
end
|
94
103
|
|
95
|
-
def to_csv(
|
104
|
+
def to_csv(*column_names)
|
105
|
+
options = columns.extract_options!
|
96
106
|
klass = if RUBY_VERSION >= "1.9"
|
97
107
|
require 'csv'
|
98
108
|
CSV
|
@@ -101,9 +111,9 @@ module Datagrid
|
|
101
111
|
FasterCSV
|
102
112
|
end
|
103
113
|
klass.generate(
|
104
|
-
{:headers => self.header, :write_headers => true}.merge(options)
|
114
|
+
{:headers => self.header(*column_names), :write_headers => true}.merge(options)
|
105
115
|
) do |csv|
|
106
|
-
self.rows.each do |row|
|
116
|
+
self.rows(*column_names).each do |row|
|
107
117
|
csv << row
|
108
118
|
end
|
109
119
|
end
|
@@ -113,8 +123,9 @@ module Datagrid
|
|
113
123
|
self.class.columns(*args)
|
114
124
|
end
|
115
125
|
|
116
|
-
def data_columns
|
117
|
-
|
126
|
+
def data_columns(*names)
|
127
|
+
names << {:data => true}
|
128
|
+
self.columns(*names)
|
118
129
|
end
|
119
130
|
|
120
131
|
def column_by_name(name)
|
@@ -1,12 +1,19 @@
|
|
1
1
|
class Datagrid::Columns::Column
|
2
2
|
|
3
|
-
attr_accessor :grid, :options, :block, :name
|
3
|
+
attr_accessor :grid, :options, :block, :name, :html_block
|
4
4
|
|
5
5
|
def initialize(grid, name, options = {}, &block)
|
6
6
|
self.grid = grid
|
7
7
|
self.name = name.to_sym
|
8
8
|
self.options = options
|
9
|
-
|
9
|
+
if options[:html] == true
|
10
|
+
self.html_block = block
|
11
|
+
else
|
12
|
+
if options[:html].is_a? Proc
|
13
|
+
self.html_block = options[:html]
|
14
|
+
end
|
15
|
+
self.block = block
|
16
|
+
end
|
10
17
|
if format
|
11
18
|
::Datagrid::Utils.warn_once(":format column option is deprecated. Use :url or :html option instead.")
|
12
19
|
end
|
@@ -53,11 +60,11 @@ class Datagrid::Columns::Column
|
|
53
60
|
end
|
54
61
|
|
55
62
|
def html?
|
56
|
-
|
63
|
+
self.html_block != nil
|
57
64
|
end
|
58
65
|
|
59
66
|
def data?
|
60
|
-
|
67
|
+
self.block != nil
|
61
68
|
end
|
62
69
|
|
63
70
|
end
|
data/lib/datagrid/core.rb
CHANGED
@@ -34,11 +34,11 @@ module Datagrid
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def greater_equal(scope, field, value)
|
37
|
-
scope.where(["#{field} >= ?", value])
|
37
|
+
scope.where(["#{scope.table_name}.#{field} >= ?", value])
|
38
38
|
end
|
39
39
|
|
40
40
|
def less_equal(scope, field, value)
|
41
|
-
scope.where(["#{field} <= ?", value])
|
41
|
+
scope.where(["#{scope.table_name}.#{field} <= ?", value])
|
42
42
|
end
|
43
43
|
|
44
44
|
def has_column?(scope, column_name)
|
data/lib/datagrid/filters.rb
CHANGED
@@ -53,7 +53,6 @@ module Datagrid
|
|
53
53
|
klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
|
54
54
|
raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
|
55
55
|
|
56
|
-
block ||= default_filter(attribute)
|
57
56
|
|
58
57
|
filter = klass.new(self, attribute, options, &block)
|
59
58
|
self.filters << filter
|
@@ -65,18 +64,6 @@ module Datagrid
|
|
65
64
|
end
|
66
65
|
|
67
66
|
protected
|
68
|
-
def default_filter(attribute)
|
69
|
-
check_scope_defined!("Scope should be defined before filters")
|
70
|
-
if !driver.has_column?(scope, attribute) && driver.to_scope(scope).respond_to?(attribute)
|
71
|
-
lambda do |value, scope, grid|
|
72
|
-
grid.driver.to_scope(scope).send(attribute, value)
|
73
|
-
end
|
74
|
-
else
|
75
|
-
lambda do |value, scope, grid|
|
76
|
-
grid.driver.where(scope, attribute => value)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
67
|
|
81
68
|
def inherited(child_class)
|
82
69
|
super(child_class)
|
@@ -3,11 +3,11 @@ class Datagrid::Filters::BaseFilter
|
|
3
3
|
|
4
4
|
attr_accessor :grid, :options, :block, :name
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
self.grid =
|
6
|
+
def initialize(grid_class, name, options = {}, &block)
|
7
|
+
self.grid = grid_class
|
8
8
|
self.name = name
|
9
9
|
self.options = options
|
10
|
-
self.block = block
|
10
|
+
self.block = block || default_filter_block
|
11
11
|
end
|
12
12
|
|
13
13
|
def format(value)
|
@@ -32,11 +32,11 @@ class Datagrid::Filters::BaseFilter
|
|
32
32
|
|
33
33
|
def format_values(value)
|
34
34
|
if !self.multiple && value.is_a?(Array)
|
35
|
-
raise Datagrid::ArgumentError, "#{grid
|
35
|
+
raise Datagrid::ArgumentError, "#{grid}##{name} filter can not accept Array argument. Use :multiple option."
|
36
36
|
end
|
37
37
|
values = Array.wrap(value)
|
38
|
-
values.map! do |
|
39
|
-
self.format(
|
38
|
+
values.map! do |v|
|
39
|
+
self.format(v)
|
40
40
|
end
|
41
41
|
self.multiple ? values : values.first
|
42
42
|
end
|
@@ -71,5 +71,25 @@ class Datagrid::Filters::BaseFilter
|
|
71
71
|
:"datagrid_#{self.to_s.demodulize.underscore}"
|
72
72
|
end
|
73
73
|
|
74
|
+
def default_filter_block
|
75
|
+
filter = self
|
76
|
+
lambda do |value, scope, grid|
|
77
|
+
filter.default_filter(value, scope, grid)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def default_filter(value, scope, grid)
|
82
|
+
driver = grid.driver
|
83
|
+
if !driver.has_column?(scope, name) && driver.to_scope(scope).respond_to?(name)
|
84
|
+
driver.to_scope(scope).send(name, value)
|
85
|
+
else
|
86
|
+
default_filter_where(driver, scope, value)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_filter_where(driver, scope, value)
|
91
|
+
driver.where(scope, name => value)
|
92
|
+
end
|
93
|
+
|
74
94
|
end
|
75
95
|
|
@@ -1,12 +1,26 @@
|
|
1
|
+
require "datagrid/filters/ranged_filter"
|
2
|
+
|
1
3
|
class Datagrid::Filters::DateFilter < Datagrid::Filters::BaseFilter
|
2
|
-
|
4
|
+
|
5
|
+
include RangedFilter
|
6
|
+
|
7
|
+
def apply(grid_object, scope, value)
|
8
|
+
if value.is_a?(Range)
|
9
|
+
value = value.first.beginning_of_day..value.last.end_of_day
|
10
|
+
end
|
11
|
+
super(grid_object, scope, value)
|
12
|
+
end
|
13
|
+
|
3
14
|
def format(value)
|
4
15
|
return nil if value.blank?
|
16
|
+
return value if value.is_a?(Range)
|
5
17
|
return value.to_date if value.respond_to?(:to_date)
|
6
18
|
return value unless value.is_a?(String)
|
19
|
+
#TODO: more smart date normalizer
|
7
20
|
Date.parse(value)
|
8
21
|
rescue ArgumentError
|
9
22
|
nil
|
10
23
|
end
|
24
|
+
|
11
25
|
end
|
12
26
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RangedFilter
|
2
|
+
|
3
|
+
|
4
|
+
def initialize(grid, name, options, &block)
|
5
|
+
super(grid, name, options, &block)
|
6
|
+
if range?
|
7
|
+
options[:multiple] = true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def format_values(value)
|
12
|
+
result = super(value)
|
13
|
+
if range?
|
14
|
+
if result.is_a?(Array)
|
15
|
+
case result.size
|
16
|
+
when 0
|
17
|
+
nil
|
18
|
+
when 1
|
19
|
+
result.first
|
20
|
+
when 2
|
21
|
+
result
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Can not create a date range from array of more than two: #{result.inspect}"
|
24
|
+
end
|
25
|
+
else
|
26
|
+
# Simulate single point range
|
27
|
+
result..result
|
28
|
+
end
|
29
|
+
|
30
|
+
else
|
31
|
+
result
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def range?
|
36
|
+
options[:range]
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_filter_where(driver, scope, value)
|
40
|
+
if range? && value.is_a?(Array)
|
41
|
+
left, right = value
|
42
|
+
if left
|
43
|
+
scope = driver.greater_equal(scope, name, left)
|
44
|
+
end
|
45
|
+
if right
|
46
|
+
scope = driver.less_equal(scope, name, right)
|
47
|
+
end
|
48
|
+
scope
|
49
|
+
else
|
50
|
+
super(driver, scope, value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
@@ -4,15 +4,13 @@ module Datagrid
|
|
4
4
|
module FormBuilder
|
5
5
|
|
6
6
|
def datagrid_filter(filter_or_attribute, options = {})
|
7
|
-
filter =
|
8
|
-
options
|
9
|
-
options[:class] += " " unless options[:class].blank?
|
10
|
-
options[:class] += "#{filter.name} #{datagrid_filter_html_class(filter)}"
|
7
|
+
filter = datagrid_get_filter(filter_or_attribute)
|
8
|
+
options = Datagrid::Utils.add_html_classes(options, filter.name, datagrid_filter_html_class(filter))
|
11
9
|
self.send(filter.form_builder_helper_name, filter, options)
|
12
10
|
end
|
13
11
|
|
14
12
|
def datagrid_label(filter_or_attribute, options = {})
|
15
|
-
filter =
|
13
|
+
filter = datagrid_get_filter(filter_or_attribute)
|
16
14
|
self.label(filter.name, filter.header, options)
|
17
15
|
end
|
18
16
|
|
@@ -22,20 +20,19 @@ module Datagrid
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def datagrid_boolean_filter(attribute_or_filter, options = {})
|
25
|
-
check_box(
|
23
|
+
check_box(datagrid_get_attribute(attribute_or_filter), options)
|
26
24
|
end
|
27
25
|
|
28
26
|
def datagrid_date_filter(attribute_or_filter, options = {})
|
29
|
-
|
30
|
-
text_field(attribute, options)
|
27
|
+
datagrid_range_filter(:date, attribute_or_filter, options)
|
31
28
|
end
|
32
29
|
|
33
30
|
def datagrid_default_filter(attribute_or_filter, options = {})
|
34
|
-
text_field
|
31
|
+
text_field datagrid_get_attribute(attribute_or_filter), options
|
35
32
|
end
|
36
33
|
|
37
34
|
def datagrid_enum_filter(attribute_or_filter, options = {})
|
38
|
-
filter =
|
35
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
39
36
|
if !options.has_key?(:multiple) && filter.multiple
|
40
37
|
options[:multiple] = true
|
41
38
|
end
|
@@ -43,11 +40,32 @@ module Datagrid
|
|
43
40
|
end
|
44
41
|
|
45
42
|
def datagrid_integer_filter(attribute_or_filter, options = {})
|
46
|
-
filter =
|
43
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
47
44
|
if filter.multiple && self.object[filter.name].blank?
|
48
45
|
options[:value] = ""
|
49
46
|
end
|
50
|
-
|
47
|
+
datagrid_range_filter(:integer, filter, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def datagrid_range_filter(type, attribute_or_filter, options = {})
|
51
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
52
|
+
if filter.range?
|
53
|
+
options = options.merge(:multiple => true)
|
54
|
+
|
55
|
+
from_options = Datagrid::Utils.add_html_classes(options, "from")
|
56
|
+
from_value = object[filter.name].try(:first)
|
57
|
+
|
58
|
+
to_options = Datagrid::Utils.add_html_classes(options, "to")
|
59
|
+
to_value = object[filter.name].try(:last)
|
60
|
+
# 2 inputs: "from date" and "to date" to specify a range
|
61
|
+
[
|
62
|
+
text_field(filter.name, from_options.merge!(:value => from_value)),
|
63
|
+
I18n.t("datagrid.misc.#{type}_range_separator", :default => "<span class=\"separator #{type}\"> - </span>"),
|
64
|
+
text_field(filter.name, to_options.merge!(:value => to_value))
|
65
|
+
].join.html_safe
|
66
|
+
else
|
67
|
+
text_field(filter.name, options)
|
68
|
+
end
|
51
69
|
end
|
52
70
|
|
53
71
|
def datagrid_string_filter(attribute_or_filter, options = {})
|
@@ -58,11 +76,11 @@ module Datagrid
|
|
58
76
|
datagrid_default_filter(attribute_or_filter, options)
|
59
77
|
end
|
60
78
|
|
61
|
-
def
|
79
|
+
def datagrid_get_attribute(attribute_or_filter)
|
62
80
|
attribute_or_filter.is_a?(Symbol) ? attribute_or_filter : attribute_or_filter.name
|
63
81
|
end
|
64
82
|
|
65
|
-
def
|
83
|
+
def datagrid_get_filter(attribute_or_filter)
|
66
84
|
if attribute_or_filter.is_a?(Symbol)
|
67
85
|
object.class.filter_by_name(attribute_or_filter) ||
|
68
86
|
raise(Error, "filter #{attribute_or_filter} not found")
|