ONLamp.com
oreilly.comSafari Books Online.Conferences.

advertisement


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_list element--in this case, a <ul> tag.

List Demo before adding items
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.

List Demo after adding list items
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
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.



Sponsored by: