In one of my earlier projects, there was a requirement from product owners, to show data in grid format. It was way back in summar of 2008. We had to load the whole data by hand-coding the trs and tds in table and shown the results in html table's grid format.
Back to the current project, I did a little research and found jquery-grid-rails-plugin
I found it pretty useful and up to the mark as far as results are being displayed on the Grid (AJAX calls). You can look at the Demo as well (http://github.com/ahe/jqgrid_demo_app/tree/master), also a detailed explanation on installation and usage mentioned here -> http://www.2dconcept.com/jquery-grid-rails-plugin
The response is pretty quick, from 1000 records in DB to fetch 25 on one page it took around 500 ms. Also, you can use various JQuery themes if you do not like the default look and feel: http://jqueryui.com/themeroller
Lets take a very small example and see how to use JQgrid:
I have User controller's index method to write logic to display all users.
User model has attributes as:
id : integer (row id)
name : string
created_at : date
I have User's view (users/index.html.erb file) to display the grid with above attributes.
Steps:
1. Install plugin: $ ./script/plugin install git://github.com/ahe/2dc_jqgrid.git
2. In layout include JS and CSS for grid:
<%= jqgrid_stylesheets %>
<%= jqgrid_javascripts %>
3. In User controller:
def index
users = User.find(:all) do
if params[:_search] == "true"
name =~ "%#{params[:name]}%" if params[:name].present?
created_at =~ "%#{params[:created_at]}%" if params[:created-at].present?
end
paginate :page => params[:page], :per_page => params[:rows]
order_by "#{params[:sidx]} #{params[:sord]}"
end
respond_to do |format|
format.html
format.json { render :json => users.to_jqgrid_json([:id, :name, :created_at], params[:page], params[:rows], users.total_entries) } # total entries will get User.all.size
end
end
4. In view:
<%= jqgrid("All users", "users", users_url, # my recommendation as putting /users sometimes does not work in all cases
[ { :field => "id", :label => "ID", :width => 35, :resizable => false },
{ :field => "name", :label => "User Name" },
{ :field => "created_at", :label => "Created on" }
]
) %>
Now everything is fine, it should work fine and show us the grid with name and created at time.
Problem that I faced: When you have to show any attribute of model with formatting , there was nothing mention on the blog, like I would like to Capitalize the name here in the grid (First letter is capital).
So, I dug into the code and found my solution
Solution:
In index I have to change the format.json in index method like this:
render :json => users.to_jqgrid_json([:id, "name.capitalize", :created_at], params[:page], params[:rows], users.total_entries)
and in view I need to change following line as :
{ :field => "name.capitalize", :label => "User Name" },
and it works!
Another problem: If I need to change the format of the created_at, can I do this in controller and view?
Controller:
render :json => users.to_jqgrid_json([:id, "name.capitalize", 'created_at.strftime("%Y-%m-%d")'], params[:page], params[:rows], users.total_entries)
View:
{ :field => "name.capitalize", :label => "User Name" },
{ :field => 'created_at.strftime("%Y-%m-%d")', :label => "Created on" }
Answer is NO.
Because, the way jqgrid ruby plugin written, you cannot use method with parameters.
Solution: I used instance method.
In model, I wrote:
def formatted_created_at
created_at.strftime("%Y-%m-%d")
end
def capitalized_name
name.capitalize
end
In controller:
render :json => users.to_jqgrid_json([:id, :capitalized_name, :formatted_created_at], params[:page], params[:rows], users.total_entries)
In view:
{ :field => "capitalized_name", :label => "User Name" },
{ :field => "formatted_created_at", :label => "Created on" }
That's it!