rails_table_for 0.2.0 → 0.3.2
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/{ruby.yml → test.yml} +9 -4
- data/.rubocop.yml +47 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +83 -61
- data/Rakefile +5 -0
- data/bin/test +5 -3
- data/docs/Gemfile +8 -7
- data/docs/Gemfile.lock +10 -12
- data/docs/guides/auto-linking-rows.md +44 -0
- data/docs/guides/customizing-column-headers.md +36 -0
- data/docs/guides/customizing-row-values.md +41 -0
- data/docs/guides/getting-started.md +35 -0
- data/docs/guides/pagination.md +55 -0
- data/docs/index.md +14 -80
- data/lib/rails_table_for.rb +2 -0
- data/lib/rails_table_for/elements/block_column.rb +29 -0
- data/lib/rails_table_for/elements/column.rb +15 -0
- data/lib/rails_table_for/elements/field_column.rb +31 -0
- data/lib/rails_table_for/elements/table.rb +79 -0
- data/lib/rails_table_for/helpers/auto_link.rb +14 -0
- data/lib/rails_table_for/helpers/paginate.rb +62 -0
- data/lib/rails_table_for/railtie.rb +2 -0
- data/lib/rails_table_for/table_helper.rb +22 -10
- data/lib/rails_table_for/version.rb +3 -1
- data/rails_table_for.gemspec +2 -0
- metadata +58 -10
- data/.github/ISSUE_TEMPLATE/new-user-story.md +0 -20
- data/lib/rails_table_for/block_column.rb +0 -14
- data/lib/rails_table_for/column.rb +0 -5
- data/lib/rails_table_for/field_column.rb +0 -17
- data/lib/rails_table_for/table.rb +0 -61
- data/lib/tasks/rails_table_for_tasks.rake +0 -4
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: rails_table_for
|
4
|
+
---
|
5
|
+
|
6
|
+
# Auto-linking Rows
|
7
|
+
|
8
|
+
With the last example, we displayed a link for each row by passing a block to the `column` method
|
9
|
+
and using `link_to`. This is a whole lot of extra code for something so simple. Let's see how we
|
10
|
+
can do something similar in a single line:
|
11
|
+
|
12
|
+
```
|
13
|
+
<%=
|
14
|
+
table_for @records do |table|
|
15
|
+
table.column :name, auto_link: true
|
16
|
+
end
|
17
|
+
%>
|
18
|
+
```
|
19
|
+
|
20
|
+
This will generate the following HTML:
|
21
|
+
|
22
|
+
```html
|
23
|
+
<table>
|
24
|
+
<thead>
|
25
|
+
<tr>
|
26
|
+
<th>Name</th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr>
|
31
|
+
<td><a href="/records/1">Austin Roos</a></td>
|
32
|
+
</tr>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
```
|
36
|
+
|
37
|
+
You can also pass a block to `column` still, whatever value you return will be placed inside
|
38
|
+
the anchor tag
|
39
|
+
|
40
|
+
If no route can be found for the record, a `NoMethodError` will be thrown.
|
41
|
+
|
42
|
+
Now that we've simplified the linking, we should move on to some more features to make the table
|
43
|
+
more user-friendly. It's likely that some collections are going to be much too large to display
|
44
|
+
on a single page, so let's try out [pagination](./pagination)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: rails_table_for
|
4
|
+
---
|
5
|
+
|
6
|
+
# Customizing Column Headers
|
7
|
+
|
8
|
+
A one-line table is a delight, but we're a bit limited by only getting values and headers directly from our models.
|
9
|
+
Let's start by customizing the column header. The `table_for` method accepts a block with a single `Table` argument.
|
10
|
+
This object has a single method (`.column`) that allows you some customization. You can use it like this:
|
11
|
+
|
12
|
+
```
|
13
|
+
<%= table_for @records do |table| %>
|
14
|
+
<% table.column :name, title: 'Naam' %>
|
15
|
+
<% end %>
|
16
|
+
```
|
17
|
+
|
18
|
+
The title of the column will now be `Naam` and the rest of the table will be the same as the first example:
|
19
|
+
```html
|
20
|
+
<table>
|
21
|
+
<thead>
|
22
|
+
<tr>
|
23
|
+
<th>Naam</th>
|
24
|
+
</tr>
|
25
|
+
</thead>
|
26
|
+
<tbody>
|
27
|
+
<tr>
|
28
|
+
<td>Austin Roos</td>
|
29
|
+
</tr>
|
30
|
+
...
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
```
|
34
|
+
|
35
|
+
So... we've got a pretty simple table here with our header in Dutch... there must be more right? Indeed, next let's see
|
36
|
+
how to do more than print out values directly off the model. Move on to [customizing row values](./customizing-row-values)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: rails_table_for
|
4
|
+
---
|
5
|
+
|
6
|
+
# Customizing Row Values
|
7
|
+
|
8
|
+
It's great that we can change the header on a column displaying a user's name, but we must be able to do more than just show
|
9
|
+
simple strings from our models in these rows, right? Right. You can pass a block to the `Table#column` method and return
|
10
|
+
anything your heart desires. Let's add a column that gives us a link to 'Show' the user.
|
11
|
+
|
12
|
+
```
|
13
|
+
<%=
|
14
|
+
table_for @records do |table|
|
15
|
+
table.column :name, title: 'Naam'
|
16
|
+
table.column title: 'Link' { |record| link_to 'Show', record }
|
17
|
+
end
|
18
|
+
%>
|
19
|
+
```
|
20
|
+
|
21
|
+
Assuming the route exists to show that record, this will generate HTML like this:
|
22
|
+
|
23
|
+
```html
|
24
|
+
<table>
|
25
|
+
<thead>
|
26
|
+
<tr>
|
27
|
+
<th>Naam</th>
|
28
|
+
<th>Link</th>
|
29
|
+
</tr>
|
30
|
+
</thead>
|
31
|
+
<tbody>
|
32
|
+
<tr>
|
33
|
+
<td>Austin Roos</td>
|
34
|
+
<td><a href="/records/1">Show</a></td>
|
35
|
+
</tr>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
```
|
39
|
+
|
40
|
+
So... this gets us through most of the basics, but let's see if we can do things a little more simply. Check out
|
41
|
+
[auto-linking rows](./auto-linking-rows)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: rails_table_for
|
4
|
+
---
|
5
|
+
|
6
|
+
# Getting Started
|
7
|
+
|
8
|
+
For a simple table displaying some attributes of your ActiveRecord model, simply
|
9
|
+
call `table_for` with an ActiveRecord collection and an array of columns:
|
10
|
+
|
11
|
+
```
|
12
|
+
<%= table_for @records, columns: [:full_name] %>
|
13
|
+
```
|
14
|
+
|
15
|
+
The columns must correspond to methods/properties on the model class. The column header
|
16
|
+
will be the method/property name "humanized" (capitalized, split into words).
|
17
|
+
|
18
|
+
Example output:
|
19
|
+
```html
|
20
|
+
<table>
|
21
|
+
<thead>
|
22
|
+
<tr>
|
23
|
+
<th>Full Name</th>
|
24
|
+
</tr>
|
25
|
+
</thead>
|
26
|
+
<tbody>
|
27
|
+
<tr>
|
28
|
+
<td>Austin Roos</td>
|
29
|
+
</tr>
|
30
|
+
...
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
```
|
34
|
+
|
35
|
+
This is a good start, but surely you'd like to customize things a little bit. Move on to [customizing columns](./customizing-column-headers)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: rails_table_for
|
4
|
+
---
|
5
|
+
|
6
|
+
# Pagination (beta)
|
7
|
+
|
8
|
+
If you've made it this far, you know how to create some basic tables to present your data
|
9
|
+
in whatever way you see fit. Now you're so happy with your table that you want to present
|
10
|
+
50 million rows. This... is a little much for a single page. Enter pagination:
|
11
|
+
|
12
|
+
```
|
13
|
+
<%= table_for @records, columns: [:id, :name], page_size: 10 %>
|
14
|
+
```
|
15
|
+
|
16
|
+
and voila! you have a table showing only 10 rows per page as well as a set of links beneath
|
17
|
+
the table to take you to each page
|
18
|
+
|
19
|
+
```html
|
20
|
+
<div>
|
21
|
+
<table>
|
22
|
+
<thead>
|
23
|
+
<tr>
|
24
|
+
<th>Id</th>
|
25
|
+
<th>Name</th>
|
26
|
+
</tr>
|
27
|
+
</thead>
|
28
|
+
<tbody>
|
29
|
+
<tr>
|
30
|
+
<td>Austin Roos</td>
|
31
|
+
<td>1</td>
|
32
|
+
</tr>
|
33
|
+
...
|
34
|
+
</tbody>
|
35
|
+
</table>
|
36
|
+
<div class="pagination-links">
|
37
|
+
1
|
38
|
+
<a href="/users?page=2">2</a>
|
39
|
+
<a href="/users?page=3">3</a>
|
40
|
+
<a href="/users?page=4">4</a>
|
41
|
+
<a href="/users?page=5">5</a>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
```
|
45
|
+
|
46
|
+
This feature is still in beta and there are some known limitations.
|
47
|
+
|
48
|
+
### Known Issues
|
49
|
+
|
50
|
+
If there are multiple tables on a single web page, the pages of the table will always be
|
51
|
+
synced because of the query parameter.
|
52
|
+
|
53
|
+
If the number of pages is very large, every pagination link is still shown instead of
|
54
|
+
something a bit more elegant like a few pages before and after the current one as well as
|
55
|
+
a link to first and last page
|
data/docs/index.md
CHANGED
@@ -3,6 +3,12 @@ layout: default
|
|
3
3
|
title: rails_table_for
|
4
4
|
---
|
5
5
|
|
6
|
+
# Introduciton
|
7
|
+
|
8
|
+
No more writing out dozens of <tr>, <th>, <td> elements. Write a few lines of ruby code (or even a single line) and
|
9
|
+
get a lovely little table generated for you. You can present data from your records directly with almost no work, or
|
10
|
+
do a little customization if you'd like something extra special. More features are coming soon, but pagination
|
11
|
+
already comes included (only if you want it).
|
6
12
|
|
7
13
|
# Installation
|
8
14
|
|
@@ -18,86 +24,14 @@ And then execute:
|
|
18
24
|
$ bundle
|
19
25
|
```
|
20
26
|
|
21
|
-
#
|
22
|
-
|
23
|
-
For the simplest table, just pass an ActiveRecord collection and an array of columns
|
24
|
-
```
|
25
|
-
<%= table_for @records, columns: [:name] %>
|
26
|
-
```
|
27
|
-
|
28
|
-
The columns must correspond to methods/properties on the record class. The column header
|
29
|
-
will be the method/property name "humanized".
|
30
|
-
|
31
|
-
Example output:
|
32
|
-
```html
|
33
|
-
<table>
|
34
|
-
<thead>
|
35
|
-
<tr>
|
36
|
-
<th>Name</th>
|
37
|
-
</tr>
|
38
|
-
</thead>
|
39
|
-
<tbody>
|
40
|
-
<tr>
|
41
|
-
<td>Austin</td>
|
42
|
-
</tr>
|
43
|
-
</tbody>
|
44
|
-
</table>
|
45
|
-
```
|
46
|
-
|
47
|
-
# Customize Column Headers
|
48
|
-
|
49
|
-
You can can change the default column headers by passing a block to `table_for` and using the `Table#column` method:
|
50
|
-
|
51
|
-
```
|
52
|
-
<%= table_for @records do |table| %>
|
53
|
-
<% table.column :name, title: 'Naam' %>
|
54
|
-
<% end %>
|
55
|
-
```
|
56
|
-
|
57
|
-
The title of the column will now be `Naam` and the rest of the table will be the same as the first example:
|
58
|
-
```html
|
59
|
-
<table>
|
60
|
-
<thead>
|
61
|
-
<tr>
|
62
|
-
<th>Naam</th>
|
63
|
-
</tr>
|
64
|
-
</thead>
|
65
|
-
<tbody>
|
66
|
-
<tr>
|
67
|
-
<td>Austin</td>
|
68
|
-
</tr>
|
69
|
-
</tbody>
|
70
|
-
</table>
|
71
|
-
```
|
27
|
+
# Code Examples
|
72
28
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
```
|
79
|
-
<%=
|
80
|
-
table_for @records do |table|
|
81
|
-
table.column title: 'Link' do |record|
|
82
|
-
link_to record.name, record
|
83
|
-
end
|
84
|
-
end
|
85
|
-
%>
|
86
|
-
```
|
29
|
+
- [Getting Started](./guides/getting-started) (a one-liner?!)
|
30
|
+
- [Customizing Column Headers](./guides/customizing-column-headers)
|
31
|
+
- [Customizing Row Values](./guides/customizing-row-values)
|
32
|
+
- [Auto-linking Rows](./guides/auto-linking-rows)
|
33
|
+
- [Pagination](./guides/pagination)
|
87
34
|
|
88
|
-
|
35
|
+
# Wanna Help?
|
89
36
|
|
90
|
-
|
91
|
-
<table>
|
92
|
-
<thead>
|
93
|
-
<tr>
|
94
|
-
<th>Link</th>
|
95
|
-
</tr>
|
96
|
-
</thead>
|
97
|
-
<tbody>
|
98
|
-
<tr>
|
99
|
-
<td><a href="/records/1">Record 1</a></td>
|
100
|
-
</tr>
|
101
|
-
</tbody>
|
102
|
-
</table>
|
103
|
-
```
|
37
|
+
Happily accepting bug reports, feature requests, and pull requests. Visit [https://github.com/acroos/rails_table_for](https://github.com/acroos/rails_table_for)
|
data/lib/rails_table_for.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_table_for/helpers/auto_link'
|
4
|
+
require 'rails_table_for/elements/column'
|
5
|
+
|
6
|
+
module RailsTableFor
|
7
|
+
module Elements
|
8
|
+
class BlockColumn
|
9
|
+
include ActionView::Helpers::TagHelper
|
10
|
+
include Helpers::AutoLink
|
11
|
+
include Column
|
12
|
+
|
13
|
+
attr_reader :block, :title, :auto_link_enabled
|
14
|
+
private :block, :title, :auto_link_enabled
|
15
|
+
|
16
|
+
def initialize(block, **options)
|
17
|
+
@block = block
|
18
|
+
@title = options[:title]
|
19
|
+
@auto_link_enabled = options[:auto_link] || false
|
20
|
+
end
|
21
|
+
|
22
|
+
def td(record)
|
23
|
+
text = block.call(record)
|
24
|
+
content = auto_link_enabled ? auto_link(record, text) : text
|
25
|
+
content_tag :td, content
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_table_for/helpers/auto_link'
|
4
|
+
require 'rails_table_for/elements/column'
|
5
|
+
|
6
|
+
module RailsTableFor
|
7
|
+
module Elements
|
8
|
+
class FieldColumn
|
9
|
+
include ActionView::Helpers::TagHelper
|
10
|
+
include Helpers::AutoLink
|
11
|
+
include Column
|
12
|
+
|
13
|
+
attr_reader :field, :title, :auto_link_enabled
|
14
|
+
private :field, :title, :auto_link_enabled
|
15
|
+
|
16
|
+
def initialize(field, **options)
|
17
|
+
raise('Field cannot be nil', ArgumentError) if field.nil?
|
18
|
+
|
19
|
+
@field = field
|
20
|
+
@title = options[:title] || field.to_s.humanize
|
21
|
+
@auto_link_enabled = options[:auto_link] || false
|
22
|
+
end
|
23
|
+
|
24
|
+
def td(record)
|
25
|
+
text = record.send(field)
|
26
|
+
content = auto_link_enabled ? auto_link(record, text) : text
|
27
|
+
content_tag :td, content
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_table_for/elements/block_column'
|
4
|
+
require 'rails_table_for/elements/field_column'
|
5
|
+
require 'rails_table_for/helpers/paginate'
|
6
|
+
|
7
|
+
module RailsTableFor
|
8
|
+
module Elements
|
9
|
+
class Table
|
10
|
+
include Helpers::Paginate
|
11
|
+
include ActionView::Helpers::TagHelper
|
12
|
+
|
13
|
+
attr_accessor :columns, :output_buffer, :page_size, :record_count, :records, :request_params,
|
14
|
+
:request_path
|
15
|
+
private :columns, :page_size, :record_count, :records, :request_params, :request_path
|
16
|
+
|
17
|
+
def initialize(records, **options)
|
18
|
+
@records = records
|
19
|
+
@record_count = records.count
|
20
|
+
@columns = []
|
21
|
+
options[:columns]&.each { |field| column(field) }
|
22
|
+
@page_size = options[:page_size]
|
23
|
+
@request_path = options[:request_path]
|
24
|
+
@request_params = options[:request_params]
|
25
|
+
end
|
26
|
+
|
27
|
+
def column(field = nil, **options, &block)
|
28
|
+
if block_given?
|
29
|
+
columns << BlockColumn.new(block, options)
|
30
|
+
elsif field
|
31
|
+
columns << FieldColumn.new(field, options)
|
32
|
+
else
|
33
|
+
raise 'Must provide either field or block'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
return '' if record_count.zero?
|
39
|
+
return '' if columns.empty?
|
40
|
+
|
41
|
+
draw
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def draw
|
47
|
+
content_tag :div do
|
48
|
+
table + pagination_links
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def table
|
53
|
+
content_tag :table do
|
54
|
+
head + body
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def head
|
59
|
+
content_tag :thead do
|
60
|
+
content_tag :tr do
|
61
|
+
columns.map(&:th).join.html_safe
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def body
|
67
|
+
content_tag :tbody do
|
68
|
+
current_page_records.map { |record| body_row(record) }.join.html_safe
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def body_row(record)
|
73
|
+
content_tag :tr do
|
74
|
+
columns.map { |column| column.td(record) }.join.html_safe
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|