Working with Ajax and Ruby on Rails


Ruby on Rails is an online application framework that comes with Ajax support built in. Ruby is a stand-alone language that’s become popular in recent years, and Rails is the Web framework that allows you to put Ruby online.

On the Web 

You can download Ruby on Rails for free from http://www.rubyonrails.com/down.

Installing Ruby on Rails is easy: just follow the directions at http://www.rubyonrails.com/down. For example, there’s a handy one-click installer for Ruby for Windows at http://rubyinstaller.rubyforge.org. How much easier could it get than that? Just use the download link, and run the installing program. That’s it-you’ve got Ruby.

Setting up Rails in Windows is just about as easy. Just open a DOS command-prompt window and type this at the command prompt:

 gem install rails --include-dependencies

And that’s it; you’ve got Ruby, and you’ve got Rails.

Installing on other platforms is as easy-or easier. For example, as of Mac OS X version 10.4, installation is more than easy: Ruby comes built in. To download Rails on the Mac, you’re going to need RubyGems, which you can pick up at http://docs.rubygems.org. After downloading RubyGems, go to the directory containing the download in the Terminal application and enter this at the command prompt:

 tar xzf rubygems-0.8.10.tar.gz cd rubygems-0.8.10 sudo ruby setup.rb

The final step is to use RubyGems to download Rails, so enter this command:

 sudo gem install rails --include-dependencies

That’s it; you should be on Rails.

If you’re using Linux or Unix, it’s probable that you already have Ruby installed (if not, take a look at www.rubyonrails.com/down). You’re also going to need Rails, which is most easily installed with RubyGems. To get RubyGems, go to http://docs.rubygems.org and click the downloads link. Then go to the directory containing the download and follow the directions described earlier for the Mac.

Downloading text with Ajax

Time to take a look at a Ruby on Rails example. In the code that follows, the % sign stands for your command prompt, whether you’re using Windows, the Mac, or Linux/Unix. To start, you need to create a new Rails application, which is easily done. To create an application named Ajax, just enter this at the command prompt (in whatever directory you want to create the application):

 %rails ajax

That makes Rails create the new Ajax application:

 %rails ajax       create       create  app/controllers       create  app/helpers       create  app/models       create  app/views/layouts       create  config/environments       create  components       create  db       create  doc       create  lib         .         .         .       create  public/javascripts/prototype.js       create  public/javascripts/effects.js       create  public/javascripts/dragdrop.js       create  public/javascripts/controls.js       create  public/javascripts/application.js       create  doc/README_FOR_APP       create  log/server.log       create  log/production.log       create  log/development.log       create  log/test.log

Next, change directories to the new ajax directory:

 %cd ajax

Now you create a controller named Look for the Ajax application; the controller handles the interaction with the user and routes the flow of the application to the correct parts of the application. Here’s how you create the controller:

 %ruby script/generate controller Look       exists  app/controllers/       exists  app/helpers/       create  app/views/look       exists  test/functional/       create  app/controllers/look_controller.rb       create  test/functional/look_controller_test.rb       create  app/helpers/look_helper.rb

Then you edit the file ajax\app\controllers\look_controller.rb, creating an action named at. Actions are called by the controller to execute specific tasks in Ruby on Rails applications. Add this code to look_controller.rb:

 class LookController < ApplicationController   def at   end end

Now you can create the application’s view. The view is a Ruby-enabled HTML page with the extension .rhtml that users see in their browser. Create ajax\app\views\look\at.rhtml now, and place this code in it (you’ll see how this code works a little bit later in this chapter):

 <html>   <head>     <title>Using Ajax</title>     <%= javascript_include_tag "prototype" %>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <%= link_to_remote("Click me to use Ajax",        :update => "displayDiv",       :url => {:action => :replacer }) %>     <br>     <div id = "displayDiv">The new text will appear here.</div>   </body> </html>

This code makes use of an action named replacer, so you need to add that action to the code in the file ajax\app\controllers\look_controller.rb. This action reads the text to download, so you set the :layout symbol to false here, indicating that you don’t want a page refresh:

 class LookController < ApplicationController   def at   end   def replacer     render(:layout => false)   end end

Finally, create the view for the replacer action, ajax\app\views\look\replacer.rhtml, and place this code in it:

 This text was downloaded using Ajax.

To test this application, you can run the Web server that comes with Rails. To do that, you enter this command in the ajax application’s directory:

 %ruby script/server

And this is what you see:

 %ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-09-12 11:52:40] INFO  WEBrick 1.3.1 [2006-09-12 11:52:40] INFO  ruby 1.8.2 (2004-12-25) [i386- mswin32] [2006-09-12 11:52:40] INFO  WEBrick::HTTPServer#start: pid=2304 port=3000

That starts the Rails Web server; to see what this application looks like in action, navigate your browser to http://localhost:3000/look/at, as shown in Figure 7.22, and then click the link. You should see the downloaded text, as shown in Figure 7.23.

image from book
Figure 7.22: A Ruby on Rails Ajax application

