Skip to content

dball/paginated_table

Repository files navigation

PaginatedTable

Build Status

PaginatedTable is a Rails plugin that makes rendering paginated, sorted HTML tables dead simple.

Requirements

  • rails 3.2 (3.1 may work)
  • will_paginate 3.0
  • jquery-rails 2.0

Installation

Add paginated_table to your Gemfile and bundle install.

Add the paginated_table javascript to your application's javascript requires after jquery and jquery_ujs:

//= require jquery
//= require jquery_ujs
//= require paginated_table

Usage

PaginatedTable mixes helper methods into ActionController::Base and ActionView::Base, conveniently named paginated_table.

Controller

The paginated_table helper is an instance method you can call in an action that paginates a table:

class ProductsController < ApplicationController
  def index
    paginated_table('products', Product.all,
      :defaults => { :sort_column => 'name' }
    )
  end
end

This will sort the collection using Arel's order method, paginate the given collection using will_paginate, store the page in an instance variable of the given name, e.g. @products, and if the request is AJAX, renders a partial response.

View

The paginated_table helper is an instance method you can call in a view that renders a paginated table. To work with the AJAX pagination, the call must appear in a partial with the same name as the table's instance variable, e.g. products.html.erb. Thus, we might have:

In index.html.erb:

<h1>Products</h1>

<%= render :partial => 'products' %>

and in products.html.erb:

<%= paginated_table(@products) do |table|
      table.column 'name', :sortable => false, :class => 'centered'
      table.column 'price', :style => 'font-face: bold' do |price|
        format_currency(price)
      end
      table.column 'qty', :title => 'Quantity'
    end %>

The first argument to paginated_table must be a paginated collection, or some other object conforming to the will_paginate collection interface. The second may be an options hash, including:

Name Default Effect
:model_label false Explicitly sets the :model option when calling will_paginate's page_entries_info method. This determines the string used in the phrase, "Displaying 1-10 products", where :model_label is product. The default behavior titleizes the name of the ActiveRecord model.

The table DSL provides a column method by which you describe the table. The column calls correspond to columns in the rendered table. Columns with no block send their name to the records to get their cell values, while columns with blocks yield to them the records to get their cell values.

Column options are:

Name Default Effect
:title nil Overrides the default title: the titleized column name
:sortable true Renders sort links in the column header, if present
:class nil The CSS class for the `td` elements
:style nil The CSS style for the `td` elements
:span false :all sets the colspan attribute value to the maximum number of columns in any row

Data may be rendered across multiple rows:

<%= paginated_table(@products) do |table|
  table.row do
    table.column 'name'
  end
  table.row :cycle => false do
    table.column 'description'
  end
end %>

The table description may have either rows or columns in the root, not both. Columns in the root are put into an implicit default row.

Row options are:

Name Default Effect
:cycle `%w(odd even)` Cycles the given values in the tr's class attribute
:hidden false Hides the row with an inline style attribute value of `display: none`
:title :header Renders the row's column titles. If the value is :header, they will appear in the table header, otherwise they will not appear anywhere.
:data_type false The attribute value for a data-type attribute

Any sortable column titles rendered in the table header will be linked to an sort action; it sorts the column ascending if not already sorted, otherwise sorts the column descending. The table itself will be preceded and succeeded by a wrapping header and footer div with pagination info and links. The pagination and sort links will be decorated with rails ujs remote AJAX links, the results of which overwrite the paginated_table div.

Table rows will have an attribute named data-datum-id whose value is the result of calling dom_id on the view with the datum.

Output

<div class="paginated_table">
  <div class="header">
    <div class="info">
      ... will_paginate info ...
    </div>
    <div class="links">
      <div class="pagination">
        ... will_paginate links ...
      </div>
    </div>
  </div>
  <table class="paginated">
    <thead>
      <tr>
        <th class="sortable sorted_asc">...</th>
        <th class="sortable">...</th>
      </tr>
    </thead>
    <tbody>
      <tr class="odd" data-datum-id="...">
        <td>...</td>
        <td>...</td>
      </tr>
      <tr class="even" data-datum-id="...">
        <td>...</td>
        <td>...</td>
      </tr>
      ... more rows ...
    </tbody>
  </table>
  <div class="footer">
    <div class="info">
      ... will_paginate info ...
    </div>
    <div class="links">
      <div class="pagination">
        ... will_paginate links ...
      </div>
    </div>
  </div>
</div>

Global Configuration

In an initializer, e.g. config/initializers/paginated_table.rb:

PaginatedTable.configure do |config|
  config.rows_per_page = 20
end

TODO

  • AJAX links should be optional

  • AJAX busy indicator

  • AJAX error indicator

  • Partial should infer ivar by template name?

  • Explicitly enable the :rows option

    • It really belongs in the view helper, but it's simpler to implement in the controller helper
  • Global configuration

    • AJAX links
  • :per_page request param should be allowed to be ignored or restricted to a configurable maximum

  • scope th header elements to column

  • allow column cells to render as th elements

About

Paginated table helper for rails

Resources

License

Stars

Watchers

Forks

Packages

No packages published