RORGURU.COM

Useful Information for Ruby on Rails Developers

How to use ExtJS Grid with Rails

 

30-07-2010 | Comments

ExtJS has become one of the most popular JavaScript frameworks available till date.
It is an extensive JavaScript library with numerous components like windows, trees,
layout and forms. All of these components not only look stunning but also closely
resemble with desktop applications. One of the most exciting feature of this framework
is native support for other popular JavaScript libraries like Prototype, Scriptaculous and
Jquery. With Prototype being the default choice for many of the Rails projects, ExtJS
components can be easily integrated without any additional requirements.

Among the various components provided by ExtJS, Grid is certainly one of the most
powerful thing to use with extensive data handling features like remote sorting and
pagination with inbuilt AJAX support. The Grid component can handle various data
types starting from basic array to xml and json.

Here is an example of using the Grid component with Rails. We will create a page that
displays a list of employees in a Grid. At the very begining we need to download the latest
ExtJS (2.02) from http://www.extjs.com/download and extract the zip file to organize the
dowloaded files inside our rails project folder structure. We will use the following structure
to organize ExtJS specific files:

  • ext-2.0.2/resources/images/default to /public/images
  • ext-2.0.2/resources/css/ext-all.css to /public/stylesheets/
  • ext-2.0.2/ext-prototype-adapter.js to /public/javascripts/ext
  • ext-2.0.2/ext-all-debug.js to /public/javascripts/ext/ (for production environment
    it is recomended to use ext-all.js which is the compressed version of ext-all-debug.js).
So now we should include the necessary files inside application.html.erb file to be able to access it:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML
    4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

    <html>

 
    <head>

        <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-1" />

        <title><!-- Title goes here --></title>

        <%= stylesheet_link_tag 'ext-all.css' %>

        <%= javascript_include_tag
    "prototype", "scriptaculous", "effects",
    "ext-prototype-adapter", "ext-all-debug",
    "application" %>

 
    </head>

 
    <body>

        <%= yield %>

 
    </body>


    </html>

Now the next step is to prepare the view template (employees/employees.html.erb) where
we are going to show the Grid with the list of employee data. Here we will place a div element
with id employee-grid that will be used as the underlying element of the Grid component.

<div id="employee-grid"></div>

Next we will write some JavaScript code to setup and render the Grid component. We will write
this code inside the application.js within the Ext.onReady block, so that the Grid initializes during
the page load time. In this code, first we create an Ext.data.Store object to serve as a client side data
store. In the Store object we create an Ext.data.HttpProxy to bind the url to fetch the data from the
server. We will use JsonReader for reading the data sent back by the server as JSON string. We will,
also configure the Grid with its inbuilt capabilities of remote sorting and paging.

Finally we create the Grid, rendering within the page and call the load method of the Store object to perform initial data load.

JavaScript code: application.js

Ext.onReady(function(){

// create the Data Store

var store = new Ext.data.Store({

proxy: new Ext.data.HttpProxy({

url: '/employees',

method: 'GET'

}),

// create reader that reads the
Employee records

reader: new Ext.data.JsonReader({

root: 'employees',

totalProperty: 'total',

id: 'id',

fields: [

'last_name', 'first_name', 'department', 'designation'

]

}),

// turn on remote sorting

remoteSort: true

});

store.setDefaultSort('last_name', 'asc');

// the column model has information about grid columns

// dataIndex maps the column to the specific data
field in

// the data store

var cm = new Ext.grid.ColumnModel([{

header: "Last Name",

dataIndex: 'last_name',

width: 150

},{

header: "First Name",

dataIndex: 'first_name',

width: 150

},{

header: "Department",

dataIndex: 'department',

width: 150

},{

header: "Designation",

dataIndex: 'designation',

width: 150

}]);

// by default columns are sortable

cm.defaultSortable = true;

var grid = new Ext.grid.GridPanel({

el:'employee-grid',

width:700,

height:500,

title:'Employee Records',

store: store,

cm: cm,

trackMouseOver:false,

sm: new Ext.grid.RowSelectionModel({selectRow:Ext.emptyFn}),

loadMask: true,

viewConfig: {

forceFit:true /*to auto expand the size of the columns to fit the grid width and prevent horizontal scrolling*/

},

bbar: new Ext.PagingToolbar({

pageSize: 20,

store: store,

displayInfo: true,

displayMsg: 'Displaying records {0} - {1} of
{2}',

emptyMsg: "No records to display"

})

});

// render it

grid.render();

// trigger the data store load

store.load({params:{start:0, limit:25}});

});

Now we have to write the backend code to actually serve the data to the Grid component. For this purpose we will
create a scaffold called employees with REST based actions. As we have used '/employees' for the data store with
'GET'method, Rails will automatically route this to '/employees/index' action. To interact with the database table
we will also create a model class named Employee.

The backend code will be pretty much simple as usual. We will fetch records form the table via the Employee model
class and return it to the front end as a JSON string. Rails has in-built support for JSON, so we do not require to do
anything extra for it. We also need to take care of the remote sorting on the backend as the Ext Grid component passes
the following four params when a Grid header is clicked: start, limit,sort,dir. Also for pagination, we will use
'will_paginate' plugin, as from version 2.0, Rails has dropped its inbuilt pagination support.

Controller Code: employees_controller.rb

def index

start = (params[:start] || 0).to_i

size = (params[:limit] || 20).to_i

page = ((start/size).to_i) + 1

sort =
"#{params[:sort]} #{params[:dir]}" || "id asc"

@employees = Employee.find(:all,

:page => page,

:per_page => size,

:order => sort

)

rtndata = {}

rtndata[:total] = @employees.total_entries

rtndata[:employees] = @employees.collect {|e| {

:id => e.id,

:last_name => e.last_name,

:first_name => e.first_name,

:department => e.department,

:designation => e.designation

}}

respond_to do |format|

format.json { render :json => rtndata.to_json }

end

end

Thats it! These are the basic steps needed to integrate the Ext Grid component with Rails backend.

comments

 

Leave a Comment

 
Name (required)
 
Email
(will not be published)
 
Website
 
Comments