Class: TidyTable

Inherits:
Object
  • Object
show all
Defined in:
lib/tidy_table.rb

Overview

This is yet another library to convert an ActiveRecord array (or any struct) to an HTML table.

You get a table with a bunch of CSS classes automatically applied (or customize it with your own classes and ids). For example, first_row (is also a th tag), first_column, last_column, even & odd (for rows).

Other tags like thead and tbody may be added in the future.

Simple example with an ActiveRecord object:

<%= TidyTable.new(@records).to_html(%w(title description created_at)) %>

You also format the row values with a block:

<%= TidyTable.new(@records, :table_class => "revenue_report").to_html(%w(resource visits min max)) do |row|
  [
    row.resource,
    number_with_delimiter(row.visit_count),
    row.min,
    row.max
  ]
end %>

Or in HAML:

= TidyTable.new(@records, :table_class => "revenue_report").to_html(%w(resource visits min max)) do |row|
  - [ row.resource, number_with_delimiter(row.visit_count), row.min, row.max ]

Constant Summary collapse

VERSION =
'0.0.5'

Instance Method Summary collapse

Constructor Details

#initialize(array, options = {}) ⇒ TidyTable

Make a new TidyTable with a data array and CSS options.

  • :table_class – Defaults to ‘tidy_table’

  • :first_row_class – Defaults to ‘first_row’

  • :first_column_class – Defaults to ‘first_column’

  • :last_column_class – Defaults to ‘last_column’

  • :title – Title for this table. Emits an extra header row

    spanning all columns.
    
  • :title_class – CSS class for the title th. Default: ‘title’

You also get ‘even’ and ‘odd’ for free (rows only).



48
49
50
51
52
53
54
55
56
57
# File 'lib/tidy_table.rb', line 48

def initialize(array, options={})
  @rows = array
  @options = {
    :table_class => "tidy_table",
    :first_row_class => "first_row",
    :first_column_class => "first_column",
    :last_column_class => "last_column",
    :title_class => "title"
  }.merge(options)
end

Instance Method Details

#to_html(fields) ⇒ Object

First argument is an array of column names. Will also be called as methods on each row object if no block is provided.

If given, a block will be called for each row of the array. You should return an Array with the values formatted in the format that you want to see in the resulting cells.

Or, return a Hash where

:data  => ['contents', 'for', 'cells'],
:id    => 'id_for_this_row',
:class => 'extra_classes for_this row'


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/tidy_table.rb', line 73

def to_html(fields)      
  output = []
  output << %(<table class="#{@options[:table_class]}">)

  # Title
  if @options.has_key?(:title)
    output << %(<tr class="#{@options[:first_row_class]}">)
    output << %(<th class="#{@options[:title_class]} #{@options[:first_row_class]} #{@options[:first_column_class]}" colspan="#{fields.length}">#{@options[:title]}</th>)
    output << %(</tr>)
  end

  # First row (header)
  output << %(<tr class="#{@options[:first_row_class]}">)
  fields.each_with_index do |field, index|
    output << %(<th class="#{@options[:first_row_class]} #{column_classes(fields, index)}">#{field}</th>)
  end
  output << "</tr>"

  @rows.each_with_index do |row, row_index|
    if block_given?
      yield_output = yield(row)

      data = []
      row_options = {}
      case yield_output
      when Array
        data = yield_output
      when Hash
        data = yield_output.delete(:data)
        row_options = yield_output
      else
        raise ArgumentError, "TidyTable block expects an Array or Hash, but a #{yield_output.class} was returned."
      end

      row_classes = [row_index % 2 == 0 ? 'even': 'odd', row_options[:class]].select {|i| !i.nil?}.join(' ')
      output << %(<tr class="#{row_classes}" #{"id=\"#{row_options[:id]}\"" if row_options.has_key?(:id)}>)
      data.each_with_index do |item, index|
        output << %(<td class="#{column_classes(data, index)}">#{item}</td>)
      end
    else
      output << %(<tr class="#{row_index % 2 == 0 ? 'even': 'odd'}">)
      fields.each_with_index do |field, index|
        output << %(<td class="#{column_classes(fields, index)}">#{row.send(field.to_sym)}</td>)
      end
    end
    output << "</tr>"
  end
  output << "</table>"
  output.join
end