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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +20 -0
  3. data/Readme.markdown +2 -0
  4. data/VERSION +1 -1
  5. data/app/views/datagrid/_head.html.erb +1 -1
  6. data/datagrid.gemspec +9 -3
  7. data/lib/datagrid.rb +0 -4
  8. data/lib/datagrid/active_model.rb +2 -1
  9. data/lib/datagrid/column_names_attribute.rb +3 -6
  10. data/lib/datagrid/columns.rb +115 -27
  11. data/lib/datagrid/drivers.rb +1 -1
  12. data/lib/datagrid/drivers/abstract_driver.rb +1 -1
  13. data/lib/datagrid/drivers/active_record.rb +1 -1
  14. data/lib/datagrid/drivers/array.rb +1 -1
  15. data/lib/datagrid/drivers/mongo_mapper.rb +1 -1
  16. data/lib/datagrid/drivers/mongoid.rb +1 -1
  17. data/lib/datagrid/form_builder.rb +15 -1
  18. data/lib/datagrid/helper.rb +45 -11
  19. data/lib/datagrid/renderer.rb +27 -6
  20. data/spec/datagrid/column_names_attribute_spec.rb +6 -0
  21. data/spec/datagrid/columns_spec.rb +103 -0
  22. data/spec/datagrid/drivers/mongo_mapper_spec.rb +1 -1
  23. data/spec/datagrid/drivers/mongoid_spec.rb +1 -1
  24. data/spec/datagrid/filters/date_filter_spec.rb +1 -1
  25. data/spec/datagrid/filters/date_time_filter_spec.rb +2 -2
  26. data/spec/datagrid/form_builder_spec.rb +28 -3
  27. data/spec/datagrid/helper_spec.rb +31 -4
  28. data/spec/spec_helper.rb +33 -2
  29. data/spec/support/matchers.rb +8 -23
  30. data/spec/support/mongo_mapper.rb +0 -4
  31. data/spec/support/mongoid.rb +0 -9
  32. data/spec/support/test_partials/client/datagrid/_form.html.erb +13 -0
  33. data/spec/support/test_partials/client/datagrid/_head.html.erb +9 -0
  34. data/spec/support/test_partials/client/datagrid/_order_for.html.erb +11 -0
  35. data/spec/support/test_partials/client/datagrid/_row.html.erb +6 -0
  36. data/spec/support/test_partials/client/datagrid/_table.html.erb +19 -0
  37. metadata +34 -28
@@ -4,9 +4,21 @@ require "action_view"
4
4
  module Datagrid
5
5
  module Helper
6
6
 
7
- # Format an value from datagrid column with given name and for given model
8
- def datagrid_format_value(report, column_name, model)
9
- datagrid_renderer.format_value(report, column_name, model)
7
+ # Returns individual cell value from the given grid, column name and model
8
+ # Allows to render custom HTML layout for grid data
9
+ #
10
+ # <ul>
11
+ # <% @grid.columns.each do |column|
12
+ # <li><%= column.header %>: <%= datagrid_value(@grid, column.name, @resource %></li>
13
+ # <% end %>
14
+ # </ul>
15
+ #
16
+ def datagrid_value(grid, column_name, model)
17
+ datagrid_renderer.format_value(grid, column_name, model)
18
+ end
19
+
20
+ def datagrid_format_value(grid, column_name, model) #:nodoc:
21
+ datagrid_value(grid, column_name, model)
10
22
  end
11
23
 
12
24
  # Renders html table with columns defined in grid class.
@@ -24,8 +36,10 @@ module Datagrid
24
36
  # * <tt>:columns</tt> - Array of column names to display.
25
37
  # Used in case when same grid class is used in different places
26
38
  # and needs different columns. Default: all defined columns.
27
- def datagrid_table(report, *args)
28
- datagrid_renderer.table(report, *args)
39
+ # * <tt>:partials</tt> - Path for partials lookup.
40
+ # Default: 'datagrid'.
41
+ def datagrid_table(grid, *args)
42
+ datagrid_renderer.table(grid, *args)
29
43
  end
30
44
 
31
45
  # Renders HTML table header for given grid instance using columns defined in it
@@ -34,23 +48,43 @@ module Datagrid
34
48
  #
35
49
  # * <tt>:order</tt> - display ordering controls built-in into header
36
50
  # Default: true
