Ruby-on-Rails and AJAX - Implementing AJAX
(Page 3 of 4 )
In the last section, the example demonstrated the complexity involved in AJAXifying an application having even the simplest logic to be implemented. So how can RoR make it simple? RoR does it by providing AJAX as one of its core functionalities. RoR has the prototype, effects, dragdrop and controls JavaScript libraries as built-in libraries. Secondly, a helper called JavaScriptHelper provides wrapping around JavaScript code so that switching between Ruby and JavaScript won't be necessary. So RoR makes things simpler by wrapping JavaScript libraries and providing them as built-in RoR libraries.
Now let's look at ways to use AJAX within RoR. To implement AJAX, RoR provides two basic ways which are:
- Using link_to_remote()
- Calling form_remote_tag()
The former is used with non-form HTML whereas the later is used with form and form based HTML elements.
The link_to_remote() is one of the simplest yet versatile and flexible helpers in RoR. It takes following parameters:
- the text for the link
- the id of the link
- the URL of the action to be called when the link is clicked
- the position which tells Rails to insert the response instead of replacing the existing content. This is an optional parameter used with the advanced form of link_to_remote().
So what are the steps required to use link_to_remote()? The steps are as follows:
- Create the page to be shown to the user
- Implement the controller to be called by link_to_remote()
- Develop the page that will provide the response
The steps are common to that of any typical RoR. That is the beauty of RoR. Of these steps, the third step is optional if rendering is taken care of by the action itself.
- Create the page to be shown to the user:
This step involves creation of an RHTML template with the addition of link_to_remote(). However, to call it, another helper will have to be included - javascript_include_tag. Using this one can include any of the four JavaScript libraries. For calling link_to_remote() we need the prototype library. So the statement would look like this:
<%= javascript_include_tag "prototype" %>
Here is an example of a page having link_to_remote():
<html>
<head>
<title>Ajax Demo</title>
<%= javascript_include_tag "prototype" %>
</head>
<body>
<h1>What time is it?</h1>
<div id="time_div">
I don't have the time, but
<%= link_to_remote( "click here",
:update => "time_div",
:url =>{ :action => :say_when }) %>
and I will look it up.
</div>
</body>
</html>
The link_to_remote() is passed three arguments: the text to be shown i.e. "click here", the id of the link created which is "time_div" and the action to be called which is say_when. The next step is to implement the controller containing the action.
- Implement the controller to be called by link_to_remote()
The action within the controller can be implemented in two ways. The first way involves a simple action which in turn calls the corresponding RHTML, while the second way renders the response using render_text. The following is an example of the first type:
class DemoController < ApplicationController
def index
end
def say_when
render(:layout => false)
end
end
The render function is called with the layout option as false because only a part of the HTML page is being updated; hence there is no requirement of any Rails layout wrappers. The example of the second type is as follows:
class DemoController < ApplicationController
def index
end
def say_when
render_text "<p>The time is <b>" + DateTime.now.to_s + "</b></p>"
end
end
It uses render_text method to generate the response.
- Develop the page that would provide the response:
This step is required only in case of an action that calls view to generate a response. The view corresponding to the action is again a straight forward RHTML:
<p>The time is <b> <%=DateTime.now.to_s%>
</b></p>
That's how link_to_remote() is used. Next let's see how form_remote_tag() is used.
While dealing with links, link_to_remote() is handy but what about form elements? That's where form_remote_tag() comes in. One can easily enable any Rails form to use AJAX using form_remote_tag(). It serializes and sends all the form elements to the server via XMLHttpRequest. All this is done automatically without any requirement for extra logic implementation. The form_remote_tag() takes three parameters:
- The update parameter specifies the id of the element that needs to be updated using the response of the executed action.
- The url parameter specifies the server-side action to call.
- The position parameter tells Rails the position in which to place the response data.
To use the form_remote_tag() there are three steps:
- Create the page to be shown to the user.
- Implement the controller to be called by form_remote_tag().
- Develop the page that will provide the response.
The steps are similar to those of using link_to_remote(). Only the way they are implemented is different.
- Create the page to be shown to the user:
The main change from the page for link_to_remote() is that form_remote_tag() uses form elements. Hence the page also contains form elements instead of links. A simple page using form_remote_tag() would look as follows:
<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>
Here the id of the element is given as my_list which is the id of the list that will be populated by the response provided by the action. The url specifies the action to be called and the position tells Rails to place the returned HTML snippet on the top of the element whose id has been specified in the update parameter. Now let's look at the action.
- Implement the controller to be called by form_remote_tag():
Just as in the case of link_to_remote() helper, the action can either render the response directly using render_text or else it can delegate it to another RHTML. If render_text is to be used the code would be:
class ListdemoController < ApplicationController
def index
end
def add_item
render_text "<li>" + params[:newitem] + "</li>"
end
end
whereas if the rendering is to be done by a template then the code would be:
class ListdemoController < ApplicationController
def index
end
def add_item
@item= params[:newitem]
render(:layout => false)
end
end
The only difference is that the parameter passed by form_remote_tag() is placed in a variable called item which can be used in the template.
- Develop the page that will provide the response:
The add_item.rhtml would be like:
<li> <%=@item%> </li>
That's it.
So now you have seen how easy the steps are for creating an AJAX based application in RoR. Next I will develop a real world application using RoR and AJAX.
Next: Ruby-on-Rails and AJAX >>
More Ruby-on-Rails Articles
More By A.P.Rajshekhar