magic_grid 0.9.3.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,9 +1,17 @@
1
1
  MagicGrid
2
2
  =========
3
3
 
4
- Takes a collection (ActiveRecord or Array) and creates a paginated table of
5
- it using a supplied column definition. It can generate the rows for you, or
6
- you can supply a block to do it yourself.
4
+ [![Build Status](https://secure.travis-ci.org/rmg/magic_grid.png?branch=master,stable,release)](http://travis-ci.org/rmg/magic_grid)
5
+
6
+ Easy collection display grid with column sorting and pagination.
7
+
8
+ Displays a collection (ActiveRelation or Array) wrapped in an html table with server
9
+ side column sorting, filtering hooks, and search bar. Large collections can be
10
+ paginated with either the will_paginate gem or kaminari gem if you use them, or a naive
11
+ Enumerable based paginator (without pager links) if neither is present.
12
+
13
+ Tables are styled using Themeroller compatible classes, which also don't look _too_ bad
14
+ with Bootstrap.
7
15
 
8
16
  Basic Usage
9
17
  -----------
@@ -18,7 +26,7 @@ In your view:
18
26
 
19
27
  Or a more realistic example:
20
28
 
21
- ```ruby
29
+ ```rhtml
22
30
  <%= magic_grid(@posts, [:title, :author, "Actions"]) do |post| %>
23
31
  <tr>
24
32
  <td><%= link_to(post.title, post) %></td>
data/Rakefile CHANGED
@@ -5,15 +5,19 @@ rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
7
 
8
- require 'yard'
8
+ begin
9
+ require 'yard'
10
+ YARD::Rake::YardocTask.new
11
+ rescue LoadError
12
+ puts "Skipping YARD tasks"
13
+ end
9
14
 
10
- YARD::Rake::YardocTask.new
11
15
 
12
16
  Bundler::GemHelper.install_tasks
13
17
 
14
18
  require 'rake/testtask'
15
19
 
16
- Rake::TestTask.new(:tests) do |t|
20
+ Rake::TestTask.new(:test) do |t|
17
21
  t.libs << 'lib'
18
22
  t.libs << 'test'
19
23
  t.pattern = 'test/**/*_test.rb'
@@ -27,5 +31,7 @@ RSpec::Core::RakeTask.new(:spec) do |t|
27
31
  t.verbose = false
28
32
  end
29
33
 
30
- task :test => [:spec, :tests]
31
- task :default => :test
34
+ desc "Run TestUnit and RSpec tests"
35
+ task :tests => [:spec, :test]
36
+
37
+ task :default => :tests
@@ -1,10 +1,10 @@
1
- require 'will_paginate/view_helpers/action_view'
1
+ #require 'will_paginate/view_helpers/action_view'
2
2
 
3
3
  module MagicGrid
4
4
  class Definition
5
- include WillPaginate::ActionView
5
+ #include WillPaginate::ActionView
6
6
  attr_accessor :columns, :collection, :magic_id, :options, :params,
7
- :current_sort_col, :current_order, :default_order
7
+ :current_sort_col, :current_order, :default_order, :per_page
8
8
 
9
9
  DEFAULTS = {
10
10
  :class => [],
@@ -54,7 +54,8 @@ module MagicGrid
54
54
  raise "I have no idea what that is, but it's not a Hash or an Array"
55
55
  end
56
56
  @default_order = @options[:default_order]
57
- @params = controller.try(:params) || {}
57
+ @params = controller && controller.params || {}
58
+ @per_page = @options[:per_page]
58
59
  @collection = collection
59
60
  begin
60
61
  #if @collection.respond_to? :table
@@ -172,9 +173,24 @@ module MagicGrid
172
173
  @collection = @options[:post_filter].call(@collection)
173
174
  end
174
175
  # Paginate at the very end, after all sorting, filtering, etc..
175
- if @options[:per_page]
176
- @collection = @collection.paginate(:page => param(:page, 1),
177
- :per_page => @options[:per_page])
176
+ if @per_page
177
+ if @collection.respond_to? :paginate
178
+ @collection = @collection.paginate(:page => current_page,
179
+ :per_page => @per_page)
180
+ elsif @collection.respond_to? :page
181
+ @collection = @collection.page(current_page).per(@per_page)
182
+ elsif @collection.is_a?(Array) and Module.const_defined?(:Kaminari)
183
+ @collection = Kaminari.paginate_array(@collection).page(current_page).per(@per_page)
184
+ else
185
+ original = @collection
186
+ @collection = @collection.to_enum.each_slice(@per_page).drop(current_page - 1).first.to_a
187
+ class << @collection
188
+ attr_accessor :current_page, :total_pages, :original_count
189
+ end
190
+ @collection.current_page = current_page
191
+ @collection.original_count = original.count
192
+ @collection.total_pages = original.count / @per_page
193
+ end
178
194
  end
179
195
  end
180
196
 
@@ -190,6 +206,10 @@ module MagicGrid
190
206
  @params.merge :magic_grid_id => @magic_id
191
207
  end
192
208
 
209
+ def current_page
210
+ [param(:page, 1).to_i, 1].max
211
+ end
212
+
193
213
  def order(something)
194
214
  case something
195
215
  when 1, "1", :desc, :DESC, "desc", "DESC"
@@ -1,5 +1,8 @@
1
1
  require 'magic_grid/definition'
2
- require 'will_paginate/array'
2
+
3
+ if Module.const_defined? :WillPaginate
4
+ require 'will_paginate/array'
5
+ end
3
6
 
4
7
  module MagicGrid
5
8
  module Helpers
@@ -62,7 +65,7 @@ module MagicGrid
62
65
  thead << content_tag('tr') do
63
66
  content_tag('td', :class => 'full-width ui-widget-header',
64
67
  :colspan => grid.columns.count) do
65
- pager = will_paginate(grid.collection,
68
+ pager = magic_paginate(grid.collection,
66
69
  :param_name => grid.param_key(:page),
67
70
  :params => base_params
68
71
  )
@@ -96,7 +99,7 @@ module MagicGrid
96
99
  tfoot << content_tag('tr') do
97
100
  content_tag('td', :class => 'full-width ui-widget-header',
98
101
  :colspan => grid.columns.count) do
99
- will_paginate(grid.collection,
102
+ magic_paginate(grid.collection,
100
103
  :param_name => grid.param_key(:page),
101
104
  :params => base_params
102
105
  )
@@ -243,6 +246,21 @@ module MagicGrid
243
246
  searcher
244
247
  end
245
248
 
249
+ def magic_paginate(collection, opts={})
250
+ if respond_to? :will_paginate
251
+ # WillPaginate
252
+ will_paginate collection, opts
253
+ #alias_method :magic_paginate, :will_paginate
254
+ elsif respond_to? :paginate
255
+ #Kaminari, or something else..
256
+ paginate collection, opts
257
+ #alias_method :magic_paginate, :paginate
258
+ else
259
+ ("<!-- page #{collection.current_page} of #{collection.total_pages} -->" +
260
+ '<!-- INSTALL WillPaginate or Kaminari for a pager! -->').html_safe
261
+ end
262
+ end
263
+
246
264
  ::ActionView::Base.send :include, self
247
265
  end
248
266
  end
@@ -1,3 +1,3 @@
1
1
  module MagicGrid
2
- VERSION = "0.9.3.1"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -1,10 +1,31 @@
1
1
  require 'spec_helper'
2
2
  require 'magic_grid/definition'
3
+ require 'active_support/core_ext/hash/indifferent_access'
3
4
 
4
5
  describe MagicGrid::Definition do
5
6
  pending "embarasses me with how tightly it is coupled with.. EVERYTHING"
6
7
 
8
+ shared_examples "a basic grid" do
9
+ its(:options) { should == MagicGrid::Definition.runtime_defaults }
10
+ its(:current_page) { should == 1 }
11
+
12
+ descendings = [1, "1", :desc, :DESC, "desc", "DESC"]
13
+ descendings.each do |down|
14
+ it "should normalize #{down} to 1" do
15
+ expect(subject.order(down)).to eq(1)
16
+ end
17
+ end
18
+
19
+ ascendings = [0, "0", :asc, :ASC, "asc", "ASC"]
20
+ ascendings.each do |up|
21
+ it "should normalize #{up} to 0" do
22
+ expect(subject.order(up)).to eq(0)
23
+ end
24
+ end
25
+ end
26
+
7
27
  let (:empty_collection) { [] }
28
+ let (:large_collection) { 200.times.map { |i| {id: i, name: "Name", description: "Describe me!"} } }
8
29
  let (:column_list) { [:name, :description] }
9
30
  let (:column_hash) { {} }
10
31
 
@@ -24,24 +45,48 @@ describe MagicGrid::Definition do
24
45
  expect { MagicGrid::Definition.new() }.to raise_error
25
46
  end
26
47
 
27
- subject { MagicGrid::Definition.new(column_list, empty_collection) }
28
- its(:base_params) { should include(:magic_grid_id) }
29
- its(:collection) { should == empty_collection }
30
- its(:columns) { should == column_list }
31
- its(:options) { should == MagicGrid::Definition.runtime_defaults }
48
+ context "when given an empty collection" do
49
+ subject { MagicGrid::Definition.new(column_list, empty_collection) }
50
+ its(:base_params) { should include(:magic_grid_id) }
51
+ its(:collection) { should == empty_collection }
52
+ its(:columns) { should == column_list }
53
+ it_behaves_like "a basic grid"
54
+ end
32
55
 
56
+ context "when given a large collection and default options" do
57
+ let(:controller) {
58
+ controller = double()
59
+ controller.stub(:params) { {page: 2} }
60
+ controller
61
+ }
62
+ subject { MagicGrid::Definition.new(column_list, large_collection, controller) }
63
+ it_behaves_like "a basic grid"
64
+ its(:collection) { should_not == empty_collection }
33
65
 
34
- descendings = [1, "1", :desc, :DESC, "desc", "DESC"]
35
- descendings.each do |down|
36
- it "should normalize #{down} to 1" do
37
- expect(subject.order(down)).to eq(1)
38
- end
66
+ its(:collection) { should have(MagicGrid::Definition.runtime_defaults[:per_page]).items }
67
+ its(:columns) { should == column_list }
39
68
  end
40
69
 
41
- ascendings = [0, "0", :asc, :ASC, "asc", "ASC"]
42
- ascendings.each do |up|
43
- it "should normalize #{up} to 0" do
44
- expect(subject.order(up)).to eq(0)
70
+ context "when given a large collection and some options" do
71
+ let(:controller) {
72
+ controller = double()
73
+ controller.stub(:params) { HashWithIndifferentAccess.new({grid_page: 2}) }
74
+ controller
75
+ }
76
+ subject { MagicGrid::Definition.new(column_list, large_collection, controller, id: :grid, per_page: 17) }
77
+ its(:collection) { should_not == empty_collection }
78
+ it "should give a collection with a page worth of items" do
79
+ subject.per_page.should < large_collection.count
80
+ subject.collection.should have(subject.per_page).items
45
81
  end
82
+ its(:columns) { should == column_list }
83
+ its(:current_page) { should == 2 }
84
+
85
+ it "should know how to extract its params" do
86
+ subject.param_key(:page).should == :grid_page
87
+ subject.param_key(:hunkydory).should == :grid_hunkydory
88
+ subject.param(:page).should == 2
89
+ end
90
+
46
91
  end
47
92
  end
data/spec/helpers_spec.rb CHANGED
@@ -10,6 +10,15 @@ describe MagicGrid::Helpers do
10
10
  let(:empty_collection) { [] }
11
11
  let(:column_list) { [:name, :description] }
12
12
 
13
+ let(:view_renderer) {
14
+ double.tap { |v|
15
+ v.stub(:render)
16
+ v.stub(:params) { {} }
17
+ # controller.stub(:option)
18
+ v.stub(:url_for) {|h| "/foo?page=#{h[:page]}"}
19
+ }
20
+ }
21
+
13
22
  describe "#normalize_magic" do
14
23
 
15
24
  it "should turn an array into a MagicGrid::Definition" do
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,33 @@
1
+ # require 'bundler'
2
+ # Bundler.setup
3
+
4
+ unless ENV['TRAVIS']
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ add_filter '/test/'
9
+ end
10
+ end
11
+
1
12
  require 'action_view'
2
13
  require 'rails'
3
- require 'will_paginate'
4
- require 'will_paginate/array'
5
- require 'will_paginate/view_helpers'
14
+
15
+ begin
16
+ require 'will_paginate'
17
+ require 'will_paginate/array'
18
+ require 'will_paginate/view_helpers'
19
+ puts "Testing with WillPaginate"
20
+ rescue LoadError
21
+ puts "skipping WillPaginate"
22
+ end
23
+
24
+ begin
25
+ require 'kaminari'
26
+ require 'kaminari/models/array_extension'
27
+ puts "Testing with Kaminari"
28
+ rescue LoadError
29
+ puts "skipping Kaminari"
30
+ end
6
31
 
7
32
  Rails.backtrace_cleaner.remove_silencers!
8
33
 
@@ -35,7 +60,8 @@ RSpec.configure do |config|
35
60
  config.filter_run :focus
36
61
 
37
62
  config.include ActionView::Helpers
38
- config.include WillPaginate::ViewHelpers
63
+ config.include WillPaginate::ViewHelpers if Module.const_defined? :WillPaginate
64
+ config.include Kaminari::ActionViewExtension if Module.const_defined? :Kaminari
39
65
  config.include ActionFaker
40
66
 
41
67
  # Run specs in random order to surface order dependencies. If you find an
@@ -23,7 +23,8 @@ Dummy::Application.configure do
23
23
  config.action_dispatch.best_standards_support = :builtin
24
24
 
25
25
  # Raise exception on mass assignment protection for Active Record models
26
- config.active_record.mass_assignment_sanitizer = :strict
26
+ # Rails 3.2.x+
27
+ # config.active_record.mass_assignment_sanitizer = :strict
27
28
 
28
29
  # Log the query plan for queries taking more than this (works
29
30
  # with SQLite, MySQL, and PostgreSQL)
@@ -30,7 +30,8 @@ Dummy::Application.configure do
30
30
  config.action_mailer.delivery_method = :test
31
31
 
32
32
  # Raise exception on mass assignment protection for Active Record models
33
- config.active_record.mass_assignment_sanitizer = :strict
33
+ # Rails 3.2.x+
34
+ #config.active_record.mass_assignment_sanitizer = :strict
34
35
 
35
36
  # Print deprecation notices to the stderr
36
37
  config.active_support.deprecation = :stderr
data/test/test_helper.rb CHANGED
@@ -1,6 +1,13 @@
1
1
  # Configure Rails Environment
2
2
  ENV["RAILS_ENV"] = "test"
3
3
 
4
+ unless ENV['TRAVIS']
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/dummy/'
8
+ end
9
+ end
10
+
4
11
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
12
  require "rails/test_help"
6
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic_grid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3.1
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-12 00:00:00.000000000 Z
12
+ date: 2012-09-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.1.0
21
+ version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,23 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 3.1.0
30
- - !ruby/object:Gem::Dependency
31
- name: will_paginate
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 3.0.0
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 3.0.0
29
+ version: '3.1'
46
30
  - !ruby/object:Gem::Dependency
47
31
  name: jquery-rails
48
32
  requirement: !ruby/object:Gem::Requirement
@@ -59,103 +43,59 @@ dependencies:
59
43
  - - ! '>='
60
44
  - !ruby/object:Gem::Version
61
45
  version: 1.0.17
62
- - !ruby/object:Gem::Dependency
63
- name: sqlite3
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
46
  - !ruby/object:Gem::Dependency
79
47
  name: rake
80
48
  requirement: !ruby/object:Gem::Requirement
81
49
  none: false
82
50
  requirements:
83
- - - ! '>='
51
+ - - ~>
84
52
  - !ruby/object:Gem::Version
85
- version: '0'
53
+ version: 0.9.2
86
54
  type: :development
87
55
  prerelease: false
88
56
  version_requirements: !ruby/object:Gem::Requirement
89
57
  none: false
90
58
  requirements:
91
- - - ! '>='
59
+ - - ~>
92
60
  - !ruby/object:Gem::Version
93
- version: '0'
61
+ version: 0.9.2
94
62
  - !ruby/object:Gem::Dependency
95
63
  name: tarantula
96
64
  requirement: !ruby/object:Gem::Requirement
97
65
  none: false
98
66
  requirements:
99
- - - ! '>='
67
+ - - ~>
100
68
  - !ruby/object:Gem::Version
101
- version: '0'
69
+ version: 0.4.0
102
70
  type: :development
103
71
  prerelease: false
104
72
  version_requirements: !ruby/object:Gem::Requirement
105
73
  none: false
106
74
  requirements:
107
- - - ! '>='
75
+ - - ~>
108
76
  - !ruby/object:Gem::Version
109
- version: '0'
77
+ version: 0.4.0
110
78
  - !ruby/object:Gem::Dependency
111
79
  name: rspec
112
80
  requirement: !ruby/object:Gem::Requirement
113
81
  none: false
114
82
  requirements:
115
- - - ! '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ! '>='
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: yard
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ! '>='
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
- - !ruby/object:Gem::Dependency
143
- name: redcarpet
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
83
+ - - ~>
148
84
  - !ruby/object:Gem::Version
149
- version: '0'
85
+ version: 2.11.0
150
86
  type: :development
151
87
  prerelease: false
152
88
  version_requirements: !ruby/object:Gem::Requirement
153
89
  none: false
154
90
  requirements:
155
- - - ! '>='
91
+ - - ~>
156
92
  - !ruby/object:Gem::Version
157
- version: '0'
158
- description: Simple collection displaying with pagination using will_paginate
93
+ version: 2.11.0
94
+ description: ! " Displays a collection (ActiveRelation or Array) wrapped in an
95
+ html table with server\n side column sorting, filtering hooks, and search bar.
96
+ Large collections can be\n paginated with either the will_paginate gem or kaminari
97
+ gem if you use them, or a naive\n Enumerable based paginator (without pager links)
98
+ if neither is present.\n"
159
99
  email:
160
100
  - r.m.graham@gmail.com
161
101
  executables: []
@@ -268,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
268
208
  version: '0'
269
209
  segments:
270
210
  - 0
271
- hash: -1296722646557219267
211
+ hash: -4018779425854186674
272
212
  required_rubygems_version: !ruby/object:Gem::Requirement
273
213
  none: false
274
214
  requirements:
@@ -277,13 +217,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
277
217
  version: '0'
278
218
  segments:
279
219
  - 0
280
- hash: -1296722646557219267
220
+ hash: -4018779425854186674
281
221
  requirements: []
282
222
  rubyforge_project:
283
223
  rubygems_version: 1.8.23
284
224
  signing_key:
285
225
  specification_version: 3
286
- summary: Simple collection displaying with pagination using will_paginate
226
+ summary: Easy collection display grid with column sorting and pagination
287
227
  test_files:
288
228
  - spec/spec_helper.rb
289
229
  - spec/helpers_spec.rb