We’re implementing a new way to quickly view your data in table form. Currently, we use our own paging and plain table solution, but we wanted richer control. Enter Dojo Grid. Of the many features, scrollable paging, sorting, and user-resizable columns are all marked improvements over our existing plain and simple table.
I’m working off of nightly development builds of dojo. I'm using the latest dojox.grid.DataGrid class, paired with the dojox.data.JsonRestStore data store since Rails definitely plays quite nicely with both JSON and REST.
The next snippet is just an example from show.html.erb for data sets:
<%= stylesheet_link_tag '/javascripts/dojotoolkit/dojox/grid/resources/tundraGrid.css' %>
<style type="text/css">
#grid {
border: 1px solid #ccc;
width: 100%;
height: 30em;
}
</style>
<%= javascript_include_tag 'dojotoolkit/dojo/dojo', :djConfig => 'isDebug: false, parseOnLoad: true' %>
<script type="text/javascript">
dojo.require("dojox.data.JsonRestStore");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.parser");var columns = <%= @data_set.columns.to_json %>;
var view1 = {
cells: [
columns.map(function(c) {
return { name: c.name, field: 'c_' + c.id };
})
] };
var layout = [ view1 ]; var url = '<%= formatted_data_set_rows_path @data_set, :json %>';
var store = new dojox.data.JsonRestStore({target: url});
</script>
<div class="tundra">
<div id="grid" dojoType="dojox.grid.DataGrid" store="store" structure="layout" jsId="grid" rowsPerPage="40"></div>
</div>
The view includes the dojo.js file along with passing it a parseOnLoad: true dojoConfig parameter, which instructs dojo to parse the HTML of the page and look for dijit-type HTML to parse and execute. The div with the dojoType attribute is recognized and a new DataGrid object is instantiated and assigned to a javascript variable named grid. The store is also set to the JsonRestStore from the script, which is pointed at the route /data_sets/:id/rows.json. This is set up to route to the rows controller in routes.rb:
map.resources :data_sets do |data_sets|
data_sets.resources :rows
end
The following code from the rows controller shows how to handle different pagination requests, responding to a Range header along with page and per_page request parameters.
class RowsController < ApplicationController
def index
@data_set = DataSet.find params[:data_set_id]
@rows =
if request.headers['Range']
headers['Content-Range'] = "/#{@data_set.rows.count}"
_, s, e = request.headers['Range'].match(/items=([^-]*)-(.*)/).to_a
@data_set.rows.find :all,
:offset => s.to_i, :limit => (e.to_i - s.to_i + 1)
else
@data_set.rows.paginate :all,
:page => params[:page], :per_page => params[:per_page]
endrespond_to do |format|
format.json { render :json => @rows }
end
end
end
Most people have probably seen the page and per_page parameters along with the will_paginate plugin, since it's an old hat for most Rails developers. Dojo uses new Range and Content-Range headers (via the JsonRestStore class) to request different pages of the data. When the DataGrid makes the first request for data, it looks for a Content-Range response header that tells it how many total rows are available. It will use the Range request header to specify which set of rows it wants to load at any given time. Nifty.
Unfortunately, I can’t link to a fully working example as this work-in-progress grid is still in development and not deployed yet. But in near-future blog posts, I’ll be adapting this example to do server-side sorting and RESTful cell editing.
This looks fantastic, I have been meaning to try to get JsonRestStore working with Rails. If there are changes or if there is a subclass of JsonRestStore that should be created to ease the use of JsonRestStore with Rails/ActiveResource, please let me know. I would really like to get more comprehensive support for Rails with JsonRestStore in Dojo 1.3, and would gladly help to get improvements into the Dojo codebase. Let me know if there is anything I can do to help and disseminate info about JsonRestStore + Rails.
Posted by: Kris Zyp | September 09, 2008 at 09:31 PM
I don't know a great deal about RoR or Groovy on Grails, apart from some very basic principles. Would it be plausible to port this to GoG? This is of interest to me since I'm considering taking existing Java code and plugging it into the GoG framework. AIUI, vanilla Java can be used from GoG. I'm currently using dojo+jabsorb(+JS+CSS+w3c DOM, of course), and I'd probably want to continue using jabsorb for some things, but this seems to provide a nice simple way to expose data in a dojo grid control.
Posted by: someone | October 15, 2008 at 06:30 AM
Also, would this be any use for AJAX submission of forms in (G)rails, e.g. for back-end validation?
Posted by: someone | October 15, 2008 at 06:32 AM
Hm. Well I found these. Will review later. Perhaps they'll be of interest to someone else, too.
http://agileice.blogspot.com/2008/09/rendering-complex-collections-as-json.html
http://www.nabble.com/enums-in-RESTful-services-td19195349.html
http://www.jroller.com/prpatel/entry/scaffolding_with_dojo_grid_and
Posted by: someone | October 15, 2008 at 07:43 AM
Also you can use dojox.grid.GridPaginator if you want leaf over data in dojo grid
http://yaildar.blogspot.com/2009/07/dojo-how-to-list-data-dojox-grid.html
Posted by: Ildar | August 07, 2009 at 09:30 AM