37
- #
51
+ # * <tt>:partials</tt> - Path for partials lookup.
52
+ # Default: 'datagrid'.
38
53
  def datagrid_header(grid, options = {})
39
54
  datagrid_renderer.header(grid, options)
40
55
  end
41
56
 
42
57
 
43
58
  # Renders HTML table rows using given grid definition using columns defined in it
44
- def datagrid_rows(report, assets, options = {})
45
- datagrid_renderer.rows(report, assets, options)
59
+ #
60
+ # Supported options:
61
+ #
62
+ # * <tt>:columns</tt> - Array of column names to display.
63
+ # Used in case when same grid class is used in different places
64
+ # and needs different columns. Default: all defined columns.
65
+ # * <tt>:partials</tt> - Path for partials lookup.
66
+ # Default: 'datagrid'.
67
+ def datagrid_rows(grid, assets, options = {})
68
+ datagrid_renderer.rows(grid, assets, options)
46
69
  end
47
70
 
48
71
  # Renders ordering controls for the given column name
49
- def datagrid_order_for(grid, column)
50
- datagrid_renderer.order_for(grid, column)
72
+ #
73
+ # Supported options:
74
+ #
75
+ # * <tt>:partials</tt> - Path for partials lookup.
76
+ # Default: 'datagrid'.
77
+ def datagrid_order_for(grid, column, options = {})
78
+ datagrid_renderer.order_for(grid, column, options)
51
79
  end
52
80
 
53
81
  # Renders HTML for for grid with all filters inputs and lables defined in it
82
+ #
83
+ # Supported options:
84
+ #
85
+ # * <tt>:partials</tt> - Path for form partial lookup.
86
+ # Default: 'datagrid'.
87
+ # * All options supported by Rails <tt>form_for</tt> helper
54
88
  def datagrid_form_for(grid, options = {})
55
89
  datagrid_renderer.form_for(grid, options)
56
90
  end
@@ -83,7 +117,7 @@ module Datagrid
83
117
 
84
118
  def method_missing(method, *args, &blk)
85
119
  if column = @grid.column_by_name(method)
86
- @context.datagrid_format_value(@grid, column, @asset)
120
+ @context.datagrid_value(@grid, column, @asset)
87
121
  else
88
122
  super
89
123
  end
@@ -30,7 +30,7 @@ module Datagrid
30
30
  options[:method] ||= :get
31
31
  options[:html] ||= {}
32
32
  options[:html][:class] ||= "datagrid-form #{@template.dom_class(grid)}"
33
- @template.render :partial => "datagrid/form", :locals => {:grid => grid, :options => options}
33
+ _render_partial('form', options[:partials], {:grid => grid, :options => options})
34
34
  end
35
35
 
36
36
  def table(grid, *args)
@@ -47,29 +47,50 @@ module Datagrid
47
47
  assets = assets.paginate(paginate)
48
48
  end
49
49
 
50
- @template.render :partial => "datagrid/table", :locals => {:grid => grid, :options => options, :assets => assets}
50
+ _render_partial('table', options[:partials],
51
+ {
52
+ :grid => grid,
53
+ :options => options,
54
+ :assets => assets
55
+ })
51
56
  end
52
57
 
53
58
  def header(grid, options = {})
54
59
  options[:order] = true unless options.has_key?(:order)
55
60
 
56
- @template.render :partial => "datagrid/head", :locals => {:grid => grid, :options => options}
61
+ _render_partial('head', options[:partials],
62
+ { :grid => grid, :options => options })
57
63
  end
58
64
 
59
65
  def rows(grid, assets, options = {})
60
66
  result = assets.map do |asset|
61
- @template.render :partial => "datagrid/row", :locals => {:grid => grid, :options => options, :asset => asset}
67
+ _render_partial('row', options[:partials],
68
+ {
69
+ :grid => grid,
70
+ :options => options,
71
+ :asset => asset
72
+ })
62
73
  end.join
63
74
 
64
75
  _safe(result)
65
76
  end
66
77
 
67
- def order_for(grid, column)
68
- @template.render :partial => "datagrid/order_for", :locals => { :grid => grid, :column => column }
78
+ def order_for(grid, column, options = {})
79
+ _render_partial('order_for', options[:partials],
80
+ { :grid => grid, :column => column })
69
81
  end
70
82
 
83
+ private
84
+
71
85
  def _safe(string)
72
86
  string.respond_to?(:html_safe) ? string.html_safe : string
