Today, I'm going to go over a quick tutorial of some basic AJAX functions. Rails has a great implementation with AJAX right out of the box, with the Prototype library. It also includes the Scriptaculous library with some special effects. We are just going to do some basic writing text into the site without page reloading. Lets get started.
Set up the application:
rails ajaxtest -d mysql
cd ajaxtest
./script/generate model Foobar foo:string bar:string
./script/generate Controller Foobars
This is our first project that doesn't use scaffolding - I decided against it because scaffolding would have generated all kinds of views we aren't going to need for this. Notice that when you created the model, it automatically generated your DB migration file. Now, lets open up app/controllers/foobars_controller.rb and do this:
class FoobarsController < ApplicationController
def index
@foobars = Foobar.find(:all)
respond_to do |format|
format.html # index.html.erb
end
end
end
Next, create app/views/foobars/index.html.erb:
<h3>Foobars!</h3>
<table>
<tr><th>Foo</th><th>Bar</th></tr>
<% for foobar in @foobars do %>
<tr>
<td><%= foobar.foo %></td>
<td><%= foobar.bar %></td>
</tr>
<% end %>
</table>
Now lets add our routing. In config/routes.rb add:
map.resources :foobars
In your console, lets get our db created and foobars table setup:
rake db:create
rake db:migrate
And one last thing. We need to populate our table with a few foobars. This is a good time to show you the rails interactive console:
./script/console
From here, we can give commands directly to our project. Lets try one:
Foobar.find(:all)
>> Foobar.find(:all)
=> []
So it returned an empty array. The interactive console is great for playing around with bits of code to see what they do or even testing out bits of code. Lets try another command:
>> myfoobar = Foobar.new
=> #<Foobar id: nil, foo: nil, bar: nil, created_at: nil, updated_at: nil>
>>
Creates a new foobar object...
>> myfoobar.foo = "This is a test."
=> "This is a test."
>> myfoobar.bar = "This is only a test."
=> "This is only a test."
>>
We can set the values of foo and bar for our new foobar, and...
>> myfoobar.save
=> true
>>
We can save it to the database. Lets try looking it up with find...
>> Foobar.find(:all)
=> [#<Foobar id: 1, foo: "This is a test.", bar: "This is only a test.", created_at: "2008-03-21 18:24:46", updated_at: "2008-03-21 18:24:46">]
>>
Great - so far so good. Now lets create a few more foobars:
myfoobar = Foobar.new
myfoobar.foo = "Foo of foobar #2"
myfoobar.bar = "Bar of foobar #2"
myfoobar.save
myfoobar = Foobar.new
myfoobar.foo = "Foo of foobar #3"
myfoobar.bar = "Bar of foobar #3"
myfoobar.save
myfoobar = Foobar.new
myfoobar.foo = "Foo of foobar #4"
myfoobar.bar = "Bar of foobar #4"
myfoobar.save
And done. You can type exit to leave the interactive console. Start the server, browse to localhost:PORT/foobars
Tablespoon of AJAX
First thing, I'm going to tell you that if you don't have Firebug yet, go ahead and get it. It is a plugin for Firefox(you are using firefox, right? nothing against you Safari/Opera lovers..if you are using IE you have no excuses, get Firefox and get Firebug...now). Firebug is a great tool for design as well as for AJAX. The inspect mode will highlight divs under your mouse and show the corresponding html/css code in the panel below. You can also take a look at Javascript AJAX responses and more quickly debug your code. Lets create app/views/layouts/application.html.erb:
<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<%= yield :layout %>
</body>
</html>
The include tag will include (among other things) the prototype library that you need to make the AJAX calls. Now, lets head back to app/views/foobars/index.html.erb and set it up for our AJAX. Change it to this:
<h3>Foobars!</h3>
<table>
<tr>
<th>Foo</th>
<th>Bar</th>
<th>Which?</th>
<th>Links</th>
</tr>
<% for foobar in @foobars do %>
<% idstring = "foobar-" + foobar.id.to_s %>
<tr>
<td><%= foobar.foo %></td>
<td><%= foobar.bar %></td>
<td id="<%= idstring %>"></td>
<td>
<%= link_to_remote "Foo", :url =>{ :action => :set, :updatewith => foobar.foo },
:update => idstring %>
<%= link_to_remote "Bar", :url =>{ :action => :set, :updatewith => foobar.bar },
:update => idstring %>
</td>
</tr>
<% end %>
</table>
We have 2 more columns in our table now - Which? will be updated by AJAX with either the foo or the bar of our current Foobar depending on the link clicked from the Links column. In the Links column, we have 2 link_to_remote 's. link_to_remote generates all the javascript calls to send an AJAX request back to our controller on the server. The first argument is what will be displayed for the link. In :url, we define the action to send the request to (:set), as well as the string we want to pass into the function (:updatewith). Last, :update will be the name of the div we will be updating. You can also add another parameter, :position. For example, :position => :before would insert whatever you are sending before the td tag, :after would be after it, :top would insert it inside the td, above anything else, and :bottom inserts it inside the td, at the bottom. If you do not specify a position(like we are doing), it will simply over-write what is inside the div. One more thing to do; lets open up app/controllers/foobars_controller.rb and add in our :set action:
def set
render :text => params[:updatewith]
end
Go back to the page and try clicking the links
Update: I found this link to be very helpful with different ways of using render with AJAX.
And we are done! Thanks for visiting, and see you next time.
16 comments:
OH MY, you are hero!!!
Thanks a lot for this great introduction to Ajax.
Informative post, thanks. A heads up, the equivalent of firefox's firebug for Safari is webkit, http://webkit.org/.
Short and sweet.
Both your tutorial and the Ruby-Ajax integration it demonstrates.
I'd like to add my applause.
Really nice tutorial for beginners like me :)... Can you also tell us how to dynamically bring data while the user is typing a text (like suggestions in google search) ?
@Pratik Rails has AJAX helpers for this, the observe_field function would be of interest for you with this.
http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html
If i wanted to save the text being displayed under 'Which?' how would i go about doing that. In other words, i'm wondering how i would go about databasing the value that is being displayed there. Thanks for a great blog!
Just started learning Ajax and it's difficult to find simple examples on the net.
Thanks you for this one !
Was hoping you could post more ?
Thank you very much for your time, it helps me a lot.
That's awesome! Easy to understand, quick to reproduce. Thank you very much for this tutorial.
In order to get this 100% working, add this in routes.rb instead of the one in the article:
map.resources :foobars, :collection => {:set => :post}
Short and easy
What a sweet and cute little independent tutorial focussing only on the AJAX of Rails!!!!!
Great Job1
This code didn't work on my PC, please repost the formulas, I'm near to become mad about this stuff.
Post a Comment