datagrid 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|