table-for 2.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem 'rails', ">= 3.0.0"
4
- gem 'blocks', "~> 2.2.0"
4
+ gem 'blocks', "~> 2.3.0"
5
5
 
6
6
  group :development do
7
7
  gem "rspec-rails", ">= 2.0.0.beta.20"
@@ -12,4 +12,5 @@ group :development do
12
12
  gem "with_model", '0.2.6'
13
13
  gem "bundler", "~> 1.3.5"
14
14
  gem "jeweler", "~> 1.8.4"
15
+ gem "debugger"
15
16
  end
data/Gemfile.lock CHANGED
@@ -29,10 +29,19 @@ GEM
29
29
  i18n (= 0.6.1)
30
30
  multi_json (~> 1.0)
31
31
  arel (3.0.2)
32
- blocks (2.2.0)
33
- blocks
32
+ blocks (2.3.0)
33
+ call_with_params
34
34
  rails (>= 3.0.0)
35
35
  builder (3.0.4)
36
+ call_with_params (0.0.1)
37
+ activesupport (>= 3.0.0)
38
+ columnize (0.3.6)
39
+ debugger (1.6.1)
40
+ columnize (>= 0.3.1)
41
+ debugger-linecache (~> 1.2.0)
42
+ debugger-ruby_core_source (~> 1.2.3)
43
+ debugger-linecache (1.2.0)
44
+ debugger-ruby_core_source (1.2.3)
36
45
  diff-lcs (1.2.1)
37
46
  erubis (2.7.0)
38
47
  git (1.2.5)
@@ -118,8 +127,9 @@ PLATFORMS
118
127
  ruby
119
128
 
120
129
  DEPENDENCIES
121
- blocks (~> 2.2.0)
130
+ blocks (~> 2.3.0)
122
131
  bundler (~> 1.3.5)
132
+ debugger
123
133
  jeweler (~> 1.8.4)
124
134
  mocha (= 0.10.3)
125
135
  rails (>= 3.0.0)
data/README.rdoc CHANGED
@@ -1,197 +1,150 @@
1
1
  = table-for
2
2
 
3
- Table-for is a table builder for a collection of domain objects. It very easily allows the user to specify the columns to render and to override how the table, the header columns, the rows, and the columns are rendered.
3
+ TableFor is a table builder for a collection of domain objects. It very easily allows the user to specify the columns to render and to override how the table, the header columns, the rows, and the columns are rendered.
4
4
 
5
5
  == Installation
6
6
 
