Ajax on Rails
Pages: 1, 2
Using form_remote_tag
The form_remote_tag() helper is similar to
link_to_remote() except that it also sends the contents of an HTML
form. This means that the action handler can use user-entered data to formulate
the response. This example displays a web page that shows a list and an
Ajax-enabled form that lets users add items to the list.
My view template (index.rhtml) looks like:
<html>
<head>
<title>Ajax List Demo</title>
<%= javascript_include_tag "prototype" %>
</head>
<body>
<h3>Add to list using Ajax</h3>
<%= form_remote_tag(:update => "my_list",
:url => { :action => :add_item },
:position => "top" ) %>
New item text:
<%= text_field_tag :newitem %>
<%= submit_tag "Add item with Ajax" %>
<%= end_form_tag %>
<ul id="my_list">
<li>Original item... please add more!</li>
</ul>
</body>
</html>
Notice the two parts in bold. They define the beginning and end of the form.
Because the form started with form_remote_tag() instead of
form_tag(), the application will submit this form using
XMLHttpRequest. The parameters to form_remote_tag() should look
familiar:
- The update parameter specifies the id of the DOM element with content to
update by the results of executing the action--in this case,
my_list. - The url parameter specifies the server-side action to call--in this case,
an action named
add_item. - The position parameter says to insert the returned HTML fragment at the top
of the content of the
my_listelement--in this case, a<ul>tag.

Figure 4. Before adding any items
My controller class looks like:
class ListdemoController < ApplicationController
def index
end
def add_item
render_text "<li>" + params[:newitem] + "</li>"
end
end
The add_item action handler constructs an HTML list item
fragment containing whatever text the user entered into the
newitem text field of the form.

