README.md
# DataTable
[![veracross/data-table](https://circleci.com/gh/veracross/data-table.svg?style=shield)](https://app.circleci.com/pipelines/github/veracross/data-table)
[![Code Climate](https://codeclimate.com/github/veracross/data-table.svg)](https://codeclimate.com/github/veracross/data-table)
DataTable renders collections (an array of hashes or ActiveRecord models) as HTML tables.
## Install
```ruby
gem install data-table
```
or, in your Gemfile
```ruby
gem 'data-table'
```
### Basic Usage
the normal usage is to call the `DataTable.render()` method and pass it a collection. The method also takes a block which can be used to configure the table. The column method takes a symbol for the first parameter. If the symbol matches a key in the @collection, then that value is printed in the cell.
```ruby
DataTable.render(@collection) do |t|
t.column :column_1, "Title"
t.column :column_2, "Title 2"
end
```
### Custom Cell Renderer
Sometimes you want to use Ruby code to customize the value for a cell. This can be done by passing a block to the .column method
```ruby
DataTable.render(@collection) do |t|
t.column :column_id, "Title" do |value, row, row_index, column, column_index|
"The value is: #{value}"
end
end
```
You don't need to pass in all of the block parameters; just the ones up to the one you need.
**Tip** The column_id doesn't need to be an actual key in the collection. You can just make up an arbitrary column id and use the block renderer to customize the value for a column.
### All Table Configuration Options
id: the html id
title: the title of the data table
subtitle: the subtitle of the data table
css_class: an extra css class to get applied to the table
empty_text: the text to display of the collection is empty
display_header => false: hide the column headers for the data table
alternate_rows => false: turn off alternating of row css classes
alternate_cols => true: turn on alternating of column classes, defaults to false
### Totals
It is possible to setup totals & subtotals. Total columns take the name of the column that should be totaled. It is also possible to specify multiple total and subtotal columns.
They also take a default aggregate function name and/or a block.
* If only a default function is given, then it is used to calculate the total
* If only a block is given then only it is used to calculated the total
* If both a block and a function are given then the default aggregate function is called first then its result is passed into the block for further processing.
```ruby
DataTable.render(@collection) do |t|
t.column :column_1, "Title"
t.column :column_2, "Title 2"
t.column :column_3, "Title 3"
# Use a default function and no block.
t.total :column_1, 0, :sum
# Pass only a block and an index
t.total :column_2, 1, do |values|
# custom methods here
end
# Pass a default function and a block
t.total(:column_3, 2, :sum) do |aggregate_total|
format_money(aggregate_total)
end
end
```
Possible default functions: `:sum`, `:avg`, `:min`, `:max`
### Sub Totals
SubTotals work in a similar way to Totals. The main difference is that you need to call group_by to specify the different subtotal groupings.
When configuring more than one subtotal column the index parameter is required
```ruby
DataTable.render(@collection) do |t|
t.column :column_1, "Title"
t.column :column_2, "Title 2"
t.column :column_3, "Title 3"
t.column :column_4, "Title 4"
t.group_by :column_1
t.subtotal :column_2, 0, :sum
t.subtotal :column_3, 1, :max
end
```
It is possible to use `group_by` on its own without subtotaling.
### Multiple Groups and Sub Totals
It is also possible to combine multiple `group_by` with multiple `subtotal`. In this
scenario you must specify a `level` for each group by passing an integer value.
When only specifying a group you may omit `level`.
```ruby
DataTable.render(@collection) do |t|
t.column :column_1, "Title"
t.column :column_2, "Title 2"
t.column :column_3, "Title 3"
t.group_by :column_1, 0
t.group_by :column_2, 1
t.subtotal :column_3, 0, :sum
t.subtotal :column_3, 0, :sum
end
```
You can also combine subtotals & totals in the same table.
## Credits
Nearly all of the code for this was written by @smerickson, and later gemified by @sixfeetover.