8000 TableFor, add tbody_html and row_html options · activeadmin/activeadmin@e41e0a1 · GitHub
[go: up one dir, main page]

Skip to content

Commit e41e0a1

Browse files
committed
TableFor, add tbody_html and row_html options
This patch adds a `tbody_html` and `row_html` options to the `TableFor` (and `IndexAsTable`) classes. These options allow you to pass a hash of html options attributes to the `tbody` and `tr` elements. This is useful when you want to add features to the table that require data attributes. For example, adding a sortable row via JavaScript. You can see how I'm currently using this approach in [this app](https://github.com/acp-admin/acp-admin): - [monkey patching](https://github.com/acp-admin/acp-admin/blob/master/config/initializers/active_admin.rb#L261-L328) (same approach as this PR) - [using both options on a `table_for` method](https://github.com/acp-admin/acp-admin/blob/master/app/views/active_admin/deliveries/_baskets.html.arb#L10-L13) for using [Stimulus Sortable component](https://www.stimulus-components.com/docs/stimulus-sortable/). The existing `row_class` option is kept for backwards compatibility, but the `row_html` will take precedence if both are provided.
1 parent 6165e14 commit e41e0a1

File tree

4 files changed

+82
-10
lines changed

4 files changed

+82
-10
lines changed

docs/3-index-pages/index-as-table.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,23 @@ index do
196196
end
197197
```
198198

199-
## Custom row class
199+
## Custom tbody HTML attributes
200200

201-
In order to add special class to table rows pass the proc object as a `:row_class` option
201+
In order to add special html attributes to table tbody pass a `:tbody_html` option of the `index` method.
202+
203+
```ruby
204+
index tbody_html: { class: "my-class", data: { controller: 'stimulus-controller' } } do
205+
# columns
206+
end
207+
```
208+
209+
## Custom row HTML attributes
210+
211+
In order to add special html attributes to table rows pass the proc object as a `:row_html` option
202212
of the `index` method.
203213

204214
```ruby
205-
index row_class: ->elem { 'active' if elem.active? } do
215+
index row_html: ->elem { { class: ('active' if elem.active?), data: { 'element-id' => elem.id } } } do
206216
# columns
207217
end
208218
```

lib/active_admin/views/components/table_for.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def build(obj, *attrs)
1616
@resource_class ||= @collection.klass if @collection.respond_to? :klass
1717

1818
@columns = []
19+
@tbody_html = options.delete(:tbody_html)
20+
@row_html = options.delete(:row_html)
21+
# To be deprecated, please use row_html instead.
1922
@row_class = options.delete(:row_class)
2023

2124
build_table
@@ -91,10 +94,12 @@ def build_table_header(col)
9194
end
9295

9396
def build_table_body
94-
@tbody = tbody do
97+
@tbody = tbody **(@tbody_html || {}) do
9598
# Build enough rows for our collection
9699
@collection.each do |elem|
97-
tr(id: dom_id_for(elem), class: @row_class&.call(elem))
100+
html_options = @row_html&.call(elem) || {}
101+
html_options.reverse_merge!(class: @row_class&.call(elem))
102+
tr(id: dom_id_for(elem), **html_options)
98103
end
99104
end
100105
end

lib/active_admin/views/index_as_table.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,17 +196,26 @@ module Views
196196
# end
197197
# ```
198198
#
199-
# ## Custom row class
199+
# ## Custom tbody HTML attributes
200200
#
201-
# In order to add special class to table rows pass the proc object as a `:row_class` option
202-
# of the `index` method.
201+
# In order to add special html attributes to table tbody pass a `:tbody_html` option of the `index` method.
203202
#
204203
# ```ruby
205-
# index row_class: ->elem { 'active' if elem.active? } do
204+
# index tbody_html: { class: "my-class", data: { controller: 'stimulus-controller' } } do
206205
# # columns
207206
# end
208207
# ```
209208
#
209+
# ## Custom row HTML attributes
210+
#
211+
# In order to add special html attributes to table rows pass the proc object as a `:row_html` option
212+
# of the `index` method.
213+
#
214+
# ```ruby
215+
# index row_html: ->elem { { class: ('active' if elem.active?), data: { 'element-id' => elem.id } } } do
216+
# # columns
217+
# end
218+
# ```
210219
class IndexAsTable < ActiveAdmin::Component
211220
def build(page_presenter, collection)
212221
add_class "index-as-table"
@@ -215,6 +224,9 @@ def build(page_presenter, collection)
215224
sortable: true,
216225
i18n: active_admin_config.resource_class,
217226
paginator: page_presenter[:paginator] != false,
227+
tbody_html: page_presenter[:tbody_html],
228+
row_html: page_presenter[:row_html],
229+
# To be deprecated, please use row_html instead.
218230
row_class: page_presenter[:row_class]
219231
}
220232

spec/unit/views/components/table_for_spec.rb

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,24 @@
294294
end
295295
end
296296

297-
context "when row_class" do
297+
context "when tbody_html" do
298+
let(:table) do
299+
render_arbre_component assigns, helpers do
300+
table_for(collection, tbody_html: { class: "my-class", data: { size: collection.size } }) do
301+
column :starred
302+
end
303+
end
304+
end
305+
306+
it "should render data-size attribute within tbody tag" do
307+
tbody = table.find_by_tag("tbody").first
308+
expect(tbody.attributes).to include(
309+
class: "my-class",
310+
data: { size: 3 })
311+
end
312+
end
313+
314+
context "when row_class (to be deprecated)" do
298315
let(:table) do
299316
render_arbre_component assigns, helpers do
300317
table_for(collection, row_class: -> e { "starred" if e.starred }) do
@@ -313,6 +330,34 @@
313330
end
314331
end
315332

333+
context "when row_html (take presence over row_class)" do
334+
let(:table) do
335+
render_arbre_component assigns, helpers do
336+
table_for(
337+
collection,
338+
row_class: -> e { "foo" },
339+
row_html: -> e {
340+
{
341+
class: ("starred" if e.starred),
342+
data: { title: e.title },
343+
}
344+
}
345+
) do
346+
column :starred
347+
end
348+
end
349+
end
350+
351+
it "should render html attributes within collection row" do
352+
trs = table.find_by_tag("tr")
353+
expect(trs.size).to eq 4
354+
expect(trs.first.attributes).to be_empty
355+
expect(trs.second.attributes).to include(class: "starred", data: { title: "First Post" })
356+
expect(trs.third.attributes).to include(class: nil, data: { title: "Second Post" })
357+
expect(trs.fourth.attributes).to include(class: nil, data: { title: "Third Post" })
358+
end
359+
end
360+
316361
context "when i18n option is specified" do
317362
around do |example|
318363
with_translation %i[activerecord attributes post title], "Name" do

0 commit comments

Comments
 (0)
0