Figure 5. After adding several new list items
Using Observers
Rails lets you monitor the value of a field and make an Ajax call to an action handler whenever the value of the field changes. The current value of the observed field is sent to the action handler in the post data of the call.
A very common use for this is to implement a live search:
<label for="searchtext">Live Search:</label>
<%= text_field_tag :searchtext %>
<%= observe_field(:searchtext,
:frequency => 0.25,
:update => :search_hits,
:url => { :action => :live_search }) %>
<p>Search Results:</p>
<div id="search_hits"></div>
This code snippet monitors the value of a text field named
searchtext. Every quarter of a second, Rails checks the field for
changes. If the field has changed, the browser will make an Ajax call to the
live_search action handler, displaying the results in the
search_hits div.
You can see an actual demonstration of this live search on my weblog. The search box is in the upper-right corner. Try typing enterprise or rails and
see what you get.
To Use or Not Use (Ajax, That Is)
When you use Ajax techniques to update portions of a web page, the user gains responsiveness and fluidity. However, the user also loses the ability to bookmark and to use the browser's back button. Both of these drawbacks stem from the same fact: the URL does not change because the browser has not loaded a new page.
Don't use Ajax just because it's cool. Think about what makes sense in your web app's user interface.
For example, if a web page displays a list of accounts with operations on the displayed list like adding, deleting, and renaming accounts, these are all good candidates for Ajax. If the user clicks on a link to show all invoices that belong to an account, that's when you should display a new page and avoid Ajax.
This means that the user can bookmark the accounts page and invoices page, and use the back and forward buttons to switch between them. The user can't bookmark the operations within one of these lists or use the back button to try to undo an operation on the list (both of which you would probably want to prevent in a traditional web app, as well).
Odds 'n' Ends
I'd like to bring a couple of really cool things to your attention, but I won't be going into any detail.
Web pages that upload files are often frustrating to users because the user receives no feedback on the status of the upload while it progresses. Using Ajax, you can communicate with the server during the upload to retrieve and display the status of the upload. Sean Treadway and Thomas Fuchs have implemented a live demonstration of this using Rails and a video on how to implement it.
The Prototype JavaScript library that Rails uses also implements a large number of visual effects. The Effects Demo Page has a live demonstration of these effects along with JavaScript calls to use them
You can find more detailed information about these and other Ajax features of Rails in Chapter 18 of Agile Web Development with Rails.
Parting Thoughts
The Web has come a long way since the days of isolated web sites serving up static pages. We are slowly moving into a new era where sites are dynamically interconnected, web APIs allow us to easily build on top of existing services, and the web user interface is becoming more fluid and responsive. Ajax not only plays an important role in this emerging Web 2.0 saga, but also raises the bar on what people will consider to be an acceptable web application.
By all rights, adding complex Ajax features to a web application should be a lot of extra work, but Rails makes it dead simple.
Resources
Web sites
- Official Ruby home page
- Official Ruby on Rails home page
- Rails Ajax API
- Download the Rails source code used to create the screenshots in this article.
Mailing lists
Curt Hibbs has been a consultant to well-known companies like Hewlett Packard, Intuit, Corel, WordStar, Charles Schwab, Vivendi Universal, and more. He now works as a Senior Software Engineer for The Boeing Company in St. Louis.
Return to ONLamp.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 56 of 56.
-
example
2009-04-15 00:50:44 Rafa1970 [Reply | View]
for beginners, The render_text method is old, now you have ti use
render :text => "The time is " + DateTime.now.to_s + "
"
and
render :text => "when3 The time is " + DateTime.now.to_s + "
"
-
Live Search
2006-11-20 09:51:22 Calleja [Reply | View]
Hi, im trying Live Search, in my template:
Live Search: <input type="text" name="texto" />
<%= observe_field( :texto,
:frequency => 0.25,
:update => "search_hits",
:with => "texto",
:url => { :action => :resultados })%>
<div id="search_hits"></div>
In my controller, can I do this?:
def resultados
live=@params[:texto]
@nombres=Receta.find_all["titulo=?",live]
@nombres.each do |nom|
render_text nom.titulo
end
end
Appears me an error: cannot convert String into Integer
How can i to read @nombres? Thanks
-
how to load xmls in rubyonrails
2006-08-24 05:20:54 xmls [Reply | View]
we may have to right a program to export the data into an xml, then write
another program to import it.
Specifically look how to load xmls and write to xmls, are there nay plugins or
whatever.
-
Def index...needed?
2006-07-31 11:41:07 Damaris [Reply | View]
In the first page you add a
def index
end
to tell the controller you have your own index view. I guess you don't need that. Rails tests always if it can render an index.rhtml of the user when you type /demo/index before rendering its own view templates.
(I think this answers my own question posted in http://www.oreillynet.com/cs/user/view/cs_msg/84357)
I have tested and it works with the def index.
-
Problems with draggable_element
2006-04-21 04:28:40 pjazzlg [Reply | View]
I am playing around with the Ajax function draggable_element in Ruby
and having an interesting problem. I have the revert option set to true
(:revert=>true), The element I want to drag is dragged successfully,
but I cannot get it to stop dragging unless I double-click.
Once it stops dragging, it does not revert to its original position,
but remains where it was located at the time of the double-click.
Not sure what to look for next. Any help will be appreciated.
Thanks -
Problems with draggable_element
2006-05-03 06:38:39 kysen [Reply | View]
Hi,
I used the sample code from the cart shop demo (http://demo.script.aculo.us/shop) and found the same problem than pjazzlg. What is amasing is that I did an new test application using "draggable_element" over a component which worked yesterday. But now the element is sticked to my mouse and I need to double-click to stop the dragging!! Did I miss something or is there a bug?? -
Problems with draggable_element
2006-04-21 06:06:40 Curt Hibbs |
[Reply | View]
I can't give you a specific answer, but I can report that draggable_element is working for me.
What you might want to try is to take the code from one of the demos that use draggable_element and then start modifying it to become more like what you want, while testing after each step to make sure it still works.
You can find them here:
http://wiki.script.aculo.us/scriptaculous/show/HomePage
-
correct code
2006-04-19 03:05:46 gvlx [Reply | View]
Hi!
Checking for "observe_field" in http://api.rubyonrails.org/ gave me the answer.
If you use the following test code in the controller
def live_search
render_text "<p> "+ params.inspect + ".</p>"
end
I'll see the function 'observe_field' will not return the text unless told to do so (you were probably expected to retrive the field directly through the DOM).
change the rhtml to:
<label for="searchtext">Live Search:</label>
<%= text_field_tag :searchtext %>
<%= observe_field(:searchtext,
:frequency => 0.25,
:update => :search_hits,
:with => "searchtext",
:url => { :action => :live_search }) %>
<p>Search Results:</p>
<div id="search_hits"></div>
That will do it (until I learn to fetch the fields directly).
Best Regards
G.
-
correct code
2006-04-19 03:02:21 gvlx [Reply | View]
Hi!
Checking for "observe_field" in http://api.rubyonrails.org/ gave me the answer.
If you use the following test code in the controller
def live_search
render_text ""+ params.inspect + ".
"
end
I'll see the function 'observe_field' will not return the text unless told to do so (you were probably expected to retrive the field directly through the DOM).
change the rhtml to:
<label for="searchtext">Live Search:</label>
<%= text_field_tag :searchtext %>
<%= observe_field(:searchtext,
:frequency => 0.25,
:update => :search_hits,
:with => "searchtext",
:url => { :action => :live_search }) %>
Search Results:
<div id="search_hits"></div>
That will do it (until I learn to fetch the fields directly).
Best Regards
G.
-
Live Search Example
2006-02-17 03:01:04 vadhavane_anil [Reply | View]
Hi,
I tried that live search example.
I want to select data from database based on that search text.
Means suppose entered text is y then i want results from database start with y.
i made it.
but when i use like query it shows error.
Query is:
@a=@params[:searchtext]
@links = Link.find_by_sql [
"SELECT * from links where link like '"+ @a +"%' order by id asc"]
-
Live Search Example
2006-02-17 03:33:36 Curt Hibbs |
[Reply | View]
What is the error you are getting?
-
AJAX remote method
2006-02-12 16:48:31 lzaman [Reply | View]
Hello, I am just wondering about the way you used the remote method to update the time... Is there a way you could update the time in place. (i.e. insted of having new lines of text come up, have the time change only in place)
-
static class variables in the controller
2005-10-23 15:43:18 lada77@yahoo.com [Reply | View]
Hi,
I'm new to rails n had a question on your example. I got everything to work and for kicks, i added the following code into my controller for testing the ajax observer functions:
@@mycount = 0
def live_search
@@mycount += 1
render_text("count is : " + @@mycount.to_s + "
")
end
I was expecting to see the count increasing by 1 evertime i changed the search text but this is not the case and the variable always remains at 1.
Would you know why this is the case ? Would i have to change some options on my webrick server ?
-
still confused
2005-09-19 11:33:10 rhubarbo [Reply | View]
I don't claim to know anything about rails, ruby or even AJAX, but I'm learning all three simultaneously and I'd really like to get this clear in my head.
The first page of this article describes AJAX in RoR Thus:
How Rails Implements Ajax
(simplifying)
1. trigger action - e.g. user making changes to the data on a form
2. Form Data sent asynchronously action handler on the server via XMLHttpRequest.
3. The server-side action handler ... returns an HTML fragment as its response.
4. The client-side JavaScript updates a specified part of the current page's HTML
Now I can see how this is much more responsive than a typical web app where the whole page is submitted then reloaded. In fact I see the Ajaxy elements as:
a) the form data is sent asynchronously and perhaps could be sent as the user types instead of after submit
b) a section of the page is updated instead of the whole page
But in general - it looks like you describe a normal web-app-like interaction - that is a full server round-trip to react to user input - just limited to a section of a page instead the whole page.
Is this what AJAX is really about?
Again - I know nothing about AJAX beyond the bits and pieces I've read - but I thought the whole point was that the UI reacts before the server round trip is made.
This is the distinction you describe in your example about a list being updated.
-
still confused
2005-09-19 11:51:13 Curt Hibbs |
[Reply | View]
It does still involve a server round trip. That why it can't match the responsiveness of a desktop app, but it can be much better than without.
In the most common case, data collected in a form is sent to the server, but it doesn't have to be form data.
Its also possible to send and receive pure data data and transform the received data on the client side to HTML (or DOM updates). This can wring out the maximum amount of responsive. But the cost is extensive, custom, client-side javascript. A lot of work.
This might be justified in some cases, but the built in Rails Ajax support is designed to hit the sweet spot of the common cases and requires very little effort to get there.
-
can ajax be used for updating two or more div's simultaniously
2005-09-12 12:12:58 viper_again [Reply | View]
hello there...
i am a bignner to this ruby on rails and ajax.... i really liked the way this ajax thing works....
but i want this ajax to update 2 divs simultaniously in a page... can this be possible... can anyone plz help me out with this...
thanks for ur concern.
viper. -
can ajax be used for updating two or more div's simultaniously
2006-09-14 09:22:52 EpsilonsDad [Reply | View]
After playing with this I have found that you can take advantage of the fact that the rails ajax framework evaluates javascript within the response. So the response hander to fill two divs could be something like this.
def response_handler
#content for div1
@text = "New text in div1"
#content for div2
@text += "<script language=\"javascript\" >document.all.div2.innerHTML='New text in div2';</script>"
render :text => @text
end
Which should update mutilple blocks
-
can ajax be used for updating two or more div's simultaniously
2005-09-12 12:26:50 Curt Hibbs |
[Reply | View]
Yes you can, but not having done that yet myself, I can't be any more specific. I just know there is a way to have your own JavaScript function be called when data is returned from the server. And, of course, your JavaScript can update as many parts of the document as you need.
I would subscribe to the Rails developer mailing list and ask your question there:
http://lists.rubyonrails.org/mailman/listinfo/rails
-
can ajax be used for updating two or more div's simultaniously
2005-09-12 22:09:57 viper_again [Reply | View]
thank u curth for ur concern...
.. ill be happy if u can guide me how to go about doing this ... as i told already.. i am just a beginer to ruby on rails
-
can ajax be used for updating two or more div's simultaniously
2005-09-13 04:01:28 Curt Hibbs |
[Reply | View]
Sorry, I don't personal know the answer. Please take my suggestion and subscribe to the Rails mailing list. You will find plenty of people there who can give you an answer.
-
confused about ajax
2005-08-26 10:36:06 rhubarbo [Reply | View]
Isn't that a football team in Amsterdam? Or a floor cleaner?
Seriously though, I enjoyed this article but was confused by what seems to be a mismatch between what you describe AJAX to be, and your examples.
On the first page, with your example (in words that is - not in code) about adding an item to a list, you describe how the point of AJAX is to update the UI immediately in response to the user action (put an item in a list), then handle the communication of that action to the server in the background - asynchronously.
Then in all of the code examples - including the example where you actually add a value to a list - it seems that the client-side html is NOT updated until a trip has been made to the action handler function on the server.
What am I missing? Are those action handler's client side?
Who can set me straight?
-
Link to "Rails Ajax API" is broken
2005-07-06 12:18:53 Solace [Reply | View]
Link to "Rails Ajax API" is broken. Needs a capital "S" in "Javascript".
-
access from controller for :searchtext
2005-06-28 19:42:26 vcosby [Reply | View]
I'm trying out the observer example, but can't seem to get at the :searchtext observed value from the controller.
# this don't work
def live_search
render_text "return search results using " +
params[:searchtext]
end
-
access from controller for :searchtext
2005-07-27 07:33:31 k.y.l.e [Reply | View]
Just add :with => "'searchtext='+value'" to the observe_field call in the view.
<%= observe_field(:searchtext,
:frequency => 0.25,
:update => :search_hits,
:with => "'searchtext='+value",
:url => { :action => :live_search }) %> -
access from controller for :searchtext
2005-06-29 05:28:27 Curt Hibbs |
[Reply | View]
"params" is an instance variable, so you need to prefix it with an at-sign:
@params[:searchtext]
-
access from controller for :searchtext
2005-06-29 21:43:10 vcosby [Reply | View]
Thanks for your help, but I'm still getting nil for the param value.
Here's the code. Even tried adding a form tag around it, but no luck.
index.rhtml:
<form action="/demo" method="get">
<label for="searchtext">Live Search:</label>
<%= text_field_tag :searchtext %>
</form>
<%= observe_field(:searchtext,
:frequency => 1,
:url => { :controller => "demo",
:action => :live_search },
:update => "search_hits") -%>
Search Results:
<div id="search_hits"></div>
demo_controller.rb
def live_search
render_text @params[:searchtext]
end
-
access from controller for :searchtext
2005-06-29 22:14:32 vcosby [Reply | View]
aha!
maybe the api changed. it appears you have to grab it from the request's raw post or querystring.
def live_search
render_text "you searched for: " +
request.raw_post || request.query_string
end
-
access from controller for :searchtext
2005-10-10 11:11:52 mewren.com [Reply | View]
I had the same problem. I had forgotten to include the library
<%= javascript_include_tag "prototype" %> -
access from controller for :searchtext
2005-12-09 12:21:43 kevinmarshall [Reply | View]
I was having a little trouble getting this to work too...so I added in a VERY generic test...ad in
render_text @params.inspect
This will show you all the fields you can access via the params ... you'll probably notice that the searchtext isn't listed, but rather the value you entered is being put there (at least that was my case) ... using the :with => "'searchtext='+value" mentioned above solved my problem ... but I thought it was worth mentioning this simple debugging approach for params
-
Oops!
2005-06-11 09:01:29 geoffleach [Reply | View]
http://blog.curthibbs.us/articles/2005/01/01/ajax-on-rails
Application error (Apache)
Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050513 Fedora/1.0.4-1.3.1 Firefox/1.0.4, Fedora 3 -
Oops!
2005-06-11 10:16:02 Robby Russell |
[Reply | View]
Thats the default Rails error page.
Should be working fine now and there is even a mirror site to handle the slashdot crowd.
-
hosting platforms
2005-06-10 07:15:29 msporleder [Reply | View]
Has anyone found many hosting services supporting Ruby at all? Mine is reluctant to add php5 support. -
hosting platforms
2006-03-01 00:09:19 TechNeck [Reply | View]
I guess they all have their quirks.
So far though, I've not found anyone to beat out these guys I've been hosting with for the last two years:
www.dreamhost.goldenpath.org (http://www.dreamhost.goldenpath.org)
Debian Systems
Basic plan ($8/mnth) includes,
- Unlimited Domains
- 20GB Disk
- 1 TB Transfer
- 75 Shell Accounts
- Lots of unlimited goodies
- Very responsive to customer base feedback
- Constantly expanding, very flexible
Ruby is currently at version 1.8.2
Rails 1.0.0
Although, I like to control my own versioning and so I install my own ruby system under ~/local/ -
hosting platforms
2005-07-08 17:50:32 ritcheyer [Reply | View]
www.1and1.com $4.99/month for lots of stuff AND ruby support. -
hosting platforms
2005-06-10 16:50:17 Davidb834 [Reply | View]
I host my Dev applications with Steel Pixel. It is run by a developers and have always been very reliable. They were actually the first few to offer ruby on rails and i know they have PHP 5. just my recommendation Steel Pixel -
hosting platforms
2005-06-10 12:01:46 bsw1971 [Reply | View]
phpwebhosting.com also supports Ruby. I emailed them about Rails and they said, "We currenly do not offer rails pre-installed, but you are allowed to install it onto your own account. We have clients who have done so." I personally host with them, and I've always had great service.
Brian
WilkinsTech.com -
hosting platforms
2005-06-10 08:43:17 Robby Russell |
[Reply | View]
PHP5 and Ruby on Rails support!
http://www.planetargon.com/hosting/
-
hosting platforms
2005-06-10 07:51:12 Curt Hibbs |
[Reply | View]
Try planetargon.com and textdrive.com.
-
*** AJAX Example Server is Down ***
2005-06-10 06:34:21 Curt Hibbs |
[Reply | View]
Its unfortunate timing, but co-location center which houses my ISP's servers had a major power failure yesterday which took down over 4,000 servers for over four hours. Power was restored late yesterday, but as of now it looks like they are back down again. Obviously, with that many servers down I sure they are scrambling like mad to get everything back up again.
Unfortunately, until things come back online the links to my Ajax enable blog will not work.
Thank you for being patient. -
*** AJAX Example Server is Down ***
2005-06-10 17:04:17 Curt Hibbs |
[Reply | View]
Its been back up for a while now... I forgot to post an update. -
*** AJAX Example Server is Down ***
2007-05-30 08:12:21 profesjonalna [Reply | View]
Thank You for another very interesting article. It's really good written and I fully agree with You on main issue, btw. I must say that I really enjoyed reading all of Your posts. It’s interesting to read ideas, and observations from someone else’s point of view… it makes you think more. So please try to keep up the great work all the time. Greetings
Tomasz Górski (http://www.profesjonalna-reklama.pl)
-
AJAX super not impressive
2005-06-09 23:28:13 hardy [Reply | View]
Application error (Apache)
Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html
http://blog.curthibbs.us/articles/2005/01/01/ajax-on-rails
um...
hope you can fix that.
AJAX is good, problems arise though when you are talking broad coverage as far as browsers go.
Not everyone runs Javascript on their client either. How does this degrade? Why RoR as opposed to the other app frameworks, why over ASP.NET or Java? Don't really see the point.
Good article tho. -
AJAX super not impressive
2005-06-10 04:24:00 Curt Hibbs |
[Reply | View]
I've got my ISP looking at the the error from the server. Hopefully it'l be back up soon.
Rails does provide the ability for the Ajax support to degrade gracefully when JavaScript (or XMLHttpRequest) are not available. I just didn't cover that aspect in this article.
-
Obscure?
2005-06-09 20:32:33 IDunno [Reply | View]
In a few short months, Ajax has moved from an obscure and rarely used technology to the hottest thing since sliced bread.
Obscure? Hardly. Not all the rage perhaps as it is now, but certainly well-known and used by experienced Web developers.
And there are actual reasons for using XML rather than HTML (and hence the name AJAX).
Anyway, thanks for a good refresher article on remote scripting. Not sure how coupling the design of your client to your services provider makes things better, though.
-
Obscure?
2005-06-11 12:47:51 davidbeard [Reply | View]
oh let them have their fun ;) - where would web developers be without a bandwagon to jump upon ?
-
Obscure?
2005-06-13 18:13:56 Nerdmaster [Reply | View]
Er... have their fun? When somebody big like google jumps on a "bandwagon", and creates the first really easy to use web app for maps / directions, you gotta wonder if it's really that much of a "bandwagon" after all... then again, developers that don't like to learn new things tend to call them bandwagons to justify their ignorance. Oh well.








Thanks for the help