7
- In <b>Rails 3</b>, add this to your Gemfile.
8
-
9
- gem "table-for"
10
-
11
- In this example, I'm going to assume the following setup:
12
- From the console, I have generated a user model with email, first_name, and last_name fields, and generated a scaffold on that model
13
- rails g scaffold user email:string first_name:string last_name:string --no-stylesheets
14
-
15
- In seeds.rb:
16
- User.create! :email => "andrew.hunter@livingsocial.com", :first_name => "Andrew", :last_name => "Hunter"
17
- User.create! :email => "todd.fisher@livingsocial.com", :first_name => "Todd", :last_name => "Fisher"
18
- User.create! :email => "jon.phillips@livingsocial.com", :first_name => "Jon", :last_name => "Phillips"
19
-
20
- In users_controller.rb (index action)
21
- @users = User.all
22
-
23
- == Sample Usage
24
- <%= table_for @users, :table_html => {:style => "border: 1px solid black"},
25
- :sortable => true, :sort_url => users_path,
26
- :row_html => {:class => lambda { cycle('even', 'odd')},
27
- :id => lambda {|user| "user-#{user.id}"}} do |table| %>
28
- <% table.column :edit, :link_label => "Modify" %>
29
- <% table.column :show %>
30
- <% table.column :email, :label => "Email Address" %>
31
- <% table.column :label => "Full Name", :sortable => false, :header_html => {:style => "color:orange"} do |user| %>
32
- <%= "#{user.first_name} #{user.last_name}" %>
33
- <% end %>
34
- <% table.column :delete, :confirm => "Are you sure?" %>
35
- <% end %>
36
-
37
- == Specifying the Columns to Use
38
- <%= table_for @users do |table| %>
39
- <% table.column :email %>
40
- <% table.column :first_name %>
41
- <% table.column :last_name %>
42
- <% end %>
43
-
44
- Here, each column will send its respective column name to the user object: user.send(:email), user.send(:first_name), user.send(:last_name),
45
- to determine what data to output in each column.
46
-
47
- == Specifying the Label to Use for a Column
48
- <%= table_for @users do |table| %>
49
- <% table.column :email, :label => "Email Address" %>
50
- <% end %>
51
-
52
- == Overriding the Default Way of Rendering a Column
53
- <%= table_for @users do |table| %>
54
- <% table.column :name do |user| %>
55
- <%= "#{user.first_name} #{user.last_name}" %>
56
- <% end %>
57
- <% end %>
58
-
59
- <!-- Or, since the name of the column is no longer used to figure out what data to render: -->
60
- <%= table_for @users do |table| %>
61
- <% table.column :full_name do |user| %>
62
- <%= "#{user.first_name} #{user.last_name}" %>
63
- <% end %>
64
- <% end %>
65
-
66
- <!-- Or the block name could be removed altogether and replaced with a label: -->
67
- <%= table_for @users do |table| %>
68
- <% table.column :label => "Full Name" do |user| %>
7
+ In <b>Rails 3 or Rails 4</b>, add this to your Gemfile.
8
+
9
+ gem "table-for", :git => "git@github.com:hunterae/table-for.git"
10
+
11
+ == Example
12
+ The following example is purposely complex (in many cases, there are easier ways to do what is shown) in order to show a wide range of features that TableFor is capable of:
13
+
14
+ <%= table_for @users, :table_html => { :class => "table table-hover table-bordered" },
15
+ :sortable => true,
16
+ :sort_url => sort_admin_users_path,
17
+ :link_namespace => :admin,
18
+ :data_row_html => {
19
+ :class => lambda { cycle('success', 'error', 'warning', 'info')},
20
+ :id => lambda { |user| "user-#{user.id}" }} do |table| %>
21
+ <% table.column :data => "Modify", :link_action => :edit %>
22
+ <% table.column :data => "Show", :link_url => lambda { |user| admin_user_path(user) } %>
23
+ <% table.column :data => "Show 2.0", :link => true %>
24
+ <% table.column :email, :header => "Email Address" %>
25
+ <% table.column :first_name, :formatter => :downcase %>
26
+ <% table.column :last_name, :formatter => Proc.new { |last_name| last_name.upcase } %>
27
+ <% table.column :created_at, :formatter => [:strftime, "%m/%d/%y %I:%M %p"] %>
28
+ <% table.column :updated_at,
29
+ :header => Proc.new {
30
+ content_tag(:span, :class => "badge badge-success") do
31
+ "Last Updated"
32
+ end
33
+ },
34
+ :sortable => false,
35
+ :header_column_html => { :style => "background-color:orange" },
36
+ :data => Proc.new { time_ago_in_words table.current_row.updated_at } %>
37
+ <% table.column :full_name, :header => "Full Name", :order => "last_name, first_name" do |user| %>
69
38
  <%= "#{user.first_name} #{user.last_name}" %>
70
39
  <% end %>
71
- <% end %>
72
-
73
- == Specifying Sortability
74
- <!-- Globally: -->
75
- <%= table_for @users, :sortable => true, :sort_url => users_path do |table| %>
76
- <% table.column :id, :sortable => false %>
77
- <% table.column :email %>
78
- <% table.column :name, :order => "first_name,last_name" do |user| %>
79
- <%= "#{user.first_name} #{user.last_name}" %>
40
+ <% table.header :full_name do |column, options| %>
41
+ <%= table.header_sort_link(column, options) do %>
42
+ <span class="label label-important">FULL NAME</span>
43
+ <% end %>
80
44
  <% end %>
81
- <% end %>
82
-
83
- <!-- Column by column basis: -->
84
- <%= table_for @users, :sort_url => users_path do |table| %>
85
- <% table.column :id %>
86
- <% table.column :email, :sortable => true %>
87
- <% table.column :name, :order => "first_name,last_name", :sortable => true do |user| %>
88
- <%= "#{user.first_name} #{user.last_name}" %>
45
+ <% table.column :data => "Delete", :link_method => :delete, :link_confirm => "Are you sure?" %>
46
+ <% table.footer do %>
47
+ <div class="pull-right">
48
+ <%= will_paginate @users %>
49
+ </div>
89
50
  <% end %>