image from book
Figure 7.23: Downloading text with a Ruby on Rails Ajax application

How does this application do what it does? Here, you used Ajax to fetch text and display that text in a <div> element. You started by including the Rails prototype.js JavaScript library in the view where you want to use Ajax:

 <html>   <head>     <title>Using Ajax</title>     <%= javascript_include_tag "prototype" %>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <%= link_to_remote("Click me to use Ajax",       :update => "displayDiv",       :url => {:action => :replacer }) %>     <br>     <div id = "displayDiv">The new text will appear here.</div>   </body> </html>

Now you can use link_to_remote to create a hyperlink that will fetch the results of an action and display them in a <div> element. To set up a hyperlink that displays the text Click me to use Ajax, updates the <div> element named displayDiv with the fetched data, and fetches the text to display from the replacer action, you call link_to_remote:

 <html>   <head>     <title>Using Ajax</title>     <%= javascript_include_tag "prototype" %>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <%= link_to_remote("Click me to use Ajax",       :update => "displayDiv",       :url => {:action => :replacer }) %>     <br>     <div id = "displayDiv">The new text will appear here.</div>   </body> </html>

In HTML, this creates a call to the Rails prototype.js library function Ajax.Updater in the HTML code created after Rails processes the at.rhtml document:

 <html>   <head>     <title>Using Ajax</title>     <script      src="/books/1/252/1/html/2//javascripts/prototype.js?1151422045"      type="text/javascript"></script>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <a href="#" onclick="new Ajax.Updater('displayDiv',     '/look/replacer', {asynchronous:true, evalScripts:true});       return     false;">Click me to use Ajax</a>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear       here.</div></h3>   </body> </html>

The replacer action simply renders its output without including any layout, which means it just shows the text in the replacer action’s view, which is replacer.rhtml. Here’s what the replacer action looks like:

 class LookController < ApplicationController   def at   end   def replacer     render(:layout => false)   end end

And here’s the text that the replacer view returns, ajax\app\views\look\replacer.rhtml:

 This text was downloaded using Ajax.

This is the text that will be displayed in the displayDiv <div> element. Here’s what the text in that <div> element starts off as:

 <html>   <head>     <title>Using Ajax</title>     <%= javascript_include_tag "prototype" %>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <%= link_to_remote("Click me to use Ajax", :update =>       "displayDiv",       :url => {:action => :replacer }) %>     <br>     <h3><div id = "displayDiv">The new text will appear       here.</div></h3>   </body> </html>

Here’s what this page looks like in the browser after you’ve downloaded the text using Ajax:

 <html>   <head>     <title>Using Ajax</title>     <script src="/books/1/252/1/html/2//javascripts/prototype.js?1151422045"        type="text/javascript"></script>   </head>   <body>     <h1>Using Ajax</h1>     <br>     <a href="#" onclick="new Ajax.      '/look/replacer',       return false;">Click me to use Ajax</a>     <br>     <br>     <h3><div id = "displayDiv">This text was downloaded        using Ajax.</div></h3>   </body> </html>

That’s a good start with Ajax and Ruby on Rails, but it’s only a start. Here, Rails handled the details for you, placing the downloaded text into the <div> element itself. But what if you want access to the Ajax data yourself? That’s coming up next.

Accessing downloaded data in code

You can configure link_to_remote to call a JavaScript function when your Ajax data is downloaded, which is more in line with the other Ajax frameworks described in this chapter. Here are the possible parameters to pass to link_to_remote to specify when you want your JavaScript function called:

  • :loading-The data is being loaded by the browser.

  • :loaded-The browser has finished getting the data.

  • :interactive-The user can interact with the data, even if it has not finished loading.

  • :success-The Ajax download is completed successfully.

  • :failure-The Ajax download failed.

  • :complete-The Ajax request is complete (whether it was successful or failed).

This next example uses the :success parameter to have a JavaScript function called with the downloaded data so you can handle that data in code. To start this new application, ajaxdata, create it this way:

 %rails ajaxdata       create       create  app/controllers       create  app/helpers       create  app/models       create  app/views/layouts       create  config/environments       create  components       create  db       create  doc       create  lib         .         .         .       create  public/javascripts/prototype.js       create  public/javascripts/effects.js       create  public/javascripts/dragdrop.js       create  public/javascripts/controls.js       create  public/javascripts/application.js       create  doc/README_FOR_APP       create  log/server.log       create  log/production.log       create  log/development.log       create  log/test.log

then change directories to the ajaxdata directory:

 %cd ajaxdata

and create a controller named Look for the ajaxdata application:

 %ruby script/generate controller Look       exists  app/controllers/       exists  app/helpers/       create  app/views/look       exists  test/functional/       create  app/controllers/look_controller.rb       create  test/functional/look_controller_test.rb       create  app/helpers/look_helper.rb

Now edit ajaxdata\app\controllers\look_controller.rb, adding this code to create an action named at:

 class LookController < ApplicationController   def at   end end

