Thursday, August 25, 2011

link_to remote in Rails 3

If you're like me, and come from a rails 2 background, you'll probably have noticed that in Rails 3 the way of creating these nifty AJAX links is completely different then the way it used to be. Actually it's not that much different, you're just required to do alot more work, and honestly the documentation on this is piss-poor on the web. I've found a few blogs that gave some insight on what needs to be done, but they're all written for jQuery.

In this case, I'm going to show you how to create a simple link_to remote which uses prototype to call an action on of our controllers and relies on a simple rj.erb file to update a
element on our page.

The first step we need to undertake is to create a JavaScript file. We'll call it bindings.js and it should be located in your /public/javascripts folder. The content of the file should something like this:

document.observe("dom:loaded", function(){
$('our_div_id')
.observe("ajax:success", function(evt, data, status, xhr){
// The response is Javascript, so evaluate it.
eval(xhr.responseText);
// Return false to avoid jumping
return false;
})
.observe("ajax:failure", function(evt, data, status, xhr){
alert("failed");
// Insert a custom error message when something goes wrong
$('
our_div_id').replace('
');

$('
our_div_id').insert('

A problem occured.

');


// Return false to avoid jumping
return false;
});
});


Make sure that you replace the 'your_div_id' with the actuall id of yourdiv-tag. Note that in regards to jQuery, you do not need to append the # symbol before the id.

The general idea behind the javascript is that we observe the 'dom:loaded' event of the entire HTML document, which is triggered after loading the page, and then we bind the 'ajax:success' and 'ajax:error' functions.
Why these 2 functions? Because they're the functions defined in rails.js. These functions are called when an AJAX calls succeeds or fails. If you want to know the details, check the rails.js file

I'm not going to discuss how your action on the controller should look like, as this is nothing special. I personally do not bother with the respond_to |format| stuff, and just let rails decide which action template needs to be server. In most cases this is always correct.
The contents of your action.js.erb file should be pure Javascript. Here is the content of mine:

$('semantic').replace('
');

$('semantic').insert("

<%=h @country.abstract.value %>

");

$('semantic').insert("

<%=h @country.comment.value %>

");

$('semantic').insert("

Currency: <%=h @country.currency.value %>

");

$('semantic').insert("

Population: <%=h @country.population.value %>

");

$('semantic').insert("

Capital: <%=h @country.capital.value %>

");


Basicly this piece of Javascript updated the semantic div on my page with new content.

The last step is creating the actuall link. This is the easiest part of everything and the syntax looks like this:

= link_to @vacancy.country.name, semantic_country_url(@vacancy.country.id), :remote => true

The trick is in the ":remote => true" part, which allows rails to make it an AJAX call.

In short:

  • Create a Javascript file that binds the ajax callbacks to your element
  • Create a js.erb (or other template) to generate the javascript/output
  • Create a link_to :remote => true
Hope this makes it clear on how AJAX works in Rails 3

No comments:

Post a Comment