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.
@@ -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
@@ -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
- # Simple Table
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
- # Pass Blocks to `Table#column`
74
-
75
- You can pass a block to the `Table#column` method to display values not directly accessible
76
- from the model's methods/properties:
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
- Assuming the route exists to show that record, this will generate HTML like this:
35
+ # Wanna Help?
89
36
 
90
- ```html
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)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails_table_for/railtie'
2
4
  require 'rails_table_for/table_helper'
3
5
 
@@ -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,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsTableFor
4
+ module Elements
5
+ module Column
6
+ def th
7
+ content_tag :th, title
8
+ end
9
+
10
+ def td(_)
11
+ raise 'Not implemented'
12
+ end
13
+ end
14
+ end
15
+ 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