datagrid 1.1.2 → 1.2.0

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