Wise Grid plugin
Plugin details
Documentation
ruby script/plugin install http://svn.wice.eu/public/wice_grid
Installation
================
Run the following command to install the plugin:
script/plugin install http://svn.wice.eu/public/wice_grid/trunk
You will see that icon files, a javascript file and a stylesheet have been copied to +public+.
If you are installing manually, copy the files with the following command:
rake wice_grid:copy_resources_to_public
Basics
===========
Add the style declaration to the header of the page:
<%= stylesheet_link_tag 'wice_grid' %>
The simplest example of a WiceGrid for one simple DB table called ApplicationAccount is the following:
Controller:
@accounts_grid = initialize_grid(ApplicationAccount)
View:
<%= grid(@accounts_grid) do |g| g.column do |account| account.username end g.column do |account| account.active? ? 'Yes' : 'No' end g.column do |account| link_to('Edit', edit_account_path(account)) end end -%>
Code g.column do |account| ... end
defines everything related to a column in the resulting view table including column names, sorting, filering, the content of the column cells, etc.
The only obligatory parameter is the block which is called for every ActiveRecord instance in the resultset, the return value of the block being the table cell content.
In the above view code three columns were defined, all without names, no sorting or filtering is available. Still, pagination becomes active if the number of all extracted records exceeds the default number of rows per page.
Column names are defined with parameter :column_name:
<%= grid(@accounts_grid) do |g| g.column :column_name => 'Username' do |account| account.username end g.column :column_name => 'Active' do |account| account.active? ? 'Yes' : 'No' end g.column :column_name => 'Edit' do |account| link_to('Edit', edit_account_path(account)) end end -%>
To add filtering and ordering, declare to which column in the underlying database table(s) the view column corresponds using parameter :attribute_name :
<%= grid(@accounts_grid) do |g| g.column :column_name => 'Username', :attribute_name => 'username' do |account| account.username end g.column :column_name => 'Active', :attribute_name => 'active' do |account| account.active? ? 'Yes' : 'No' end g.column :column_name => 'Edit' do |account| link_to('Edit', edit_account_path(account)) end end -%>
This will magically add sorting links and filters for columns +Username+ and +Active+. The plugin automatically creates filters according to the type of the database column. In the above example a text field will be created for column Username (username is a string), while for column +Active+ a dropdown filter will be created with options 'Yes', 'No', and '--'. Read more about available filters in the documentation for the column method. Read the section about custom dropdown filters for more advanced filters.
If only sorting is needed, we can turn off filters using :no_filter :
g.column :column_name => 'Username', :attribute_name => 'username', :no_filter => true do |account| account.username end
It is important to understand that it is up to the developer to make sure that the value returned by a column block (the content of a cell) corresponds to the underlying database column specified by :attribute_name (and :model_class discussed below).
Initial Ordering
===============
Initializing the grid we can also define the column by which the record will be ordered on the first rendering of the grid, when the user has not set their ordering setting by clicking the column label, and the order direction:
@accounts_grid = initialize_grid(ApplicationAccount, :order => 'username', :order_direction => 'desc' )
Records Per Page
=================
The number of rows per page is set with :per_page:
@accounts_grid = initialize_grid(ApplicationAccount, :per_page => 20, :order => 'username', :order_direction => 'desc' )
Conditions
============
The +initialize_grid+ method supports a :conditions parameter which is passed on to the underlying ActiveRecord (via will_paginate), so it can be anything that :conditions in ActiveRecord#find can be.
A good example is substituting a common pattern like
@user_groups = @portal_application.user_groups
with WiceGrid code:
@user_groups_grid = initialize_grid(UserGroup, :conditions => ['portal_application_id = ?', @portal_application])
Queries with join tables
===================
WiceGrid also supports ActiveRecord's :joins and :include.
@products_grid = initialize_grid(Product, :include => :category, :order => 'products.name', :per_page => 20)
Note that if we want to order initially by a column from a joined table we have to specify the table and the column name with the sql dot notation, that is, products.name
To show columns of joined tables in the view table, the ActiveRecord model class name has to be specified, that corresponds to the joined table:
<%= grid(@products_grid) do |g| g.column :column_name => 'Product Name', :attribute_name => 'name' do |product| # primary table link_to(product.name, product_path(product)) end g.column :column_name => 'Category', :attribute_name => 'name', :model_class => Category |product| # joined table product.category.name end %>
Custom dropdown filters
======================
It is possible to construct custom dropdown filters. Depending on the value of column parameter:custom_filter different modes are available:
Array of strings
================
This is a direct manual definition of possible values of the dropdown. The generated dropdown list filter will contain these values together with a special value '--' (+nil+).
g.column :column_name => 'Category', :attribute_name => 'name', :model_class => Category, :custom_filter => ['Men\'s underwear', 'Women\'s underwear'] |product| product.category.name end
:auto
==================
:auto - a powerful option which populates the dropdown list with all unique values of the field specified by
:attribute_name and :model_class throughout all pages. In other words, this runs an SQL query without +offset+ and +limit+ clauses and with distinct(table.field) instead of distinct(*).
g.column :column_name => 'Category', :attribute_name => 'name', :model_class => Category, :custom_filter => :auto |product| product.category.name end
Any other symbol name (method name)
=================================
The dropdown list is populated by all unique value returned by the method with this name sent to all ActiveRecord objects throughout all pages. The main difference from :auto is that this method does not have to be a field in the result set, it is just some value computed in the method after the database call and ActiveRecord instantiation.
But here lies the major drawback - this mode requires additional query without +offset+ and +limit+ clauses to instantiate _all_ ActiveRecord objects, and performance-wise it brings all the advantages of pagination to nothing. Thus, memory- and performance-wise this can be really bad for some queries and tables and should be used with care.
An array of symbols (method names)
==============================
Similar to the mode with a single symbol name. The first method name is sent to the ActiveRecord object if it responds to this method, the second method name is sent to the returned value unless it is +nil+, and so on. In other words, a single symbol mode is a case of an array of symbols where the array contains just one element. Thus the warning about the single method name mode applies here as well. Be warned.
g.column :column_name => 'Customer Profile', :attribute_name => 'name', :model_class => CustomerProfile, :custom_filter => [:customer_profile, :name] do |shop_preference| link_to(shop_preference.customer_profile.name, shop_customer_profile_path(@shop, shop_pref.customer_profile)) end
Defaults
============
Default values like can be changed in lib/config.rb, as well grid labels and paths to some images.
Rendering filter panel
=====================
The filter panel can be shown and hidden clicking the icon with binoculars.
The way the filter panel is shown after the page is loaded is controlled via parameter :show_filters of the grid helper.
Possible values are:
* :when_filtered - the filter is shown when the current table is the result of filtering
* :always - show the filter always
* :no - never show the filter
Example:
<%= grid(@accounts_grid, :show_filters => :always) do |g| ...... end -%>
Styling the grid
================
The grid table has style class +wice_grid+ by default. The +grid+ helper accepts parameter :table_html_attrs which is a hash of HTML attributes for the table tag. If this hash contains a :class key, the default style class gets overwritten.
Another +grid+ parameter is header_tr_html_attrs which is a hash of HTML attributes to be added to the first +tr+ tag (or two first +tr+鈥榮 if the filter row is present).
:td_html_attrs is a parameter for the +column+ method setting HTML attributes of +td+ tags for a certain column.
+td+ tags also are assigned two styles automatically - +sorted+ if the column is the one by which the grid is ordered, and +active_filter+ if the column's filter is on. These two styles and a style coming from :td_html_attrs do not overwite each other, instead, they are concatenated. The resulting class might be class="active_filter sorted user_style"
Additionally, odd and even +tr+ tags are assigned styles +odd+ and +even+, correspondingly.
The css file coming with the plugin is an example defining 2 styles for ordered columns (one for the header, one for content cells), and two styles for filtered columns. Customize them to your needs.
WiceGrid icons are in directory public/images/icons/grid/.
More than one grid on a page
===========================
It is possible to use more that one grid on a page, each with its own state. To do so, you must specify the name of the grid in +initialize_grid+ using parameter :name
The name serves as the base name for HTTP parameters, DOM IDs, etc, so it is important that all grids on a page have different names. The default name is 'grid'.
The name can only contain alphanumeric characters.
@accounts_grid = initialize_grid(ApplicationAccount, :order => 'username', :order_direction => 'desc') @user_groups_grid = initialize_grid(UserGroup, :conditions => ['portal_application_id = ?', @portal_application], :name => 'grid2')
ERB mode
=============
The view helper may have two styles defined by the +erb_mode+ parameter to the +initialize_grid+ in the contoller.
By default (erb_mode = false) this is a simple helper surrounded by <%= and %>, like in all examples above.
The second style (erb_mode = true) is called ERB mode and it allows to embed any ERB content inside blocks, which is basically the style of the form_for helper, only form_for takes one block, while inside the grid block there are other method calls taking blocks as parameters:
<% grid(@countries_grid) do |g| %>
<% g.column :column_name => 'Name', :attribute_name => 'name' do |country| %>
Name: <%= link_to(country.name, country_path(country)) %>
<% end %>
<% g.column :column_name => 'Numeric Code', :attribute_name => 'numeric_code' do |country| %>
Numeric Code: <%= country.numeric_code %>
<% end %>
<% end -%>
This mode can be usable if you like to have much HTML code inside cells.
Please remember that in this mode the helper opens with <% instead of <%=, similar to form_for.
The default value for :show_filters can be changed in lib/config.rb.
Integration of the grid with other forms on page
==========================================
Imagine that the user should be able to change grid's conditions using some other control on the page, and not a grid filter.
For example, on a page showing users, change options 'Show all users' to 'Show only active users' clicking a button or a checkbox. WiceGrid allows to keep the status of the grid with all the filtering and sorting using helper +dump_filter_parameters_as_hidden_fields+ which takes a grid object and dumps all current sorting and filtering parameters as hidden fields. Just include dump_filter_parameters_as_hidden_fields(@grid) inside your form, and the newly rendered grid will keep ordering and filtering.
<% form_tag('', :method => :get) do %> <%= dump_filter_parameters_as_hidden_fields(@grid) %> <%= check_box_tag('show_all', '1', @show_all, :onclick => 'this.form.submit()') %> Show all <% end -%>
Further Documentation
There is currently no advanced documentation for this plugin.
New documentationEdit plugin | (0 older versions) | Last edited by: hardway, 5 months ago

