crushlovely_table_helper 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTliYTQxODQzZWVkMGMzMTI5MmM5NWZjYTkyZDk4MzI5YWJkNzhlMw==
5
+ data.tar.gz: !binary |-
6
+ NzY0YTkwMGJmZTk5YzJlMmRjN2NlZTg2ZjdkZmEzM2U2ZmNmNmY1Nw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NDM3ZGYyMzYyMjU5YjQwZDA1YjE4OGZmM2EzMDE1MGM1NDQ1MzZlMDc0Zjlj
10
+ MTY4ZGY1MDE0MmI4OTk3ODVlNzRiMzgyYTkzNTNmMTk4MDBlMmQyMWVmOThm
11
+ ODcyNzczNTEwNWE5ZjY2OGFhNzExMTkwNWY4YWNlY2UwZmNkZDg=
12
+ data.tar.gz: !binary |-
13
+ M2U2YTg2M2RiZGJmOGU5YzIwYTdiMmM2MTBlMGY1YmEzMWU1NDBmZTFkNjE1
14
+ NmYwNjFiODVlY2Q0YjI2MGE5ZDRjMmJiZWMzZjMwMGUyYjE1NTJkMWJiYjgy
15
+ MGUyYTk3NzVlNDBiOTU5MzVhMWY3NjBiYWQwMmUyZmEwZTJiODQ=
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ coverage
3
+ pkg
4
+ rdoc
5
+ test/app_root/log
6
+ test/app_root/script
7
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.8.7
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ == master
2
+
3
+ == 0.2.2 / 2010-03-07
4
+
5
+ * Fix footer failing to render when there are multiple cells [Richard Luther]
6
+ * Fix TableHelper::RowBuilder failing on Ruby 1.9.1
7
+ * Release gems via rake-gemcutter instead of rubyforge
8
+
9
+ == 0.2.1 / 2009-04-25
10
+
11
+ * Automatically determine the colspan for the last footer to match the number of headers
12
+ * Fix default headers including all model columns when using :select in the collection query
13
+
14
+ == 0.2.0 / 2009-04-25
15
+
16
+ * Reorganize documentation
17
+ * Allow css classes to be customized
18
+ * Use the jQuery UI css naming convention
19
+ * Allow multiple headers to be created at once
20
+ * No longer allow pre-existing headers to be customized (instead must re-define all headers)
21
+ * Remove :header / :footer options
22
+ * Simplify public interface
23
+
24
+ == 0.1.0 / 2008-12-14
25
+
26
+ * Remove the PluginAWeek namespace
27
+ * Update tests to use ActionView::TestCase
28
+
29
+ == 0.0.5 / 2008-06-22
30
+
31
+ * Remove log files from gems
32
+
33
+ == 0.0.4 / 2008-06-15
34
+
35
+ * Support cell/column names that conflict with existing method names on the Row/Header classes
36
+ * Avoid string evaluation for dynamic methods
37
+
38
+ == 0.0.3 / 2008-06-01
39
+
40
+ * Remove dependency on set_or_append
41
+
42
+ == 0.0.2 / 2008-05-05
43
+
44
+ * Updated documentation
45
+
46
+ == 0.0.1 / 2007-08-18
47
+
48
+ * Add README documentation
49
+ * Add gem dependency on set_or_append
50
+ * Refactor test method names
51
+ * Convert dos newlines to unix newlines
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2010 Aaron Pfeifer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ desc 'Default: run all tests.'
7
+ task :default => :test
8
+
9
+ desc "Test table_helper."
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.test_files = Dir['test/**/*_test.rb']
13
+ t.verbose = true
14
+ end
15
+
16
+ begin
17
+ require 'rcov/rcovtask'
18
+ namespace :test do
19
+ desc "Test table_helper with Rcov."
20
+ Rcov::RcovTask.new(:rcov) do |t|
21
+ t.libs << 'lib'
22
+ t.test_files = Dir['test/**/*_test.rb']
23
+ t.rcov_opts << '--exclude="^(?!lib/)"'
24
+ t.verbose = true
25
+ end
26
+ end
27
+ rescue LoadError
28
+ end
29
+
30
+ desc "Generate documentation for table_helper."
31
+ Rake::RDocTask.new(:rdoc) do |rdoc|
32
+ rdoc.rdoc_dir = 'rdoc'
33
+ rdoc.title = 'table_helper'
34
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main=README.rdoc'
35
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
36
+ end
data/Readme.md ADDED
@@ -0,0 +1,16 @@
1
+ # Table Helper
2
+
3
+ **Important**: This gem is not actively maintained and only exists to support the older applications that still use it. If you're starting a new application, use the excellent [Table Cloth](https://github.com/bobbytables/table_cloth) gem instead.
4
+
5
+ This is the [Crush + Lovely](http://crushlovely.com) fork of the [Table Helper](http://github.com/pluginaweek/table_helper) gem. This fork contains the following changes:
6
+
7
+ * Use of `ActiveSupport::SafeBuffer` so table content isn't auto-encoded.
8
+ * Dependencies on Blankslate and Builder since this is being used in Rails apps that don't auto-require them.
9
+
10
+ ## Usage
11
+
12
+ In your `Gemfile`, do the following:
13
+
14
+ ```
15
+ gem 'crushlovely-table_helper', :require => 'table_helper'
16
+ ```
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+ require 'table_helper/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "crushlovely_table_helper"
6
+ s.version = TableHelper::VERSION
7
+ s.authors = ["Aaron Pfeifer", "PJ Kelly"]
8
+ s.email = "admin@crushlovely.com"
9
+ s.homepage = "https://github.com/crushlovely/table_helper"
10
+ s.description = "Adds a helper method for generating HTML tables from collections in Rails. Modifed by Crush + Lovely."
11
+ s.summary = "HTML tables from collections in Rails."
12
+ s.require_paths = ["lib"]
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- test/*`.split("\n")
15
+
16
+ s.add_dependency("blankslate")
17
+ s.add_dependency("builder")
18
+ s.add_development_dependency("rake")
19
+ s.add_development_dependency("plugin_test_helper", ">= 0.3.2")
20
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'table_helper'
@@ -0,0 +1,213 @@
1
+ require 'blankslate'
2
+ require 'builder'
3
+ require 'table_helper/collection_table'
4
+
5
+ # Provides a set of methods for turning a collection into a table
6
+ module TableHelper
7
+ # Generates a new table for the given collection.
8
+ #
9
+ # == Basic Example
10
+ #
11
+ # This example shows the most basic usage of +collection_table+ which takes
12
+ # information about a collection, the objects in them, the columns defined
13
+ # for the class, and generates a table based on that.
14
+ #
15
+ # Suppose you have a table generated by a migration like so:
16
+ #
17
+ # class CreatePeople < ActiveRecord::Base
18
+ # def self.up
19
+ # create_table do |t|
20
+ # t.string :first_name
21
+ # t.string :last_name
22
+ # t.integer :company_id
23
+ # t.string :role
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # ...then invoking the helper within a view:
29
+ #
30
+ # <%= collection_table Person.find(:all) %>
31
+ #
32
+ # ...is compiled to (formatted here for the sake of sanity):
33
+ #
34
+ # <table cellpadding="0" cellspacing="0" class="posts ui-collection">
35
+ # <thead>
36
+ # <tr>
37
+ # <th class="person-first_name" scope="col">First Name</th>
38
+ # <th class="person-last_name" scope="col">Last Name</th>
39
+ # <th class="person-company_id" scope="col">Company</th>
40
+ # <th class="person-role" scope="col">Role</th>
41
+ # </tr>
42
+ # </thead>
43
+ # <tbody>
44
+ # <tr class="person ui-collection-result">
45
+ # <td class="person-first_name">John</td>
46
+ # <td class="person-last_name">Doe</td>
47
+ # <td class="person-company_id">1</td>
48
+ # <td class="person-role">President</td>
49
+ # </tr>
50
+ # <tr class="person ui-collection-result">
51
+ # <td class="first_name">Jane</td>
52
+ # <td class="last_name">Doe</td>
53
+ # <td class="company_id">1</td>
54
+ # <td class="role">Vice-President</td>
55
+ # </tr>
56
+ # </tbody>
57
+ # <table>
58
+ #
59
+ # == Advanced Example
60
+ #
61
+ # This example below shows how +collection_table+ can be customized to show
62
+ # specific headers, content, and footers.
63
+ #
64
+ # <%=
65
+ # collection_table(@posts, :id => 'posts', :class => 'summary') do |t|
66
+ # t.header :title
67
+ # t.header :category
68
+ # t.header :author
69
+ # t.header :publish_date, 'Date<br \>Published'
70
+ # t.header :num_comments, '# Comments'
71
+ # t.header :num_trackbacks, '# Trackbacks'
72
+ #
73
+ # t.rows.alternate = :odd
74
+ # t.rows.each do |row, post, index|
75
+ # row.category post.category.name
76
+ # row.author post.author.name
77
+ # row.publish_date time_ago_in_words(post.published_at)
78
+ # row.num_comments post.comments.empty? ? '-' : post.comments.size
79
+ # row.num_trackbacks post.trackbacks.empty? ? '-' : post.trackbacks.size
80
+ # end
81
+ # end
82
+ # %>
83
+ #
84
+ # ...is compiled to (formatted here for the sake of sanity):
85
+ #
86
+ # <table cellpadding="0" cellspacing="0" class="summary posts ui-collection" id="posts">
87
+ # <thead>
88
+ # <tr>
89
+ # <th class="post-title" scope="col">Title</th>
90
+ # <th class="post-category" scope="col">Category</th>
91
+ # <th class="post-author" scope="col">Author</th>
92
+ # <th class="post-publish_date" scope="col">Date<br \>Published</th>
93
+ # <th class="post-num_comments" scope="col"># Comments</th>
94
+ # <th class="post-num_trackbacks" scope="col"># Trackbacks</th>
95
+ # </tr>
96
+ # </thead>
97
+ # <tbody>
98
+ # <tr class="post ui-collection-result">
99
+ # <td class="post-title">Open-source projects: The good, the bad, and the ugly</td>
100
+ # <td class="post-category">General</td>
101
+ # <td class="post-author">John Doe</td>
102
+ # <td class="post-publish_date">23 days</td>
103
+ # <td class="post-num_comments">-</td>
104
+ # <td class="post-num_trackbacks">-</td>
105
+ # </tr>
106
+ # <tr class="post ui-collection-result ui-state-alternate">
107
+ # <td class="post-title">5 reasons you should care about Rails</td>
108
+ # <td class="post-category">Rails</td>
109
+ # <td class="author">John Q. Public</td>
110
+ # <td class="post-publish_date">21 days</td>
111
+ # <td class="post-num_comments">-</td>
112
+ # <td class="post-num_trackbacks">-</td>
113
+ # </tr>
114
+ # <tr class="post ui-collection-result">
115
+ # <td class="post-title">Deprecation: Stop digging yourself a hole</td>
116
+ # <td class="post-category">Rails</td>
117
+ # <td class="post-author">Jane Doe</td>
118
+ # <td class="post-publish_date">17 days</td>
119
+ # <td class="post-num_comments">-</td>
120
+ # <td class="post-num_trackbacks">-</td>
121
+ # </tr>
122
+ # <tr class="post ui-collection-result ui-state-alternate">
123
+ # <td class="post-title">Jumpstart your Rails career at RailsConf 2007</td>
124
+ # <td class="post-category">Conferences</td>
125
+ # <td class="post-author">Jane Doe</td>
126
+ # <td class="post-publish_date">4 days</td>
127
+ # <td class="post-num_comments">-</td>
128
+ # <td class="post-num_trackbacks">-</td>
129
+ # </tr>
130
+ # <tr class="post ui-collection-result">
131
+ # <td class="post-title">Getting some REST</td>
132
+ # <td class="post-category">Rails</td>
133
+ # <td class="post-author">John Doe</td>
134
+ # <td class="post-publish_date">about 18 hours</td>
135
+ # <td class="post-num_comments">-</td>
136
+ # <td class="post-num_trackbacks">-</td>
137
+ # </tr>
138
+ # </tbody>
139
+ # </table>
140
+ #
141
+ # == Creating footers
142
+ #
143
+ # Footers allow you to show some sort of summary information based on the
144
+ # data displayed in the body of the table. Below is an example:
145
+ #
146
+ # <%
147
+ # collection_table(@posts) do |t|
148
+ # t.header :title
149
+ # t.header :category
150
+ # t.header :author
151
+ # t.header :publish_date, 'Date<br \>Published'
152
+ # t.header :num_comments, '# Comments'
153
+ # t.header :num_trackbacks, '# Trackbacks'
154
+ #
155
+ # t.rows.alternate = :odd
156
+ # t.rows.each do |row, post, index|
157
+ # row.category post.category.name
158
+ # row.author post.author.name
159
+ # row.publish_date time_ago_in_words(post.published_at)
160
+ # row.num_comments post.comments.empty? ? '-' : post.comments.size
161
+ # row.num_trackbacks post.trackbacks.empty? ? '-' : post.trackbacks.size
162
+ # end
163
+ #
164
+ # t.footer :num_comments, @posts.inject(0) {|sum, post| sum += post.comments.size}
165
+ # t.footer :num_trackbacks, @posts.inject(0) {|sum, post| sum += post.trackbacks.size}
166
+ # end
167
+ # %>
168
+ #
169
+ # ...is compiled to:
170
+ #
171
+ # <table cellpadding="0" cellspacing="0" class="posts ui-collection">
172
+ # <thead>
173
+ # <tr>
174
+ # <th class="post-title" scope="col">Title</th>
175
+ # <th class="post-category" scope="col">Category</th>
176
+ # <th class="post-author" scope="col">Author</th>
177
+ # <th class="post-publish_date" scope="col">Date<br \>Published</th>
178
+ # <th class="post-num_comments" scope="col"># Comments</th>
179
+ # <th class="post-num_trackbacks" scope="col"># Trackbacks</th>
180
+ # </tr>
181
+ # </thead>
182
+ # <tbody>
183
+ # <tr class="post ui-collection-result">
184
+ # <td class="post-title">Open-source projects: The good, the bad, and the ugly</td>
185
+ # <td class="post-category">General</td>
186
+ # <td class="post-author">John Doe</td>
187
+ # <td class="post-publish_date">23 days</td>
188
+ # <td class="post-num_comments">-</td>
189
+ # <td class="post-num_trackbacks">-</td>
190
+ # </tr>
191
+ # <tr class="post ui-collection-result ui-state-alternate">
192
+ # <td class="post-title">5 reasons you should care about Rails</td>
193
+ # <td class="post-category">Rails</td><td class="author">John Q. Public</td>
194
+ # <td class="post-publish_date">21 days</td>
195
+ # <td class="post-num_comments">-</td>
196
+ # <td class="post-num_trackbacks">-</td>
197
+ # </tr>
198
+ # </tbody>
199
+ # <tfoot>
200
+ # <tr>
201
+ # <td class="post-num_comments">0</td>
202
+ # <td class="post-num_trackbacks" colspan="5">0</td>
203
+ # </tr>
204
+ # </tfoot>
205
+ # <table>
206
+ def collection_table(collection, klass = nil, html_options = {}, &block)
207
+ CollectionTable.new(collection, klass, html_options, &block).html
208
+ end
209
+ end
210
+
211
+ ActionController::Base.class_eval do
212
+ helper TableHelper
213
+ end
@@ -0,0 +1,113 @@
1
+ require 'table_helper/body_row'
2
+
3
+ module TableHelper
4
+ # Represents the body of the table. In HTML, you can think of this as
5
+ # the <tbody> tag of the table.
6
+ class Body < HtmlElement
7
+ # The css class to apply for all rows in the body
8
+ cattr_accessor :empty_caption_class
9
+ @@empty_caption_class = 'ui-collection-empty'
10
+
11
+ # The table this body is a part of
12
+ attr_reader :table
13
+
14
+ # If set to :odd or :even, every odd or even-numbered row will have the
15
+ # alternate class appended to its html attributes. Default is nil.
16
+ attr_accessor :alternate
17
+
18
+ # The caption to display in the collection is empty
19
+ attr_accessor :empty_caption
20
+
21
+ def initialize(table) #:nodoc:
22
+ super()
23
+
24
+ @table = table
25
+ @empty_caption = 'No matches found.'
26
+ end
27
+
28
+ def alternate=(value) #:nodoc:
29
+ raise ArgumentError, 'alternate must be set to :odd or :even' if value && ![:odd, :even].include?(value)
30
+ @alternate = value
31
+ end
32
+
33
+ # Builds the body of the table. This includes the actual data that is
34
+ # generated for each object in the collection.
35
+ #
36
+ # +each+ expects a block that defines the data in each cell. Each
37
+ # iteration of the block will provide the row within the table, the object
38
+ # being rendered, and the index of the object. For example,
39
+ #
40
+ # t.rows.each do |row, post, index|
41
+ # row.title "<div class=\"wrapped\">#{post.title}</div>"
42
+ # row.category post.category.name
43
+ # end
44
+ #
45
+ # In addition, to specifying the data, you can also modify the html
46
+ # options of the row. For more information on doing this, see the
47
+ # BodyRow class.
48
+ #
49
+ # If the collection is empty and +empty_caption+ is set on the body,
50
+ # then the actual body will be replaced by a single row containing the
51
+ # html that was stored in +empty_caption+.
52
+ #
53
+ # == Default Values
54
+ #
55
+ # Whenever possible, the default value of a cell will be set to the
56
+ # object's attribute with the same name as the cell. For example,
57
+ # if a Post consists of the attribute +title+, then the cell for the
58
+ # title will be prepopulated with that attribute's value:
59
+ #
60
+ # t.rows.each do |row, post index|
61
+ # row.title post.title
62
+ # end
63
+ #
64
+ # <tt>row.title</tt> is already set to post.category so there's no need to
65
+ # manually set the value of that cell. However, it is always possible
66
+ # to override the default value like so:
67
+ #
68
+ # t.rows.each do |row, post, index|
69
+ # row.title link_to(post.title, post_url(post))
70
+ # row.category post.category.name
71
+ # end
72
+ def each(&block)
73
+ @builder = block
74
+ end
75
+
76
+ # Builds a row for an object in the table.
77
+ #
78
+ # The provided block should set the values for each cell in the row.
79
+ def build_row(object, index = table.collection.index(object))
80
+ row = BodyRow.new(object, self)
81
+ row.alternate = alternate ? index.send("#{alternate}?") : false
82
+ @builder.call(row.builder, object, index) if @builder
83
+ row.html
84
+ end
85
+
86
+ private
87
+ def tag_name
88
+ 'tbody'
89
+ end
90
+
91
+ def content
92
+ content = ActiveSupport::SafeBuffer.new
93
+
94
+ if table.empty? && @empty_caption
95
+ # No objects to display
96
+ row = Row.new(self)
97
+ row[:class] = empty_caption_class
98
+
99
+ html_options = {}
100
+ html_options[:colspan] = table.header.columns.size if table.header.columns.size > 1
101
+ row.cell nil, @empty_caption, html_options
102
+
103
+ content << row.html
104
+ else
105
+ table.collection.each_with_index do |object, i|
106
+ content << build_row(object, i)
107
+ end
108
+ end
109
+
110
+ content
111
+ end
112
+ end
113
+ end