Next, create the file ajaxdata\app\views\look\at.rhtml, and place this code in it, including a JavaScript function that will display the downloaded text in the <div> element in this Web page:

 <html>   <head>     <title>Handling Ajax Data</title>     <%= javascript_include_tag "prototype" %>     <script language="JavaScript">       function handleData(request)       {           var displayDiv = document.getElementById("displayDiv");            displayDiv.innerHTML = request.responseText;        }     </script>   </head>   <body>     <h1>Handling Ajax Data</h1>     <br>     <%= link_to_remote("Click me to handle Ajax data", :success =>        "handleData(request)", :url => {:action => :getter }) %>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear       here.</div></h3>   </body> </html>

then edit ajaxdata\app\controllers\look_controller.rb, adding this code to create the getter action:

 class LookController < ApplicationController   def at   end   def getter     render(:layout => false)   end end

Finally, create ajaxdata\app\views\look\getter.rhtml, and place this code in it:

 This text was downloaded using Ajax.

Okay, that’s it; start the Rails Web server:

 %ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-09-12 11:52:40] INFO  WEBrick 1.3.1 [2006-09-12 11:52:40] INFO  ruby 1.8.2 (2004-12-25) [i386-   mswin32] [2006-09-12 11:52:40] INFO  WEBrick::HTTPServer#start: pid=2304 port=3000

Open your browser and navigate to http://localhost:3000/look/at, as shown in Figure 7.24.

image from book
Figure 7.24: A Ruby on Rails Ajax application that lets you handle data

Then click the link; you should see the downloaded text, as shown in Figure 7.25.

image from book
Figure 7.25: A data-handling Ruby on Rails Ajax application

This Ruby on Rails example lets you set up a callback function to handle the downloaded data. The application starts by including the Rails prototype.js Ajax library in the view file, at.rhtml:

 <html>   <head>     <title>Handling Ajax Data</title>     <%= javascript_include_tag "prototype" %>     <script language="JavaScript">       function handleData(request)       {           var displayDiv = document.getElementById("displayDiv");            displayDiv.innerHTML = request.responseText;        }     </script>   </head>   <body>     <h1>Handling Ajax Data</h1>     <br>     <%= link_to_remote("Click me to handle Ajax data", :success        => "handleData(request)", :url => {:action => :getter }) %>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear        here.</div></h3>   </body> </html>

In this example, you connected a successful download from an action named getter to a JavaScript function, handleData, which is passed the data sent to the browser from the getter action:

 <html>   <head>     <title>Handling Ajax Data</title>     <%= javascript_include_tag "prototype" %>     <script language="JavaScript">       function handleData(request)       {           var displayDiv = document.getElementById("displayDiv");           displayDiv.innerHTML = request.responseText;       }     </script>   </head>   <body>     <h1>Handling Ajax Data</h1>     <br>     <%= link_to_remote("Click me to handle Ajax data", :success       => "handleData(request)", :url => {:action => :getter }) %>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear here.</div></h3>   </body> </html>

In code, the getter action renders its view, without a layout:

 class LookController < ApplicationController   def at   end   def getter     render(:layout => false)   end end

The getter view passes this text data back to the browser:

 This text was downloaded using Ajax.

In the browser, that text is stored in the XMLHttpRequest object’s responseText property, and that object is passed to the JavaScript handleData function like this, as the request parameter:

 <html>   <head>     <title>Handling Ajax Data</title>     <%= javascript_include_tag "prototype" %>     <script language="JavaScript">       function handleData(request)       {         .         .         .       }     </script>   </head>   <body>     <h1>Handling Ajax Data</h1>     <br>     <%= link_to_remote("Click me to handle Ajax data", :success       => "handleData(request)", :url => {:action => :getter }) %>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear       here.</div></h3>   </body> </html>

You can display the text in a <div> element using code in the JavaScript handleData function:

 <script language="JavaScript">   function handleData(request)   {     var displayDiv = document.getElementById("displayDiv");     displayDiv.innerHTML = request.responseText;   } </script>

What does this action look like in HTML in the browser? Here it is:

 <html>   <head>     <title>Handling Ajax Data</title>     <script src="/books/1/252/1/html/2//javascripts/prototype.js?1151428997"       type="text/javascript"></script>     <script language="JavaScript">       function handleData(request)       {           var displayDiv = document.getElementById("displayDiv");           displayDiv.innerHTML = request.responseText;       }     </script>   </head>   <body>     <h1>Handling Ajax Data</h1>     <br>     <a href="#" onclick="new Ajax.Request('/look/getter', {asynchronous:true, evalScripts:true, onSuccess:function(request){handleData(request)}}); return false;">Click me to handle Ajax data</a>     <br>     <br>     <h3><div id = "displayDiv">The new text will appear here.</div></h3>   </body> </html>

This is what gives you the result you see in Figures 7.24 and 7.25.



Ajax Bible
Ajax Bible
ISBN: 0470102632
EAN: 2147483647
Year: 2004
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net