header image

jq.png I needed to add an AJAX grid/table component with all the bells and whistles (AJAX sorting, pagination, multiple row select, AJAX add/delete etc) to an application I am working on right now (will blog about it when we roll out a good-enough version). We are using jQuery so I started looking for a suitable plugin.

I believe I have found it - it’s called jqGrid and it’s super sexy, feature rich and the documentation is on par with a commercial tool - so I created a Rails plug-in enabling you to add it to your Rails app in no time! Follow the 10 steps below to find out how.

  1. Create a blank Rails app (in your home dir - or change the path in the next step):

    1. rails -d mysql grid_test

  2. install jQuery:

    1. curl http://jqueryjs.googlecode.com/files/jquery-1.2.6.pack.js > ~/grid_test/public/javascripts/jquery.js

  3. install jquery_grid_for_rails - I am using giternal (how to install), so this is what you need to do in this case: open config/giternal.yml and enter:

    jquery_grid_for_rails:
      repo: git://github.com/scrubber/jquery_grid_for_rails.git
      path: vendor/plugins
    

    then run

    1. giternal update

    (obviously you can use script/plugin, git submodules, piston, braid or whatever floats your boat)

  4. Generate a migration to test out stuff with:

    1. script/generate resource person
    1. class CreatePeople < ActiveRecord::Migration
    2.   def self.up
    3.     create_table :people do |t|
    4.       t.string :first_name, :last_name, :title, :i_can_has_cheezburger
    5.     end
    6.   end
    7.  
    8.   def self.down
    9.     drop_table :people
    10.   end
    11. end

  5. generate dummy data

    1. script/generate migration create_dummy_people_data_migration
    1. class CreateDummyPeopleDataMigration < ActiveRecord::Migration
    2.   def self.up
    3.     Person.create :first_name =>"He", :last_name => "Man", :title => "Hero", :i_can_has_cheezburger => "Sure"
    4.     Person.create :first_name =>"Bat", :last_name => "Man", :title => "Mr.", :i_can_has_cheezburger => "Yeah"
    5.     Person.create :first_name =>"Cat", :last_name => "Woman", :title => "Ms.", :i_can_has_cheezburger => "Yes"
    6.     Person.create :first_name => "Super", :last_name => "Man", :title => "d00d", :i_can_has_cheezburger => "Nope"
    7.     Person.create :first_name => "Spider", :last_name => "Man", :title => "Mr.", :i_can_has_cheezburger => "Meh"
    8.     Person.create :first_name => "Chuck", :last_name => "Norris", :title => "Sir", :i_can_has_cheezburger => "Who is asking?"
    9.     Person.create :first_name => "G.I.", :last_name => "Joe", :title => "Sgt", :i_can_has_cheezburger => "What is a cheezeburger?"
    10.   end
    11.  
    12.   def self.down
    13.     Person.destroy_all
    14.   end
    15. end

  6. Time to run the migrations!

    Set up the db first:

    1. rake db:create

    run teh migrations:

    1. rake db:migrate

  7. Set up the controller (PeopleController) - add this method:

    1. def grid_data
    2.     @people = Person.all(:order => "#{params[:sidx]} #{params[:sord]}")
    3.  
    4.     respond_to do |format|
    5.       format.xml { render :partial => ‘grid_data.xml.builder‘, :layout => false }
    6.     end   
    7.   end

  8. Modify config/routes.rb to look like

    1. map.resources :people, :collection => {:grid_data => :get}

  9. This goes into your application layout (create a new file - views/layouts/application.html.erb):

    1. <html>
    2.     <head>
    3.         <title>jqGrid Test App - w00t!</title>
    4.         <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    5.         <%= javascript_include_tag ‘jquery’ %>
    6.         <%= include_jquery_grid_javascript %>
    7.         <%= include_jquery_grid_css %>
    8.     </head>
    9.     <body>
    10.         <%= yield %>
    11.     </body>
    12. </html>

  10. The last step: views (views/people/griddata.xml.builder, views/people/index.html.erb)

    1. xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
    2. xml.rows do
    3.   xml.page params[:page]
    4.   xml.total_pages (@people.size.to_i / params[:rows].to_i)
    5.   xml.records{@people.size}
    6.   @people.each do |u|
    7.     xml.row :id => u.id do
    8.       xml.cell u.title
    9.       xml.cell u.first_name
    10.       xml.cell u.last_name
    11.       xml.cell u.i_can_has_cheezburger
    12.     end
    13.   end
    14. end
    1. <%= jquery_grid :sample, {:url => grid_data_people_url } %>
    2.   <center>
    3.     <div style="background :black; color:white; width:518px;">My cool AJAX grid!</div>
    4.     <%= jquery_grid_table %>
    5.     <%= jquery_grid_pager %>
    6.   </center>

  11. That’s it! Start script/server, point your app to http://localhost:3000/people and if you did everything according the tutorial, you should (hopefully) see something like this:

    ajax_grid.png

    I have uploaded the app to github, be sure to check it out (WARNING - don’t copy and paste from the above code, the code highlighting plugin has some problems and you’d get strange results. Clone the repo instead).

    Note that the installed plug-in is included in .gitignore so you have to run “giternal update” after you clone it.

    Drop me a comment if you experience any problems!



    If you liked the article, subscribe to the feed   and follow me on twitter!.


          