73
87
  end
88
+
89
+ def _render_partial(partial_name, partials_path, locals = {})
90
+ @template.render({
91
+ :partial => File.join(partials_path || 'datagrid', partial_name),
92
+ :locals => locals
93
+ })
94
+ end
74
95
  end
75
96
  end
@@ -39,6 +39,12 @@ describe Datagrid::ColumnNamesAttribute do
39
39
  subject.row_for(entry).should == ["hello", "greeting"]
40
40
  end
41
41
 
42
+ it "should find any column by name" do
43
+ subject.column_by_name(:id).should_not be_nil
44
+ subject.column_by_name(:name).should_not be_nil
45
+ subject.column_by_name(:category).should_not be_nil
46
+ end
47
+
42
48
 
43
49
  context "when default option is passed to column_names_filter" do
44
50
  let(:column_names_filter_options) do
@@ -146,6 +146,7 @@ describe Datagrid::Columns do
146
146
  scope {Entry}
147
147
  column(:id, :if => :show?)
148
148
  column(:name, :unless => proc {|grid| !grid.show? })
149
+ column(:category)
149
150
 
150
151
  def show?
151
152
  false
@@ -153,6 +154,7 @@ describe Datagrid::Columns do
153
154
  end
154
155
  report.columns(:id).should == []
155
156
  report.columns(:name).should == []
157
+ report.available_columns.map(&:name).should == [:category]
156
158
  end
157
159
 
158
160
  describe ".column_names attributes" do
@@ -243,6 +245,21 @@ describe Datagrid::Columns do
243
245
  fake_assets.should_not_receive(:find_each)
244
246
  report.rows
245
247
  end
248
+
249
+ it "should support instance level batch size" do
250
+ grid = test_report do
251
+ scope {Entry}
252
+ column :id
253
+ self.batch_size = 25
254
+ end
255
+ grid.batch_size = 0
256
+ fake_assets = double(:assets)
257
+
258
+ grid.should_receive(:assets) { fake_assets }
259
+ fake_assets.should_receive(:each)
260
+ fake_assets.should_not_receive(:find_each)
261
+ grid.rows
262
+ end
246
263
  end
247
264
 
248
265
  describe ".data_row" do
@@ -285,4 +302,90 @@ describe Datagrid::Columns do
285
302
  grid.row_for(group).should == [2, false]
286
303
  end
287
304
  end
305
+
306
+ describe "instance level column definition" do
307
+ let(:modified_grid) do
308
+ grid = test_report do
309
+ scope { Entry }
310
+ column(:id)
311
+ end
312
+ grid.column(:name)
313
+ grid
314
+ end
315
+
316
+ let(:basic_grid) { modified_grid.class.new }
317
+ let!(:entry) { Entry.create!(:name => "Hello", :category => 'first') }
318
+
319
+ it "should have correct columns" do
320
+ modified_grid.columns.size.should == 2
321
+ basic_grid.class.columns.size.should == 1
322
+ basic_grid.columns.size.should == 1
323
+ end
324
+
325
+ it "should give correct header" do
326
+ modified_grid.header.should == ["Id", "Name"]
327
+ basic_grid.header.should == ["Id"]
328
+ end
329
+
330
+ it "should give correct rows" do
331
+ modified_grid.rows.should == [[entry.id, 'Hello']]
332
+ basic_grid.rows.should == [[entry.id]]
333
+ end
334
+
335
+ it "should support possitioning" do
336
+ modified_grid.column(:category, :before => :name)
337
+ modified_grid.header.should == ["Id", "Category", "Name"]
338
+ end
339
+
340
+ it "should support columns block" do
341
+ modified_grid.column(:category) do
342
+ category.capitalize
343
+ end
344
+ modified_grid.rows.should == [[entry.id, "Hello", 'First']]
345
+ end
346
+
347
+ it "should support column_names accessor" do
348
+ modified_grid.column_names = [:name]
349
+ modified_grid.rows.should == [['Hello']]
350
+ modified_grid.column_names = [:id]
351
+ modified_grid.rows.should == [[entry.id]]
352
+ end
353
+ it "should support column_names accessor with mandatory columns" do
354
+ modified_grid.column(:category, :mandatory => true)
355
+ modified_grid.column_names = [:name]
356
+ modified_grid.rows.should == [['Hello', 'first']]
357
+ basic_grid.column_names = [:id]
358
+ basic_grid.rows.should == [[entry.id]]
359
+ end
360
+
361
+ it "should support available columns" do
362
+ modified_grid.column(:category, :mandatory => true)
363
+ modified_grid.available_columns.map(&:name).should == [:id, :name, :category]
364
+ end
365
+
366
+ it "should respect column availability criteria" do
367
+ modified_grid.column(:category, :if => proc { false })
368
+ modified_grid.columns.map(&:name).should == [:id, :name]
369
+ end
370
+ end
371
+
372
+ describe 'dynamic helper' do
373
+ it "should work" do
374
+ grid = test_report do
375
+ scope {Entry}
376
+ column(:id)
377
+ dynamic {
378
+ column(:name)
379
+ column(:category)
380
+ }
381
+ end
382
+
383
+ grid.columns.map(&:name).should == [:id, :name, :category]
384
+ grid.class.columns.map(&:name).should == [:id]
385
+
386
+ grid.column_by_name(:id).should_not be_nil
387
+ grid.column_by_name(:name).should_not be_nil
388
+ end
389
+ end
390
+
288
391
  end
