rails3 rails.js and jquery catching success and failure of ajax requests
Solution 1
Ha! I found it described in this article. In rails.js the following callbacks are checked:
- ajax:loading : triggered before executing the AJAX request
- ajax:success : triggered after a successful AJAX request
- ajax:complete : triggered after the AJAX request is complete, regardless the status of the response
- ajax:failure : triggered after a failed AJAX request, as opposite to ajax:success
As the javascript should be unobtrusive, this coupling is not done in the HTML.
An example (from the same site) : the following Rails 2.3.8
<% form_remote_tag :url => { :action => 'run' },
:id => "tool-form",
:update => { :success => "response", :failure => "error" },
:loading => "$('#loading').toggle()", :complete => "$('#loading').toggle()" %>
is translated to this :
<% form_tag url_for(:action => "run"), :id => "tool-form", :remote => true do %>
and inside some javascript (application.js), you bind the events
jQuery(function($) {
// create a convenient toggleLoading function
var toggleLoading = function() { $("#loading").toggle() };
$("#tool-form")
.bind("ajax:loading", toggleLoading)
.bind("ajax:complete", toggleLoading)
.bind("ajax:success", function(xhr, data, status) {
$("#response").html(status);
});
});
Great! :)
[UPDATE: 29/12/2011]
Two events have been renamed lately:
-
ajax:beforeSend
: replace the lateajax:loading
-
ajax:error
replaces theajax:failure
(I guess to be more in line with jQuery itself)
So my example would become:
$("#tool-form")
.bind("ajax:beforeSend", toggleLoading)
.bind("ajax:complete", toggleLoading)
.bind("ajax:success", function(xhr, data, status) {
$("#response").html(status);
});
For completeness, the events and their expected parameters:
.bind('ajax:beforeSend', function(xhr, settings) {})
.bind('ajax:success', function(xhr, data, status) {})
.bind('ajax:complete', function(xhr, status) {})
.bind('ajax:error', function(xhr, data, status) {})
Solution 2
The related rails 4 guide can be found at: http://guides.rubyonrails.org/working_with_javascript_in_rails.html
It points to the documentation of the events at: https://github.com/rails/jquery-ujs/wiki/ajax , as mentioned by ncherro
The actual values passed to the callbacks can be inferred from jQuery's ajax
method http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings
.bind
is deprecated in favor of .on
by jQuery: http://api.jquery.com/on/
So now the recommended approach is:
Template:
<%= link_to 'Click me!',
'path/to/ajax',
remote: true,
id: 'button',
method: :get,
data: {type: 'text'}
%>
CoffeScript:
$(document).ready ->
$("#button").on("ajax:success", (e, data, status, xhr) ->
alert xhr.responseText
).on "ajax:error", (e, xhr, status, error) ->
alert "error"
Solution 3
I know this question is 3 years old, but it comes up high in Google results and some of the events listed above are not used anymore.
See here for a current list - https://github.com/rails/jquery-ujs/wiki/ajax
Related videos on Youtube
nathanvda
Now mainly C++/Ruby-Rails/SQL/Oracle/jQuery/git. I started out programming MC68000 assembler for Sinclair QL when i was 16. Studied Computer Science. Developed mostly in C++ ever after. Occasionally did some c# and java. Moved to Ruby on Rails in 2009.
Updated on July 09, 2022Comments
-
nathanvda almost 2 years
Previously, in rails 2.3.8 i used the prototype-helpers
link_to_remote
andform_remote_for
(amongst others).These had the option
:update
as follows:link_to_remote "Add to cart", :url => { :action => "add", :id => product.id }, :update => { :success => "cart", :failure => "error" }
(an example from the documentation). This example would, upon success update the html-element with class "cart", and upon failure the class "error".
Now i believe the modus operandi has changed, instead we write:
link_to "Add to cart", :url => {:action => "add", :id => product.id}, :remote => true
and there is no option to set
:update
anymore. Instead of a normal html, we now render javascript, like this (in jquery) :$('.cart').replaceWith(<%= escape_javascript(render :partial => 'cart') %>)
but how do you handle an error situation? Do i handle it in my controller, and use seperate views?
It would seem useful to me to somehow be able to mimic the behaviour we had before. Any ideas?
-
Amala over 13 yearsAm I the only one who thinks they took a step back with removing simple javascript from Rails?
-
nathanvda over 13 yearsLike css splits much of the layouting from the content (HTML), it is also better to split the behaviour from the HTML (so use unobtrusive js). While this is, indeed, harder (at first), it also makes your HTML/JS easier to read (use your class-names and identifiers wisely), and makes your JS easier to maintain and re-use in the longrun.
-
tmaximini over 12 years'ajax:loading' did not work for me, I had to use 'ajax:before' - just in case anybody else encounters this problem. (Rails 3.1.1)
-
nathanvda over 12 years@Axsuul: please check the code of the rails.js : there is no event variable triggered!
-
benz001 about 11 yearsAnd for the latest jQuery rails callbacks see the GitHub page: github.com/rails/jquery-ujs/wiki/ajax