Greentable produces HTML tables from an array without you having to deal with any HTML elements. Greentable is an declarative approach to HTML tables and adds additional export features.
Installation
gem 'greentable'Greentable works for Rails 3.x and Rails 4.x
Usage
To produce a table from an array of elements, do the following in a view:
=greentable(users) do |gt,user|
- gt.col('NAME') do
=user.name
- gt.col('EMAIL') do
=user.emailwhich will produce the following html:
<table>
<thead>
<tr>
<th>NAME</th>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>Joe Ruby</td>
<td>jruby@example.com</td>
</tr>
<tr>
<td>Donald Rails</td>
<td>drails@example.com</td>
</tr>
</tbody>
</table>Options
Both greentable and greentable.col may be called with an optional hash
=greentable(array, class: 'table_class') do |gt, el|
-gt.col('col0', th: {class: 'th_class'}) do
=el.col0
-gt.col('col1', td: {class: 'td_class'}) do
=el.col1will produce
<table class="table_class"">
<thead>
<tr>
<th class="th_class">col0</th>
<th>col1</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td class="td_class">...</td>
</tr>
</tbody>
</table>A comprehensive example:
note how gt.col(class: 'h') below is applied to both TH and TD elements
=greentable(array, class: 'a aa', style: 'b:c', tr: {class: 'd'}, th: {onclick: 'e();'}, td: {class: 'f', 'data-target' => 'g'} ) do |gt, el|
-gt.col('col0', class: 'h', th: {class: 'i'}) do
=el.col0
-gt.col('col1', td: {class: 'j'}) do
=el.col1will produce
<table class="a aa" style="b:c">
<thead>
<tr class="d">
<th onclick="e();" class="ee h i">col0</th>
<th onclick="e();" class="ee">col1</th>
</tr>
</thead>
<tbody>
<tr class="d">
<td data-target="f" class="ff h">0</td>
<td data-target="f" class="ff j">0</td>
</tr>
</tbody>
</table>If you need column names or options to be dynamic, you can use procs:
=greentable(years) do |gt,year|
-gt.col('Year') do
=year.to_s
-4.times do |week|
-gt.col(Proc.new{ week % 2 == 0 ? 'An even week' : 'An odd week' }, td: {style: Proc.new{ year % 2 == 1 ? 'background-color:red' : nil }} ) do
=weekwill produce
<table>
<thead>
<tr>
<th>Year</th>
<th>An even week</th>
<th>An odd week</th>
<th>An even week</th>
</tr>
</thead>
<tbody>
<tr>
<td>2013</td>
<td>0</td>
<td style='background-color:red'>1</td>
<td>2</td>
<td style='background-color:red'>3</td>
</tr>
<tr>
<td>2014</td>
<td>0</td>
<td style='background-color:red'>1</td>
<td>2</td>
<td style='background-color:red'>3</td>
</tr>
...
</tbody>
</table>Counter Object
Sometimes, you'll need to know what row you're currently on. For that purpose Greentable exposes a counter object:
=greentable([x,y,z]) do |gt, el|
-gt.col('i') do
=gt.counter.i
-gt.col('first?') do
=gt.counter.first?
-gt.col('last?') do
=gt.counter.last?
-gt.col('odd?') do
=gt.counter.odd?
-gt.col('even?') do
=gt.counter.even?will produce
<table>
<thead>
<tr>
<th>i</th>
<th>first?</th>
<th>last?</th>
<th>odd?</th>
<th>even?</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>true</td>
<td>false</td>
<td>true</td>
<td>false</td>
</tr>
<tr>
<td>1</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>true</td>
</tr>
<tr>
<td>2</td>
<td>false</td>
<td>true</td>
<td>true</td>
<td>false</td>
</tr>
</tbody>
</table>Greentable Footer
Sometimes, you'll need to display a total (or whathaveyou) at the end:
=greentable(products) do |gt, product|
-gt.footer(class: 'a', style: 'border-top: 2px solid black;', tr: {class: 'footer_tr_class'}) do |footer|
-footer.col do
Total
-footer.col(style: 'font-weight: bold;') do
$3.14
-gt.col('name') do
=product
-gt.col('price') do
=product.pricewill produce
<table>
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
<tr>
<td>ProductA</td>
<td>$2.11</td>
</tr>
<tr>
<td>ProductB</td>
<td>$1.03</td>
</tr>
</tbody>
<tfoot>
<tr class='footer_tr_class'>
<td class='a' style='border-top: 2px solid black;'>Total</td>
<td class='a' style='border-top: 2px solid black; font-weight: bold;'>$3.14</td>
</tr>
</tfoot>
</table>Subtotal, shipping, tax, total? No problem:
=greentable(order.order_line_items) do |gt, order_line_item|
-gt.footer([:subtotal, :shipping, :tax, :total], class: 'klass') do |footer, attr|
-footer.col do
=attr
-footer.col do
=order.send(attr)
-gt.col('name') do
=order_line_item.name
-gt.col('price') do
=order_line_item.pricewill produce
<table>
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
<tr>
<td>ProductA</td>
<td>$2.11</td>
</tr>
<tr>
<td>ProductB</td>
<td>$1.03</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class='klass'>subtotal</td>
<td class='klass'>xyz</td>
</tr>
<tr>
<td class='klass'>shipping</td>
<td class='klass'>xyz</td>
</tr>
<tr>
<td class='klass'>tax</td>
<td class='klass'>xyz</td>
</tr>
<tr>
<td class='klass'>total</td>
<td class='klass'>xyz</td>
</tr>
</tfoot>
</table>Global Defaults
You can configure global defaults for all your greentables.
In config/initializers/greentable.rb
Greentable.configure do |config|
config.defaults = {class: 'myTableClass', tr: {class: 'myTrClass'}, th: {style: 'cursor:pointer'}, td: {class: 'pi', onclick: 'alert(3.14159265359)'}}
endand in some view:
<%= greentable([3.14]) do |gt,element| %>
<% gt.col('First Column') do %>
<%= element %>
<% end %>
<% end %>will produce
<table class='myTableClass'>
<thead>
<tr class='myTrClass'>
<th style='cursor:pointer'>First Column</th>
</tr>
</thead>
<tbody>
<tr class='myTrClass'>
<td class='pi' onclick='alert(3.14159265359)'>3.14</td>
</tr>
</tbody>
</table>Green Export & Green Printing
Greentable enables you to export or print your greentable data for download in various formats seamlessly by a rack middleware. Add a couple of http query parameters in your view and your done:
<a href="/?greentable_export=csv&greentable_id=greentable_id">Export CSV</a>
|
<a href="/?greentable_export=print&greentable_id=greentable_id">Print</a>
<%= greentable([0], :id => 'greentable_id') do |gt, el| %>
<% gt.col('i') do %>
<%= el %>
<% end %>
<% gt.col('i+1') do %>
<%= el + 1 %>
<% end %>
<% end %>Green Export and Green Printing requires Nokogiri to be installed. Add 'nokogiri' as a gem dependency to your project if you want to use greentable's export or printing feature
Available Query Parameters
- greentable_id=any string [REQUIRED]. A unique html tag id to tell the rack middleware which greentable to extract.
-
greentable_export=csv | print [REQUIRED].
csv will produce a CSV file. Headers will be the table headers. Colspans are honored (row spans are not).
print will extract the green table by id and insert a javascript snippet to print the doc
Any css styling done within the html HEAD will remain. Anything within the BODY will be replaced with the greentable content.
window.onload = function() { window.focus(); window.print(); }
- greentable_export_filename=any string [OPTIONAL]. default: 'export.csv'. Specifies the filename in the Content-Disposition header. Only used if greentable_export=csv