@@ -1,4 +1,4 @@
1
- describe Datagrid::Drivers::MongoMapper do
1
+ describe Datagrid::Drivers::MongoMapper, :mongomapper do
2
2
 
3
3
  describe ".match?" do
4
4
 
@@ -1,4 +1,4 @@
1
- describe Datagrid::Drivers::Mongoid do
1
+ describe Datagrid::Drivers::Mongoid, :mongoid do
2
2
 
3
3
  describe ".match?" do
4
4
 
@@ -16,7 +16,7 @@ describe Datagrid::Filters::DateFilter do
16
16
  end
17
17
 
18
18
  {:active_record => Entry, :mongoid => MongoidEntry}.each do |orm, klass|
19
- describe "with orm #{orm}" do
19
+ describe "with orm #{orm}", orm => true do
20
20
  describe "date to timestamp conversion" do
21
21
  let(:klass) { klass }
22
22
  subject do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Datagrid::Filters::DateTimeFilter do
4
4
  {:active_record => Entry, :mongoid => MongoidEntry}.each do |orm, klass|
5
- describe "with orm #{orm}" do
5
+ describe "with orm #{orm}", orm => true do
6
6
  describe "timestamp to timestamp conversion" do
7
7
  let(:klass) { klass }
8
8
  subject do
@@ -117,7 +117,7 @@ describe Datagrid::Filters::DateTimeFilter do
117
117
 
118
118
  context "when datetime format is configured" do
119
119
  around(:each) do |example|
120
- with_datetime_format(format = "%m/%d/%Y %H:%M") do
120
+ with_datetime_format("%m/%d/%Y %H:%M") do
121
121
  example.run
122
122
  end
123
123
  end
@@ -14,7 +14,6 @@ describe Datagrid::FormBuilder do
14
14
 
15
15
  let(:template) { ActionView::Base.new}
16
16
  let(:view) { ActionView::Helpers::FormBuilder.new(:report, _grid, template, {}, Proc.new {|f| })}
17
- subject { view }
18
17
 
19
18
 
20
19
  describe ".datagrid_filter" do
@@ -28,6 +27,7 @@ describe Datagrid::FormBuilder do
28
27
  subject do
29
28
  view.datagrid_filter(_filter, _filter_options)
30
29
  end
30
+
31
31
  let(:_filter_options) { {} }
32
32
  context "with default filter type" do
