datagrid 1.1.2 → 1.2.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/.travis.yml +20 -0
- data/Readme.markdown +2 -0
- data/VERSION +1 -1
- data/app/views/datagrid/_head.html.erb +1 -1
- data/datagrid.gemspec +9 -3
- data/lib/datagrid.rb +0 -4
- data/lib/datagrid/active_model.rb +2 -1
- data/lib/datagrid/column_names_attribute.rb +3 -6
- data/lib/datagrid/columns.rb +115 -27
- data/lib/datagrid/drivers.rb +1 -1
- data/lib/datagrid/drivers/abstract_driver.rb +1 -1
- data/lib/datagrid/drivers/active_record.rb +1 -1
- data/lib/datagrid/drivers/array.rb +1 -1
- data/lib/datagrid/drivers/mongo_mapper.rb +1 -1
- data/lib/datagrid/drivers/mongoid.rb +1 -1
- data/lib/datagrid/form_builder.rb +15 -1
- data/lib/datagrid/helper.rb +45 -11
- data/lib/datagrid/renderer.rb +27 -6
- data/spec/datagrid/column_names_attribute_spec.rb +6 -0
- data/spec/datagrid/columns_spec.rb +103 -0
- data/spec/datagrid/drivers/mongo_mapper_spec.rb +1 -1
- data/spec/datagrid/drivers/mongoid_spec.rb +1 -1
- data/spec/datagrid/filters/date_filter_spec.rb +1 -1
- data/spec/datagrid/filters/date_time_filter_spec.rb +2 -2
- data/spec/datagrid/form_builder_spec.rb +28 -3
- data/spec/datagrid/helper_spec.rb +31 -4
- data/spec/spec_helper.rb +33 -2
- data/spec/support/matchers.rb +8 -23
- data/spec/support/mongo_mapper.rb +0 -4
- data/spec/support/mongoid.rb +0 -9
- data/spec/support/test_partials/client/datagrid/_form.html.erb +13 -0
- data/spec/support/test_partials/client/datagrid/_head.html.erb +9 -0
- data/spec/support/test_partials/client/datagrid/_order_for.html.erb +11 -0
- data/spec/support/test_partials/client/datagrid/_row.html.erb +6 -0
- data/spec/support/test_partials/client/datagrid/_table.html.erb +19 -0
- metadata +34 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87a528983e7fd2ef73cf521c573fec464b5461cb
|
4
|
+
data.tar.gz: f74b44092e5cb1b1c5c076514c655c6874729f45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a60e18d5454ad9dabc58d4c367b5b93b1d589d6c4a5dc6aa8d2a7836b4046c587a21fdd694c1553f5746fb4c6b76851fb95a38d8062a6a1cb993e6f06081ff0
|
7
|
+
data.tar.gz: 09c2cc3b93a3387d1b36eb09bf42c226eeab2bb363ae0ea7db00280d38136b330f1c39bca03441b3969519f4526f413e86dfa8382f9c1b358e28138002b414a5
|
data/.travis.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
language: ruby
|
2
|
+
#bundler_args: --without development
|
3
|
+
rvm:
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
- 2.1.1
|
7
|
+
#- jruby
|
8
|
+
#- jruby-head
|
9
|
+
#env: JRUBY_OPTS="--server -J-Xms512m -J-Xmx1024m"
|
10
|
+
#matrix:
|
11
|
+
#allow_failures:
|
12
|
+
#- rvm: jruby-head
|
13
|
+
#- gemfile: gemfiles/rails41.gemfile
|
14
|
+
notifications:
|
15
|
+
email: false
|
16
|
+
services:
|
17
|
+
- mongodb
|
18
|
+
gemfile:
|
19
|
+
- Gemfile
|
20
|
+
#- gemfiles/rails41.gemfile
|
data/Readme.markdown
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% grid.html_columns(*options[:columns]).each do |column| %>
|
3
3
|
<th class="<%= datagrid_column_classes(grid, column) %>">
|
4
4
|
<%= column.header %>
|
5
|
-
<%= datagrid_order_for(grid, column) if column.order && options[:order]%>
|
5
|
+
<%= datagrid_order_for(grid, column, options) if column.order && options[:order]%>
|
6
6
|
</th>
|
7
7
|
<% end %>
|
8
8
|
</tr>
|
data/datagrid.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: datagrid 1.
|
5
|
+
# stub: datagrid 1.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "datagrid"
|
9
|
-
s.version = "1.
|
9
|
+
s.version = "1.2.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Bogdan Gusiev"]
|
14
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-05-10"
|
15
15
|
s.description = "This allows you to easily build datagrid aka data tables with sortable columns and filters"
|
16
16
|
s.email = "agresso@gmail.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.files = [
|
21
21
|
".document",
|
22
22
|
".rspec",
|
23
|
+
".travis.yml",
|
23
24
|
"Gemfile",
|
24
25
|
"LICENSE.txt",
|
25
26
|
"Rakefile",
|
@@ -105,6 +106,11 @@ Gem::Specification.new do |s|
|
|
105
106
|
"spec/support/mongoid.rb",
|
106
107
|
"spec/support/simple_report.rb",
|
107
108
|
"spec/support/test_partials/_actions.html.erb",
|
109
|
+
"spec/support/test_partials/client/datagrid/_form.html.erb",
|
110
|
+
"spec/support/test_partials/client/datagrid/_head.html.erb",
|
111
|
+
"spec/support/test_partials/client/datagrid/_order_for.html.erb",
|
112
|
+
"spec/support/test_partials/client/datagrid/_row.html.erb",
|
113
|
+
"spec/support/test_partials/client/datagrid/_table.html.erb",
|
108
114
|
"templates/controller.rb.erb",
|
109
115
|
"templates/grid.rb.erb",
|
110
116
|
"templates/index.html.erb"
|
data/lib/datagrid.rb
CHANGED
@@ -24,7 +24,6 @@ module Datagrid
|
|
24
24
|
autoload :Engine
|
25
25
|
|
26
26
|
def self.included(base)
|
27
|
-
base.extend ClassMethods
|
28
27
|
base.class_eval do
|
29
28
|
|
30
29
|
include ::Datagrid::Core
|
@@ -37,9 +36,6 @@ module Datagrid
|
|
37
36
|
end
|
38
37
|
end # self.included
|
39
38
|
|
40
|
-
module ClassMethods
|
41
|
-
end # ClassMethods
|
42
|
-
|
43
39
|
class ConfigurationError < StandardError; end
|
44
40
|
class ArgumentError < ::ArgumentError; end
|
45
41
|
|
@@ -3,9 +3,6 @@ module Datagrid
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
class_attribute :columns_array
|
7
|
-
self.columns_array = []
|
8
|
-
|
9
6
|
datagrid_attribute :column_names do |names|
|
10
7
|
names = Array(names).reject(&:blank?)
|
11
8
|
if names.reject(&:blank?).blank?
|
@@ -48,12 +45,12 @@ module Datagrid
|
|
48
45
|
# Returns a list of columns with <tt>:mandatory => true</tt> option
|
49
46
|
# If no mandatory columns specified than all of them considered mandatory
|
50
47
|
def mandatory_columns
|
51
|
-
|
48
|
+
columns_array.select(&:mandatory?)
|
52
49
|
end
|
53
50
|
|
54
51
|
# Returns a list of columns without <tt>:mandatory => true</tt> option
|
55
52
|
def optional_columns
|
56
|
-
|
53
|
+
columns_array - mandatory_columns
|
57
54
|
end
|
58
55
|
|
59
56
|
protected
|
@@ -77,7 +74,7 @@ module Datagrid
|
|
77
74
|
end
|
78
75
|
|
79
76
|
def columns_visibility_enabled?
|
80
|
-
|
77
|
+
columns_array.any? do |column|
|
81
78
|
column.options.key?(:mandatory)
|
82
79
|
end
|
83
80
|
end
|
data/lib/datagrid/columns.rb
CHANGED
@@ -12,11 +12,16 @@ module Datagrid
|
|
12
12
|
|
13
13
|
include Datagrid::Core
|
14
14
|
|
15
|
-
class_attribute :default_column_options
|
15
|
+
class_attribute :default_column_options, :instance_writer => false
|
16
16
|
self.default_column_options = {}
|
17
17
|
|
18
18
|
class_attribute :batch_size
|
19
19
|
|
20
|
+
class_attribute :columns_array
|
21
|
+
self.columns_array = []
|
22
|
+
|
23
|
+
class_attribute :dynamic_block, :instance_writer => false
|
24
|
+
|
20
25
|
end
|
21
26
|
base.send :include, InstanceMethods
|
22
27
|
end # self.included
|
@@ -72,18 +77,13 @@ module Datagrid
|
|
72
77
|
# All column definistion are returned by default
|
73
78
|
# You can limit the output with only columns you need like:
|
74
79
|
#
|
75
|
-
#
|
80
|
+
# GridClass.columns(:id, :name)
|
76
81
|
#
|
77
82
|
# Supported options:
|
78
83
|
#
|
79
84
|
# * :data - if true returns only non-html columns. Default: false.
|
80
85
|
def columns(*args)
|
81
|
-
|
82
|
-
args.compact!
|
83
|
-
args.map!(&:to_sym)
|
84
|
-
columns_array.select do |column|
|
85
|
-
(!options[:data] || column.data?) && (!options[:html] || column.html?) && (column.mandatory? || args.empty? || args.include?(column.name))
|
86
|
-
end
|
86
|
+
filter_columns(columns_array, *args)
|
87
87
|
end
|
88
88
|
|
89
89
|
# Defines new datagrid column
|
@@ -116,25 +116,12 @@ module Datagrid
|
|
116
116
|
#
|
117
117
|
# See: https://github.com/bogdan/datagrid/wiki/Columns for examples
|
118
118
|
def column(name, options_or_query = {}, options = {}, &block)
|
119
|
-
|
120
|
-
query = options_or_query
|
121
|
-
else
|
122
|
-
options = options_or_query
|
123
|
-
end
|
124
|
-
check_scope_defined!("Scope should be defined before columns")
|
125
|
-
block ||= lambda do |model|
|
126
|
-
model.send(name)
|
127
|
-
end
|
128
|
-
position = Datagrid::Utils.extract_position_from_options(columns_array, options)
|
129
|
-
column = Datagrid::Columns::Column.new(self, name, query, default_column_options.merge(options), &block)
|
130
|
-
columns_array.insert(position, column)
|
119
|
+
define_column(columns_array, name, options_or_query, options, &block)
|
131
120
|
end
|
132
121
|
|
133
122
|
# Returns column definition with given name
|
134
123
|
def column_by_name(name)
|
135
|
-
|
136
|
-
col.name.to_sym == name.to_sym
|
137
|
-
end
|
124
|
+
find_column_by_name(columns_array, name)
|
138
125
|
end
|
139
126
|
|
140
127
|
# Returns an array of all defined column names
|
@@ -146,6 +133,14 @@ module Datagrid
|
|
146
133
|
Datagrid::Columns::Column::ResponseFormat.new(&block)
|
147
134
|
end
|
148
135
|
|
136
|
+
# Formats column value for HTML.
|
137
|
+
# Helps to distinguish formatting as plain data and HTML
|
138
|
+
#
|
139
|
+
# column(:name) do |model|
|
140
|
+
# format(model.name) do |value|
|
141
|
+
# content_tag(:strong, value)
|
142
|
+
# end
|
143
|
+
# end
|
149
144
|
def format(value, &block)
|
150
145
|
if block_given?
|
151
146
|
respond_to do |f|
|
@@ -161,11 +156,72 @@ module Datagrid
|
|
161
156
|
end
|
162
157
|
end
|
163
158
|
|
159
|
+
# Allows dynamic columns definition, that could not be defined at class level
|
160
|
+
#
|
161
|
+
# class MerchantsGrid
|
162
|
+
#
|
163
|
+
# scope { Merchant }
|
164
|
+
#
|
165
|
+
# column(:name)
|
166
|
+
#
|
167
|
+
# dynamic do
|
168
|
+
# PurchaseCategory.all.each do |category|
|
169
|
+
# column(:"#{category.name.underscore}_sales") do |merchant|
|
170
|
+
# merchant.purchases.where(:category_id => category.id).count
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
# end
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# grid = MerchantsGrid.new
|
177
|
+
# grid.data # => [
|
178
|
+
# # [ "Name", "Swimwear Sales", "Sportswear Sales", ... ]
|
179
|
+
# # [ "Reebok", 2083382, 8382283, ... ]
|
180
|
+
# # [ "Nike", 8372283, 18734783, ... ]
|
181
|
+
# # ]
|
182
|
+
def dynamic(&block)
|
183
|
+
previous_block = dynamic_block
|
184
|
+
self.dynamic_block = proc {
|
185
|
+
instance_eval(&previous_block) if previous_block
|
186
|
+
instance_eval(&block)
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
164
190
|
def inherited(child_class) #:nodoc:
|
165
191
|
super(child_class)
|
166
192
|
child_class.columns_array = self.columns_array.clone
|
167
193
|
end
|
168
194
|
|
195
|
+
def filter_columns(columns, *args) #:nodoc:
|
196
|
+
options = args.extract_options!
|
197
|
+
args.compact!
|
198
|
+
args.map!(&:to_sym)
|
199
|
+
columns.select do |column|
|
200
|
+
(!options[:data] || column.data?) && (!options[:html] || column.html?) && (column.mandatory? || args.empty? || args.include?(column.name))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def define_column(columns, name, options_or_query = {}, options = {}, &block) #:nodoc:
|
205
|
+
if options_or_query.is_a?(String)
|
206
|
+
query = options_or_query
|
207
|
+
else
|
208
|
+
options = options_or_query
|
209
|
+
end
|
210
|
+
check_scope_defined!("Scope should be defined before columns")
|
211
|
+
block ||= lambda do |model|
|
212
|
+
model.send(name)
|
213
|
+
end
|
214
|
+
position = Datagrid::Utils.extract_position_from_options(columns, options)
|
215
|
+
column = Datagrid::Columns::Column.new(self, name, query, default_column_options.merge(options), &block)
|
216
|
+
columns.insert(position, column)
|
217
|
+
end
|
218
|
+
|
219
|
+
def find_column_by_name(columns,name) #:nodoc:
|
220
|
+
columns.find do |col|
|
221
|
+
col.name.to_sym == name.to_sym
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
169
225
|
end # ClassMethods
|
170
226
|
|
171
227
|
module InstanceMethods
|
@@ -277,7 +333,7 @@ module Datagrid
|
|
277
333
|
# grid.columns # => id and name columns
|
278
334
|
# grid.columns(:id, :category) # => id and category column
|
279
335
|
def columns(*args)
|
280
|
-
self.class.
|
336
|
+
self.class.filter_columns(columns_array, *args).select {|column| column.enabled?(self)}
|
281
337
|
end
|
282
338
|
|
283
339
|
# Returns all columns that can be represented in plain data(non-html) way
|
@@ -298,10 +354,9 @@ module Datagrid
|
|
298
354
|
|
299
355
|
# Finds a column definition by name
|
300
356
|
def column_by_name(name)
|
301
|
-
self.class.
|
357
|
+
self.class.find_column_by_name(columns_array, name)
|
302
358
|
end
|
303
359
|
|
304
|
-
|
305
360
|
# Gives ability to have a different formatting for CSV and HTML column value.
|
306
361
|
#
|
307
362
|
# Example:
|
@@ -347,6 +402,40 @@ module Datagrid
|
|
347
402
|
::Datagrid::Columns::DataRow.new(self, asset)
|
348
403
|
end
|
349
404
|
|
405
|
+
# Defines a column at instance level
|
406
|
+
#
|
407
|
+
# See Datagrid::Columns::ClassMethods#column for more info
|
408
|
+
def column(name, options_or_query = {}, options = {}, &block) #:nodoc:
|
409
|
+
self.class.define_column(columns_array, name, options_or_query, options, &block)
|
410
|
+
end
|
411
|
+
|
412
|
+
def initialize(*) #:nodoc:
|
413
|
+
self.columns_array = self.class.columns_array.clone
|
414
|
+
instance_eval(&dynamic_block) if dynamic_block
|
415
|
+
super
|
416
|
+
end
|
417
|
+
|
418
|
+
# Returns all columns available for current grid configuration
|
419
|
+
#
|
420
|
+
# class MyGrid
|
421
|
+
# filter(:search)
|
422
|
+
# column(:id)
|
423
|
+
# column(:name, :mandatory => true)
|
424
|
+
# column(:search_match, :if => proc {|grid| grid.search.present? }
|
425
|
+
# end
|
426
|
+
#
|
427
|
+
# grid = MyGrid.new
|
428
|
+
# grid.columns # => [ <#Column:name> ]
|
429
|
+
# grid.available_columns # => [ <#Column:id>, <#Column:name> ]
|
430
|
+
# grid.search = "keyword"
|
431
|
+
# grid.available_columns # => [ <#Column:id>, <#Column:name>, <#Column:search_match> ]
|
432
|
+
#
|
433
|
+
def available_columns
|
434
|
+
columns_array.select do |column|
|
435
|
+
column.enabled?(self)
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
350
439
|
protected
|
351
440
|
|
352
441
|
def map_with_batches(&block)
|
@@ -365,7 +454,6 @@ module Datagrid
|
|
365
454
|
end
|
366
455
|
end
|
367
456
|
|
368
|
-
|
369
457
|
def csv_class
|
370
458
|
if RUBY_VERSION >= "1.9"
|
371
459
|
require 'csv'
|
data/lib/datagrid/drivers.rb
CHANGED
@@ -50,7 +50,10 @@ module Datagrid
|
|
50
50
|
filter.select(object).map do |element|
|
51
51
|
text, value = @template.send(:option_text_and_value, element)
|
52
52
|
id = [object_name, filter.name, value].join('_').underscore
|
53
|
-
|
53
|
+
html_options = datagrid_extra_checkbox_options.reverse_merge(
|
54
|
+
:id => id, :multiple => true, :checked => enum_checkbox_checked?(filter, value)
|
55
|
+
)
|
56
|
+
input = check_box(filter.name, html_options, value.to_s, nil)
|
54
57
|
label(filter.name, input + text, options.reverse_merge(:for => id))
|
55
58
|
end.join("\n").html_safe
|
56
59
|
else
|
@@ -61,6 +64,17 @@ module Datagrid
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
67
|
+
def enum_checkbox_checked?(filter, option_value)
|
68
|
+
current_value = object.send(filter.name)
|
69
|
+
if current_value.respond_to?(:include?)
|
70
|
+
# Typecast everything to string
|
71
|
+
# to remove difference between String and Symbol
|
72
|
+
current_value.map(&:to_s).include?(option_value.to_s)
|
73
|
+
else
|
74
|
+
current_value.to_s == option_value.to_s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
64
78
|
def datagrid_integer_filter(attribute_or_filter, options = {})
|
65
79
|
filter = datagrid_get_filter(attribute_or_filter)
|
66
80
|
if filter.multiple? && self.object[filter.name].blank?
|