33 Responses to “Add a powerful AJAX Table to your Rails Application in 5 minutes”

  1. jason white Says:

    thank you for the outstanding tutorial

  2. peter Says:

    @jason: Glad you liked it!

  3. Web 2.0 Announcer Says:

    Add a powerful AJAX Table to your Rails Application in 5 minutes…

    [...]Full tutorial: adding a powerful jQuery table to a Rails application step by step, from scratch to viewing app in your browser. Includes full source code.[...]…

  4. Ali Says:

    Thanks. Very useful

  5. Ali Says:

    However I get the following error:

    Errno::ENOENT in People#index

    No such file or directory - /home/…./grid3/config/jquery_grid/sample.yml

    2: <%= jquerygrid :sample, {:url => griddatapeopleurl } %>

  6. peter Says:

    Ali… indeed, the file /config/jquery_grid_sample.yml is missing for some reason - please clone the example app repo (git clone git://github.com/scrubber/jquery_grid_for_rails_sampleapp.git) and copy it from there.

    Strange though that it is missing…

  7. links for 2008-12-13 « pabloidz Says:

    [...] Add a powerful AJAX Table to your Rails Application in 5 minutes Ruby, Rails, Web2.0 (tags: rails ajax jquery) [...]

  8. Ali Says:

    That’s what I’ve done. I’ve solved the problem by copying the jquery_grid in config folder of the project.

    Thanks Peter

  9. Ali Says:

    Hi Peter.

    How do you do to delete a row?

    I’ve tried with :function_onclickSubmit: “(params){alert(’kos’); }” with no results.

    Thanks

  10. Bala Paranj Says:

    What values should I pass for sidx and sord ? Thanks.

  11. peter Says:

    @Bala: sord can be ‘asc’ or ‘desc’. sid should be the column name.

  12. Heath Morrison Says:

    Thanks for this tutorial! It has been helpful.

    Step 10 instructs you to create “views/people/griddata.xml.builder”, which is not the file referenced by the controller. This should be “views/people/_grid_data.xml.builder”. (Note: I attempted to paste the correct filename here in the blog comment, but the blog is treating the leading underscore as an escape character. Heh. I used an HTML escape to render things properly…)

    I tried giternal as you suggested, but also ran into the sample.yml problems. I was also missing the CSS and JS files in my public/ dir. I went with script/plugin instead, which correctly copied all these files for me.

    Thanks again!

  13. Doug Peterman Says:

    The tutorial is great. I was able to get the grid up and running in no time. I did struggle getting the editing features to work until I found this article on how to automatically embed the authenticity token.
    Rails-Authenticity-token-with-jquery

  14. Thomas Reitz Says:

    “Excellent point! I read most of your article and establish it great. The points you furnished in your article are magnificent. I am actually waiting for your following conceived of.

    Thanks and best of luck!”

  15. Peter Marx Says:

    Man - this tutorial really helped. Good Job! Got it up and running easily.
    If I now could find a example REST-App which allows to add/delete rows and to edit/select cell data/pulldowns I’d be happiest man in the world.
    I tried to do this in Dojo and jmaki but it didn’t work. Jsgrid looks easier to cope with.

    Do you know about an display/edit app ?

  16. peter Says:

    Peter,

    Sure - check this out: http://codetunes.com/2008/12/08/rails-ajax-and-jquery/

  17. Peter Marx Says:

    ooooook……
    thanks for the link. It’s written for experienced web programmers. Tried it , but as a pure Rails and man and Ajax newbee i can’t transfer his hints onto your example to get a RESTful grid. The leap from readonly to full edit seems to be as high as with Dojo. Do you have any more idea where to look ? Thanks in advance.

  18. Peter Szinek Says:

    Not really… I am planning to create a second part of this tutorial, which would include the stuff you are requesting. Now that I know that people would need it (you are not the first, and most probably not the last one to ask for this) I might force myself to write part II…

  19. Peter Marx Says:

    yes please! should i convince your boss (or wife) ?
    Even in books you can’t find full-blown railish examples. Best i found online today for php was

    http://www.trirand.com/jqgrid/jqgrid.html

    there is still not enough love for RoR in the world..

  20. Peter Szinek Says:

    hehe, my wife is also my boss, kinda (my pair programming partner and officially the CEO of our LLC) so at least you don’t have to hassle with more people :-)

    Ok, I’ll look into it during the weekend, I guess a mid-week blog post sounds realistic (or next weekend… or something :-) don’t like to make promises as I am mega-swamped w/ ‘real’ work ;-)

  21. Peter Marx Says:

    great! I’m looking forward to it!

  22. david Says:

    Is there any working demo on using yield, Ajax for dynamic content? or a Dynamic Help System.

    Regards.

    David

  23. Steffen Says:

    Hi, thanks very much for the tutorial! I tried to use it for my own program but I can’t get it to display the data. If i go to http://127.0.0.1:3000/planets it only shows me the table heading.

    If I go to http://127.0.0.1:3000/planets/grid_data however it does show the correct information (tho it complains “This XML file does not appear to have any style information associated with it. The document tree is shown below.” but I think that is normal).

    I’ve tried various things but I just can’t get it to work :(
    Any chance someone can take a look at this and tell me where I’m going wrong, or give some hints?

    Here’s what I think are the most relevant bits of the source files:
    app/views/planets/index.html.erb:

    <%= jquerygrid :sample, {:url => griddataplanetsurl } %>

    using this doesnt work either: <%= jquerygrid :sample, {:url => “http://127.0.0.1:3000/planets/griddata” } %>

    Planets - Uni40.org
    <%= jquerygridtable %>
    <%= jquerygridpager %>

    app/controllers/planets_controller.rb:

    [...]
    def grid_data
    params[:sidx]=:id
    params[:sord]=”asc”
    params[:rows]=20
    @planets = Planet.all(:order => “#{params[:sidx]} #{params[:sord]}”)

    respond_to do |format|
      format.xml { render :partial => 'grid_data.xml.builder', :layout => false }
    end
    

    end
    [...]

    app/views/layouts/application.html.erb:

    Railpot in Ajax

    app/views/planets/griddata.xml.builder:

    xml.instruct! :xml, :version=>”1.0″, :encoding=>”UTF-8″
    xml.rows do
    xml.page params[:page]
    xml.totalpages(@planets.size.toi / params[:rows].toi)
    xml.records{@planets.size}
    @planets.each do |u|
    xml.row :id => u.id do
    xml.cell u.universe
    id
    xml.cell u.playername
    xml.cell u.galaxy
    no
    xml.cell u.systemno
    xml.cell u.planet
    no
    end
    end
    end

  24. Steffen Says:

    Ok the comment function kinda crippled my code so I put it up as an archive: http://94.192.245.178:3000/railpot2009-02-171121.tar.bz2

  25. Steffen Says:

    lol it crippled my link as well. here it is without any underscores in the filename: http://94.192.245.178:3000/railpot-2009-02-17-1121.tar.bz2

  26. juliet Says:

    a bit too complicated for a person like me who is not a computer literate but very clever if it works for some, not for me though good luck to the person who created it.

  27. Farida Says:

    I am dying to take this for a drive except …

    I installed the it as a plugin:
    script/plugin install git://github.com/scrubber/jquerygridfor_rails.git

    no errors

    created everything. run it, got error: undefined method `jquerygrid’ for #
    rechecked the code yup - included jquery in view/layout/application.html.erb file
    <%= javascript
    includetag ‘jquery’ %>
    <%= include
    jquerygridjavascript %>
    <%= includejquerygrid_css %>

    checked the vendor/plugin folder - yup - it’s there - but it’s empty.

    I am a newbie. Tried to get giternal - link that you provided gone, so found giternal by Pat Maddox. Don’t know what to do with it since there are no install instructions. Darn.
    http://github.com/pat-maddox/giternal/tree/master

    So I download the scrubber jquery from github, untarred it, and copied the jquery folder from config into my app. No dice. same error.

    I am sure that I am making a foolish error somewhere - any ideas?

    TIA, Farida

  28. Farida Says:

    Tried using the giternal posted by Pat Maddox on github: http://github.com/pat-maddox/giternal/tree/master

    Any help about what to do after the downloading. I tried:

    gem sources -a http://gems.github.com
    gem install giternal
    giternal update

    C:grid_test>giternal update
    C:/ruby/lib/ruby/gems/1.8/gems/giternal-0.0.2/bin/../lib/giternal/repository.rb:
    23:in update': Directory 'jquery_grid_for_rails' exists but is not a git reposi
    tory (RuntimeError)
    from C:/ruby/lib/ruby/gems/1.8/gems/giternal-0.0.2/bin/../lib/giternal/a
    pp.rb:8:in
    update’

    TIA, Farida

  29. Farida Says:

    Hi,

    Dan Croak helped me out. He said to get the it:
    http://github.com/scrubber/jquerygridfor_rails (click the “download”
    button)

    and save it to vendor/plugins
    I did it and renamed the file jquerygrid. Then I copied over the config/jquerygrid folder with the sample.

    Yeah - no errors. Darn - no grid either. More head scratching. Checked above code. Yup looks good. Did change the file name like Heath said because it was rendering partial. He also mentioned about plugin install - but being a newbie I was not exactly what to do.

    Any suggestions what I screwed up? View source shows that it is getting:
    var lastsel2;
    jQuery(document).ready(function(){
    jQuery(”#sample”).jqGrid({
    imgpath: “/stylesheets/jqGrid-themes/basic/images”,
    pager: jQuery(’#samplepager’),
    mtype: “GET”,
    onSelectRow: function(id) {
    if(id && id!==lastsel2) { $(’#sample’).restoreRow(lastsel2); $(’#sample’).editRow(id,true); lastsel2=id; }
    },
    datatype: “xml”,
    sortname: “first
    name”,
    colNames: ["title", "first name", "last name", "i can has cheezburger?"],
    sortorder: “desc”,
    colModel: [{"editable": true, "index": "title", "name": "title", "width": 40}, {"editable": true, "index": "firstname", "name": "firstname", "width": 130}, {"editable": true, "index": "lastname", "name": "lastname", "width": 130}, {"editable": false, "index": "icanhascheezburger", "name": "icanhascheezburger", "width": 200}],
    rowNum: 10,
    url: “http://localhost:3000/people/grid_data”
    });
    });

    Thanks, Farida

  30. Farida Says:

    Tried http://localhost:3000/people/grid_data

    Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 1: SELECT * FROM people ORDER BY

    tried grid_data with a comma
    @people = Person.all(:order => “#{params[:sidx]}, #{params[:sord]}”)

    same error with a comma in it ORDER BY ,

    hmm. Any suggestions where I went wrong?
    Thanks, Farida

  31. Bob Walsh Says:

    What happens if you want to use this plugin for two or more grids in the same view?

    Since this specifies the grid in the view:
    <%= jquerygridtable %>
    <%= jquerygridpager %>

    How can you specify a second grid?

  32. RussK Says:

    Thanks for the great demo. I had a problem that I fixed, but I don’t understand why I had the problem. I’m using RadRails in Eclipse. I loaded the jquerygridforrails plugin using git, and everything appeared under vendor/plugins/jquerygridforrails. But when I ran the app, it couldn’t find any of the javascript or stylesheets. When I compared my code to the demo code on github, I saw that these files were directly in the app’s public javascripts and stylesheets directories. When I copied these directories from the plugin to my app, everything worked. My question is why wouldn’t my app load from the vendor/plugins directory? Is there a configuration change I need to make to tell it to do that?

  33. kate Says:

    Anybody tried to use this w/ will_paginate? The “next” icon doesn’t work.
    Please advice.

Leave a Reply




Bad Behavior has blocked 705 access attempts in the last 7 days.