90
51
  <% end %>
91
52
 
92
- == Specifying the Table HTML
93
- <%= table_for @users, :table_html => {:class => "table-for-table", :style => "border:1px solid black"} %>
94
-
95
- == Specifying the Row HTML
96
- <!-- Header row -->
97
- <%= table_for @users, :header_row_html => {:style => "background-color:blue", :class => "table-header"} do |table| %>
98
- <% table.column :email %>
99
- <% end %>
100
-
101
- <!-- Data rows -->
102
- <%= table_for @users, :row_html => {:style => "background-color:blue",
103
- :class => lambda {"table-row #{cycle('even', 'odd')}"},
104
- :id => lambda {|user| "user-#{user.id}"}} do |table| %>
105
- <% table.column :email %>
106
- <% end %>
107
-
108
- == Specifying the Column HTML
109
- <!-- Header columns -->
110
- <%= table_for @users, :header_html => {:class => lambda {|column| "header-column #{column.name}"} } do |table| %>
111
- <!-- Override this columns' header's html -->
112
- <% table.column :email, :header_html => {:style => "color: red"} %>
113
- <% table.column :first_name %>
114
- <% table.column :last_name %>
115
- <% end %>
116
-
117
- <!-- Data columns -->
118
- <%= table_for @users, :column_html => {:class => lambda {|column| "data-column #{column.name}"} } do |table| %>
119
- <!-- Override this column's html -->
120
- <% table.column :email, :column_html => {:style => "background-color: red"} %>
121
- <% table.column :first_name %>
122
- <% table.column :last_name %>
123
- <% end %>
124
-
125
- == Using Show, Edit, and Delete Columns
126
- <%= table_for @users do |table| %>
127
- <!-- Standard show link -->
128
- <% table.column :show %>
129
-
130
- <!-- Specify the controller action for the show link (used for generating the link) -->
131
- <% table.column :show, :action => :display %>
132
-
133
- <!-- Standard edit link -->
134
- <% table.column :edit %>
135
-
136
- <!-- Specify the text for the edit link -->
137
- <% table.column :edit, :link_label => "Modify" %>
138
-
139
- <!-- Specify the url for the edit link -->
140
- <% table.column :edit, :url => lambda {|user| edit_user_path(user) } %>
141
-
142
- <!-- Specify the controller action for the edit link (used for generating the link) -->
143
- <% table.column :edit, :action => :modify %>
144
-
145
- <!-- Specify the scope for the edit link (i.e. for nested resources) -->
146
- <% table.column :edit, :scope => :admin %>
147
-
148
- <!-- Specify the confirmation message for the confirm link -->
149
- <% table.column :delete, :confirm => "Are you sure???" %>
150
- <% end %>
53
+ Produces (with Twitter Bootstrap):
54
+
55
+ {<img src="https://raw.github.com/hunterae/table-for/master/example_table.png">}[http://example.com]
56
+
57
+ For detailed instructions on how to run this example, along with comments on every line of the above table, check out the {Example Details}[https://github.com/hunterae/table-for/blob/master/example.rdoc].
58
+
59
+ == table_for options
60
+ The first argument to the table_for call will always be the array of domain objects. The second argument is a hash
61
+ and is optional. It is any combination of the following options:
62
+
63
+ sortable::
64
+ (defaults to false)
65
+ Sets whether all columns are sortable by default.
66
+ If this field is set to true, each column header will be generated as a link.
67
+ sort_url::
68
+ (defaults to "")
69
+ Sets the url for the header column links. This will only affect columns that are sortable.
70
+ link_namespace::
71
+ (defaults to nil)
72
+ Sets the default namespace for any links generated in the columns.
73
+ For example, a link_namespace of admin would try to build links within the admin namespace in the routes.
74
+ This can be specified as a string, an array, a domain object, or a symbol,
75
+ i.e. :link_namespace => [:admin, @post, :comments]
76
+ table_html::
77
+ (defaults to nil)
78
+ Hash to specify the styles, classes, id, and other attributes applied to the table element,
79
+ i.e. :table_html => { :id => "my-table", :class => "table table-bordered", :cellpadding => 2 }.
80
+ thead_html::
81
+ (defaults to nil)
82
+ Hash to specify the styles, classes, id, and other attributes applied to the thead element,
83
+ i.e. :thead_html => { :id => "thead-id" }
84
+ Note: If TableFor.render_thead_element is set to false, the thead surrounding element for the
85
+ header row will not be rendered.
86
+ header_row_html::
87
+ (defaults to nil)
88
+ Hash to specify the styles, classes, id, and other attributes applied to the header row (tr) element,
89
+ i.e. :header_row_html => { :style => 'color: orange' }
90
+ header_column_html::
91
+ (defaults to {})
92
+ Hash to specify the styles, classes, id, and other attributes applied to the header column (th) element.
93
+ The values in this hash can each be a string or a Proc that takes (optionally) the column object as a parameter
94
+ i.e. :header_column => { :style => "font-weight: bold" }, or :header_column => { :class => Proc.new {|column| "#{column.name}_header" } }
95
+ tbody_html::
96
+ (defaults to nil)
97
+ Hash to specify the styles, classes, id, and other attributes applied to the tbody element,
98
+ i.e. :tbody_html => { :id => "body-id" }
99
+ Note: If TableFor.render_tbody_element is set to false, the tbody surrounding element for the
100
+ table data rows will not be rendered.
101
+ data_row_html::
102
+ (defaults to nil)
103
+ Hash to specify the styles, classes, id, and other attributes applied to each data row element (tr).
104
+ The values in this hash can each be a string or a Proc that takes (optionally) the current record as a parameter
105
+ i.e. :data_row_html => { :class => lambda { cycle('success', 'error', 'warning', 'info')}, :id => lambda { |user| "user-#{user.id}" } }
106
+ data_column_html::
107
+ (defaults to {})
108
+ Hash to specify the styles, classes, id, and other attributes applied to the header column (th) element.
109
+ The values in this hash can each be a string or a Proc that takes (optionally) the current_record and (also optionally) the column object as parameters
110
+ i.e. :data_column_html => { :style => "font-weight: bold", :id => Proc.new {|record, column| "record-#{record.id}-#{column.name}" } }
111
+ tfoot_html::
112
+ (defaults to nil)
113
+ Hash to specify the styles, classes, id, and other attributes applied to the tfoot element,
114
+ i.e. :tfoot_html => { :id => "tfoot-id" }
115
+ Note: If TableFor.render_tfoot_element is set to false, the tfoot surrounding element for the
116
+ footer row will not be rendered.
117
+ footer_row_html::
118
+ (defaults to nil)
119
+ Hash to specify the styles, classes, id, and other attributes applied to the footer row (tr) element,
120
+ i.e. :footer_row_html => { :style => 'color: orange' }
121
+ footer_column_html::
122
+ TODO
123
+
124
+ == table_for column options
125
+ data:: TODO
126
+ header:: TODO
127
+ formatter:: TODO
128
+ sortable:: TODO
129
+ sort_url:: TODO
130
+ order:: TODO
131
+ link_url:: TODO
132
+ link_action:: TODO
133
+ link_method:: TODO
134
+ link_confirm:: TODO
135
+ link_html::
136
+ link:: TODO
137
+ data_column_html:: TODO
138
+ header_column_html:: TODO
139
+
140
+ == table_for header options
141
+ TODO
142
+
143
+ == table_for footer options
144
+ TODO
145
+
146
+ == table_for configuration
147
+ TODO
151
148
 
152
149
  == Using "Before" and "After" hooks
153
- <!-- Adding a table footer -->
154
- <%= table_for @users do |table| %>
155
- <% table.column :email %>
156
- <% table.define :footer do %>
157
- <tfoot><tr><td colspan="<%= table.columns.length %>">My Footer</td></tr></tfoot>
158
- <% end %>
159
- <% end %>
160
-
161
- <!-- Evaluating an expression before each row renders -->
162
- <%= table_for @users do |table| %>
163
- <% table.before :row do |user| %>
164
- <!-- Perform some calculation -->
165
- <% @evaluated_data = user.do_some_method %>
166
- <% end %>
167
- <% table.column :label => "First Column" do |user| %>
168
- <!-- Use the stored value in some way -->
169
- <%= @evaluated_data.method_1 %>
170
- <% end %>
171
- <% table.column :label => "Second Column" do |user| %>
172
- <!-- Use the stored value in some other way -->
173
- <%= @evaluated_data.method_2 %>
174
- <% end %>
175
- <% end %>
176
-
177
- <!-- Adding a row before all the data rows -->
178
- <%= table_for @users do |table| %>
179
- <% table.before :rows do %>
180
- <tr><td colspan="<%= table.columns.length %>">My First Row</td></tr>
181
- <% end %>
182
- <% table.column :email %>
183
- <% end %>
184
-
185
- == Changing the Default Way table_for Renders
186
- <!-- Don't render thead and tbody tags -->
187
- <%= table_for @users do |table| %>
188
- <% table.define :table do |options| %>
189
- <%= content_tag :table, options[:table_html] do %>
190
- <!-- Instead of table.render :header, do this -->
191
- <%= table.render :header_row %>
192
- <!-- Instead of table.render :body, do this -->
193
- <%= table.render :rows %>
194
- <% end %>
195
- <% end %>
196
- <% table.column :email %>
197
- <% end %>
150
+ TODO
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 3.0.0
@@ -1,14 +1,18 @@
1
1
  <% table.define :table do |options| %>
2
- <%= content_tag :table, table_for_table_html(options) do %>
2
+ <%= content_tag :table, table.table_html(options) do %>
3
3
  <%= table.render :header %>
4
4
  <%= table.render :body %>
5
- <%# Purposely no default implementation for the tfoot block given, since most tables do not have footers. Block provided to for easy hook to add a footer %>
5
+ <%# Purposely no default implementation for the tfoot block given, since most tables do not have footers (provided to for easy hook to add a footer). %>
6
6
  <%= table.render :footer %>
7
7
  <% end %>
8
8
  <% end %>
9
9
 
10
10
  <% table.define :header do |options| %>
11
- <%= content_tag :thead, options[:thead_html] do %>
11
+ <% if TableFor.render_thead_element %>
12
+ <%= content_tag :thead, options[:thead_html] do %>
13
+ <%= table.render :header_row %>
14
+ <% end %>
15
+ <% else %>
12
16
  <%= table.render :header_row %>
13
17
  <% end %>
14
18
  <% end %>
@@ -20,65 +24,64 @@
20
24
  <% end %>
21
25
 
22
26
  <% table.define :header_column do |column, options| %>
23
- <%= content_tag :th, table_for_header_html(column, options) do %>
27
+ <%= content_tag :th, table.header_column_html(column, options) do %>
24
28
  <%= table.render "#{column.name}_header", column, column.options %>
25
29
  <% end %>
26
30
  <% end %>
27
31
 
28
- <%# Define header blocks for the edit, show, and delete columns (i.e. we want those columns to display with a blank header) %>
29
- <% [:edit, :show, :delete].each do |action| %>
30
- <% table.define "#{action}_header", :label => false, :order => :id do |column, options| %>
31
- <%= table_for_header_cell_data(column, options) %>
32
- <% end %>
33
- <% end %>
34
-
35
32
  <%# Define a header block for each column, named using that column's name with the word "_header" appended to it %>
36
33
  <% table.define lambda {|column| "#{column.name}_header" }, :collection => table.columns do |column, options| %>
37
- <%= table_for_header_cell_data(column, options) %>
34
+ <%= table.header_cell_content(column, options) %>
38
35
  <% end %>
39
36
 
40
37
  <% table.define :body do |options| %>
41
- <%= content_tag :tbody, options[:tbody_html] do %>
42
- <%= table.render :row, :collection => records %>
38
+ <% if TableFor.render_tbody_element %>
39
+ <%= content_tag :tbody, options[:tbody_html] do %>
40
+ <%= table.render :data_row, :collection => records %>
41
+ <% end %>
42
+ <% else %>
43
+ <%= table.render :data_row, :collection => records %>
43
44
  <% end %>
44
45
  <% end %>
45
46
 
46
- <% table.define :row do |record, options| %>
47
+ <% table.define :data_row do |record, options| %>
47
48
  <% table.set_current_record(record) %>
48
- <%= content_tag :tr, call_each_hash_value_if_proc(options[:row_html], record) do %>
49
- <%= table.render :column, record, :collection => table.columns %>
49
+ <%= content_tag :tr, table.call_each_hash_value_with_params(options[:data_row_html], record) do %>
50
+ <%= table.render :data_column, record, :collection => table.columns %>
50
51
  <% end %>
51
52
  <% end %>
52
53
 
53
- <% table.define :column do |column, record, options| %>
54
- <%= content_tag :td, call_each_hash_value_if_proc(options[:column_html], record, column) do %>
54
+ <% table.define :data_column do |column, record, options| %>
55
+ <%= content_tag :td, table.call_each_hash_value_with_params(options[:data_column_html], record, column) do %>
55
56
  <%= table.render column.name, record, column, column.options %>
56
57
  <% end %>
57
58
  <% end %>
58
59
 
59
- <% table.define :edit, :action => :edit, :link_label => "Edit" do |record, column, options| %>
60
- <% url = options[:url] ? call_if_proc(options[:url], record) : [options[:action], options[:scope], record].flatten %>
61
- <% link_name = options[:link_field] ? record.send(options[:link_field]) : options[:link_label] %>
62
- <%= link_to call_if_proc(link_name, record), url, options[:link_html] %>
60
+ <%# Define a block for each column, named using that column's name %>
61
+ <% table.define lambda {|column| column.name }, :collection => table.columns, :link_html => {} do |record, column, options| %>
62
+ <%= table.cell_content(record, column, options) %>
63
63
  <% end %>
64
64
 
65
- <% table.define :show, :action => nil, :link_label => "Show" do |record, column, options| %>
66
- <% url = options[:url] ? call_if_proc(options[:url], record) : [options[:action], options[:scope], record].flatten %>
67
- <% link_name = options[:link_field] ? record.send(options[:link_field]) : options[:link_label] %>
68
- <%= link_to call_if_proc(link_name, record), url, options[:link_html] %>
69
- <% end %>
65
+ <% table.define :footer do |options| %>
66
+ <% if TableFor.render_tfoot_element %>
67
+ <%= content_tag :tfoot, options[:tfoot_html] do %>
68
+ <%= table.render :footer_row %>
69
+ <% end %>
70
+ <% else %>
71
+ <%= table.render :footer_row %>
72
+ <% end %>
73
+ <% end if table.defined?(:footer_content) %>
70
74
 
71
- <% table.define :delete, :action => nil, :link_html => {}, :link_label => "Delete" do |record, column, options| %>
72
- <% url = options[:url] ? call_if_proc(options[:url], record) : [options[:action], options[:scope], record].flatten %>
73
- <% confirm = options[:confirm] ? options[:confirm] : "Are you sure you want to delete this #{record.class.to_s.titleize}?" %>
74
- <% method = options[:method] ? options[:method] : "delete" %>
75
- <% link_name = options[:link_field] ? record.send(options[:link_field]) : options[:link_label] %>
76
- <%= link_to call_if_proc(link_name, record), url, {:method => method, :confirm => confirm}.merge(options[:link_html]) %>
77
- <% end %>
75
+ <% table.define :footer_row do |options| %>
76
+ <%= content_tag :tr, options[:footer_row_html] do %>
77
+ <%= table.render :footer_column %>
78
+ <% end %>
79
+ <% end if table.defined?(:footer_content) %>
78
80
 
79
- <%# Define a block for each column, named using that column's name %>
80
- <% table.define lambda {|column| column.name }, :collection => table.columns do |record, column, options| %>
81
- <%= table_for_cell_data(record, column, options) %>
82
- <% end %>
81
+ <% table.define :footer_column do |options| %>
82
+ <%= content_tag :td, {:colspan => table.columns.length}.merge(table.blocks[:footer_content].options[:footer_column_html] || {}) do %>
83
+ <%= table.render :footer_content %>
84
+ <% end %>
85
+ <% end if table.defined?(:footer_content) %>
83
86
 
84
87
  <%= table.render :table %>