From 8e4ab92bf75c88cd48c53c282cdd5f442c8f32f9 Mon Sep 17 00:00:00 2001 From: Matthew Denaburg Date: Fri, 21 Aug 2026 10:20:26 -0400 Subject: [PATCH 1/2] Add `subtitle` to `table`'s `attr_accessor` list --- lib/data-table/table.rb | 17 ++++++++++----- lib/data-table/version.rb | 2 +- spec/table_spec.rb | 46 ++++++++++++++++++++++++++++++++++----- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib/data-table/table.rb b/lib/data-table/table.rb index 9da2104..9051a19 100644 --- a/lib/data-table/table.rb +++ b/lib/data-table/table.rb @@ -23,7 +23,7 @@ class Table attr_reader :collection, :grouped_data, :subtotals, :totals, :subtotal_calculations, :total_calculations, :columns - attr_accessor :id, :title, :css_class, :empty_text, + attr_accessor :id, :title, :subtitle, :css_class, :empty_text, :alternate_rows, :alternate_cols, :display_header, :hide_if_empty, :repeat_headers_for_groups, :custom_headers @@ -41,7 +41,7 @@ def initialize(collection) def default_options! @id = '' @title = '' - @subtitle = '' + @subtitle = nil @css_class = '' @empty_text = 'No records found' @hide_if_empty = false @@ -76,7 +76,14 @@ def render def render_data_table html = "" - html << "" if @title + html << '' + html << render_data_table_header if @display_header if @collection.any? html << render_data_table_body(@collection) @@ -254,7 +261,7 @@ def render_totals html = '' @total_calculations.each_with_index do |totals_row, index| next if totals_row.nil? - + html << "" @columns.each do |col| value = totals_row[col.name] ||= nil @@ -291,7 +298,7 @@ def render_subtotals(group_header, _group_data = nil, ancestors = nil) @subtotal_calculations[path].each_with_index do |group, index| next if group.empty? - + html << "" @columns.each do |col| value = group[col.name] ? group[col.name].values[0] : nil diff --git a/lib/data-table/version.rb b/lib/data-table/version.rb index 70deb9d..2027c3e 100644 --- a/lib/data-table/version.rb +++ b/lib/data-table/version.rb @@ -1,3 +1,3 @@ module DataTable - VERSION = '2.0.3'.freeze + VERSION = '2.0.4'.freeze end diff --git a/spec/table_spec.rb b/spec/table_spec.rb index 96284c8..2e5367c 100644 --- a/spec/table_spec.rb +++ b/spec/table_spec.rb @@ -23,7 +23,7 @@ data_table.column(:name, 'Name') data_table.column(:class, 'Class') expect(data_table.render).to \ - eq(%{
#{@title}' + if @title || @subtitle + html << "#{@title}" if @title + html << "" if @title && @subtitle + html << "#{@subtitle}" if @subtitle + end + html << '
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) + eq(%{
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) end it "should group the records" do @@ -35,7 +35,7 @@ expect(data_table.grouped_data).to be true data_table.prepare_data expect(data_table.collection).to eq(collection.group_by {|g| g[grouping_column]}) - expect(data_table.render).to eq(%{
NameClass
Star Wars
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
Middle Earth
MithranderWizard
AragornRanger
}) + expect(data_table.render).to eq(%{
NameClass
Star Wars
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
Middle Earth
MithranderWizard
AragornRanger
}) end it "should do totaling" do @@ -111,7 +111,7 @@ # note how the rows are index_1, and there is no index_0 row expect(data_table.render).to \ - eq(%{
Star Wars
50
95
Star Wars
Middle Earth
9001
80
Middle Earth
}) + eq(%{
Star Wars
50
95
Star Wars
Middle Earth
9001
80
Middle Earth
}) end it "should render a custom header" do @@ -129,14 +129,14 @@ it "should render a table with the 'no records' message" do expect(data_table.render).to \ - eq(%{
No records found
}) + eq(%{
No records found
}) end it "should render a custom empty text notice" do text = "Nothing to see here" data_table.empty_text = text expect(data_table.render).to \ - eq(%{
#{text}
}) + eq(%{
#{text}
}) end it "avoids dividing by zero" do @@ -274,8 +274,42 @@ t.column :_empty_space, '' end - expected_html = %(
 Points
Basketball
9
 50
 51
9: AVG50.5
10
 52
 53
 54
10: AVG53.0
12
 55
12: AVG55.0
Basketball: AVG52.5
) + expected_html = %(
 Points
Basketball
9
 50
 51
9: AVG50.5
10
 52
 53
 54
10: AVG53.0
12
 55
12: AVG55.0
Basketball: AVG52.5
) expect(html).to eq(expected_html) end end + + context 'with a title and no subtitle' do + it 'renders the title' do + table = DataTable::Table.new([]) + table.title = 'My Table Title' + html = table.render + expect(html).to include("My Table Title") + end + end + + context 'with a subtitle and no title' do + it 'renders the subtitle' do + table = DataTable::Table.new([]) + table.subtitle = 'My Subtitle' + html = table.render + + expect(html).to include("") + expect(html).to include("") + expect(html).to include("My Subtitle") + end + end + + context 'with a title and a subtitle' do + it 'renders the subtitle' do + table = DataTable::Table.new([]) + table.title = 'My Table Title' + table.subtitle = 'My Subtitle' + html = table.render + + expect(html).to include("My Table Title") + expect(html).to include("") + expect(html).to include("My Subtitle") + end + end end From 7d9c956193880d09a86b87e3d15a57fe717c6037 Mon Sep 17 00:00:00 2001 From: Matthew Denaburg Date: Fri, 21 Aug 2026 11:17:17 -0400 Subject: [PATCH 2/2] Add support for CSS classes --- lib/data-table/table.rb | 12 ++++--- spec/data_table_spec.rb | 2 +- spec/table_spec.rb | 79 +++++++++++++++++++++++++---------------- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/lib/data-table/table.rb b/lib/data-table/table.rb index 9051a19..f4a8a71 100644 --- a/lib/data-table/table.rb +++ b/lib/data-table/table.rb @@ -23,7 +23,8 @@ class Table attr_reader :collection, :grouped_data, :subtotals, :totals, :subtotal_calculations, :total_calculations, :columns - attr_accessor :id, :title, :subtitle, :css_class, :empty_text, + attr_accessor :id, :css_class, :empty_text, + :title, :title_class, :subtitle, :subtitle_class, :title_separator_class, :alternate_rows, :alternate_cols, :display_header, :hide_if_empty, :repeat_headers_for_groups, :custom_headers @@ -41,7 +42,10 @@ def initialize(collection) def default_options! @id = '' @title = '' + @title_class = nil @subtitle = nil + @subtitle_class = nil + @title_separator_class = nil @css_class = '' @empty_text = 'No records found' @hide_if_empty = false @@ -78,9 +82,9 @@ def render_data_table html = "" html << '' diff --git a/spec/data_table_spec.rb b/spec/data_table_spec.rb index 1392601..ef0301b 100644 --- a/spec/data_table_spec.rb +++ b/spec/data_table_spec.rb @@ -17,6 +17,6 @@ t.column :class, 'Class' end - expect(html).to eq(%{
' if @title || @subtitle - html << "#{@title}" if @title - html << "" if @title && @subtitle - html << "#{@subtitle}" if @subtitle + html << "#{@title}" if @title + html << "" if @title && @subtitle + html << "#{@subtitle}" if @subtitle end html << '
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) + expect(html).to eq(%{
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) end end diff --git a/spec/table_spec.rb b/spec/table_spec.rb index 2e5367c..d515a5f 100644 --- a/spec/table_spec.rb +++ b/spec/table_spec.rb @@ -23,7 +23,7 @@ data_table.column(:name, 'Name') data_table.column(:class, 'Class') expect(data_table.render).to \ - eq(%{
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) + eq(%{
NameClass
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
MithranderWizard
AragornRanger
}) end it "should group the records" do @@ -35,7 +35,7 @@ expect(data_table.grouped_data).to be true data_table.prepare_data expect(data_table.collection).to eq(collection.group_by {|g| g[grouping_column]}) - expect(data_table.render).to eq(%{
NameClass
Star Wars
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
Middle Earth
MithranderWizard
AragornRanger
}) + expect(data_table.render).to eq(%{
NameClass
Star Wars
Luke SkywalkerJedi Knight
Emporer PalpatineSith Lord
Middle Earth
MithranderWizard
AragornRanger
}) end it "should do totaling" do @@ -111,7 +111,7 @@ # note how the rows are index_1, and there is no index_0 row expect(data_table.render).to \ - eq(%{
Star Wars
50
95
Star Wars
Middle Earth
9001
80
Middle Earth
}) + eq(%{
Star Wars
50
95
Star Wars
Middle Earth
9001
80
Middle Earth
}) end it "should render a custom header" do @@ -129,14 +129,14 @@ it "should render a table with the 'no records' message" do expect(data_table.render).to \ - eq(%{
No records found
}) + eq(%{
No records found
}) end it "should render a custom empty text notice" do text = "Nothing to see here" data_table.empty_text = text expect(data_table.render).to \ - eq(%{
#{text}
}) + eq(%{
#{text}
}) end it "avoids dividing by zero" do @@ -274,42 +274,61 @@ t.column :_empty_space, '' end - expected_html = %(
 Points
Basketball
9
 50
 51
9: AVG50.5
10
 52
 53
 54
10: AVG53.0
12
 55
12: AVG55.0
Basketball: AVG52.5
) + expected_html = %(
 Points
Basketball
9
 50
 51
9: AVG50.5
10
 52
 53
 54
10: AVG53.0
12
 55
12: AVG55.0
Basketball: AVG52.5
) expect(html).to eq(expected_html) end end - context 'with a title and no subtitle' do - it 'renders the title' do - table = DataTable::Table.new([]) + describe 'title rendering' do + let(:table) { DataTable::Table.new([]) } + let(:html) { table.render } + before(:each) do table.title = 'My Table Title' - html = table.render - expect(html).to include("My Table Title") end - end - - context 'with a subtitle and no title' do - it 'renders the subtitle' do - table = DataTable::Table.new([]) + before(:each, include_subtitle: true) do table.subtitle = 'My Subtitle' - html = table.render + end + + context 'with a title and no subtitle' do + it 'renders the title' do + expect(html).to include("My Table Title") + end - expect(html).to include("") - expect(html).to include("") - expect(html).to include("My Subtitle") + it 'includes the css class for the title' do + table.title_class = 'custom_title_class' + expect(html).to include("My Table Title") + end end - end - context 'with a title and a subtitle' do - it 'renders the subtitle' do - table = DataTable::Table.new([]) - table.title = 'My Table Title' - table.subtitle = 'My Subtitle' - html = table.render + context 'with a subtitle', :include_subtitle do + before(:each) do + table.subtitle = 'My Subtitle' + end + + it 'renders the subtitle' do + expect(html).to include("") + expect(html).to include("") + expect(html).to include("My Subtitle") + end - expect(html).to include("My Table Title") - expect(html).to include("") - expect(html).to include("My Subtitle") + it 'includes the css class for the subtitle' do + table.subtitle_class = 'custom_subtitle_class' + expect(html).to include("My Subtitle") + end + end + + context 'with css classes', :include_subtitle do + before(:each) do + table.title_class = 'custom_title_class' + table.title_separator_class = 'custom_separator_class' + table.subtitle_class = 'custom_subtitle_class' + end + + it 'renders the subtitle' do + expect(html).to include("My Table Title") + expect(html).to include("") + expect(html).to include("My Subtitle") + end end end end