33
33
  let(:_grid) {
@@ -257,8 +257,8 @@ describe Datagrid::FormBuilder do
257
257
  else
258
258
  it { should equal_to_dom(
259
259
  '
260
- <label class="category enum_filter checkboxes" for="report_category_first"><input name="report[category][]" type="hidden"><input id="report_category_first" name="report[category][]" type="checkbox" value="first" />first</label>
261
- <label class="category enum_filter checkboxes" for="report_category_second"><input name="report[category][]" type="hidden"><input id="report_category_second" name="report[category][]" type="checkbox" value="second" />second</label>
260
+ <label class="category enum_filter checkboxes" for="report_category_first"><input id="report_category_first" name="report[category][]" type="checkbox" value="first" />first</label>
261
+ <label class="category enum_filter checkboxes" for="report_category_second"><input id="report_category_second" name="report[category][]" type="checkbox" value="second" />second</label>
262
262
  '
263
263
  )}
264
264
 
@@ -392,6 +392,31 @@ describe Datagrid::FormBuilder do
392
392
 
393
393
  it { should equal_to_dom(expected_html) }
394
394
  end
395
+ context "with column_names_filter default given as symbols" do
396
+ let(:_grid) do
397
+ test_report() do
398
+ scope {Entry}
399
+
400
+ column_names_filter(:default => [:id, :name], :checkboxes => true)
401
+
402
+ column(:id)
403
+ column(:name)
404
+ column(:category)
405
+ end
406
+ end
407
+ let(:_filter) { :column_names }
408
+ let(:expected_html) do
409
+ <<DOM
410
+ <label class="column_names enum_filter checkboxes" for="report_column_names_id"><input checked id="report_column_names_id" name="report[column_names][]" type="checkbox" value="id">Id</label>
411
+ <label class="column_names enum_filter checkboxes" for="report_column_names_name"><input checked id="report_column_names_name" name="report[column_names][]" type="checkbox" value="name">Name</label>
412
+ <label class="column_names enum_filter checkboxes" for="report_column_names_category"><input id="report_column_names_category" name="report[column_names][]" type="checkbox" value="category">Category</label>
413
+ DOM
414
+ end
415
+
416
+ it do
417
+ should equal_to_dom(expected_html)
418
+ end
419
+ end
395
420
 
396
421
  context "with dynamic filter" do
397
422
  let(:filter_options) do
@@ -128,6 +128,26 @@ describe Datagrid::Helper do
128
128
  end
129
129
  end
130
130
 
131
+ context 'with partials attribute' do
132
+ let(:grid) do
133
+ test_report do
134
+ scope { Entry }
135
+ column(:name)
136
+ column(:category)
137
+ end
138
+ end
139
+
140
+ it 'renders namespaced table partial' do
141
+ rendered_partial = subject.datagrid_table(grid, [entry], {
142
+ :partials => 'client/datagrid'
143
+ })
144
+ expect(rendered_partial).to include 'Namespaced table partial.'
145
+ expect(rendered_partial).to include 'Namespaced row partial.'
146
+ expect(rendered_partial).to include 'Namespaced head partial.'
147
+ expect(rendered_partial).to include 'Namespaced order_for partial.'
148
+ end
149
+ end
150
+
131
151
 
132
152
  describe ".datagrid_rows" do
133
153
  it "should support urls" do
@@ -308,7 +328,7 @@ describe Datagrid::Helper do
308
328
  "td.name" => 1
309
329
  )
310
330
  end
311
- end
331
+ end
312
332
  end
313
333
 
314
334
  describe ".datagrid_order_for" do
@@ -328,6 +348,13 @@ describe Datagrid::Helper do
328
348
  end
329
349
  end
330
350
  describe ".datagrid_form_for" do
351
+ it 'returns namespaced partial if partials options is passed' do
352
+ rendered_form = subject.datagrid_form_for(grid, {
353
+ :url => '',
354
+ :partials => 'client/datagrid'
355
+ })
356
+ expect(rendered_form).to include 'Namespaced form partial.'
357
+ end
331
358
  it "should render form and filter inputs" do
332
359
  class FormForGrid
333
360
  include Datagrid
@@ -393,7 +420,7 @@ describe Datagrid::Helper do
393
420
  end
394
421
  end
395
422
 
396
- describe ".datagrid_format_value" do
423
+ describe ".datagrid_value" do
397
424
  it "should format value by column name" do
398
425
  report = test_report do
399
426
  scope {Entry}
@@ -401,7 +428,7 @@ describe Datagrid::Helper do
401
428
  "<b>#{e.name}</b>"
402
429
  end
403
430
  end
404
- subject.datagrid_format_value(report, :name, entry).should == "<b>Star</b>"
431
+ subject.datagrid_value(report, :name, entry).should == "<b>Star</b>"
405
432
  end
406
433
  it "should support format in column" do
407
434
  report = test_report do
@@ -412,7 +439,7 @@ describe Datagrid::Helper do
412
439
  end
413
440
  end
414
441
  end
415
- subject.datagrid_format_value(report, :name, entry).should == "<a href=\"/profile\">Star</a>"
442
+ subject.datagrid_value(report, :name, entry).should == "<a href=\"/profile\">Star</a>"
416
443
  end
417
444
  end
418
445
  end