ajax:success and ajax:complete callback doesn't work when using UJS in Rails

medBouzid picture medBouzid · Oct 15, 2013 · Viewed 8.9k times · Source

I have a link that when i click on it will trigger an ajax call then replace this link by another link, says for example the original link is "add friend", when i click this link it will send an ajax request to add_friend action then if the friend is added the link above will be replaced by another link "cancel request", i use ujs for that :

$("#link_for_friend").html("<%= escape_javascript(render('users/cancel_link')) %>")

when i try to add callback (:success and :complete) it doesn't works, i tried with :beforeSend like the following it works :

$(document).ready ->
  $("#my_link").on "ajax:beforeSend", ->
    alert("hello")

there is a solution for success and complete callback ?

note : my idea is to show an loader.gif when ajaxStart is triggered then hide it when ajax:complete callback is triggered at least , also if there is some error i want to show it when ajax:error is triggered

Update

I tried to solve this by moving the code inside action.js.erb to js file like this :

  $(document).ready ->
  $(document).on("ajax:success", "a.invitation-box", ->
    $("#link_for_friend").html("<%= escape_javascript(render('users/cancel_link')) %>")
  ).on "ajax:error", "a.invitation-box", ->
    alert "error"

but this way its not possible to put render('users/cancel_link') inside a JS file

Answer

elsa picture elsa · Mar 22, 2014

I had the same issue, and the problem is not with ajax:success or ajax:complete callback. The problem is that when displaying the loading gif image, you replace the content of the container, including the link itself. So the element on which you apply the success, complete callback is not part of the DOM anymore, that's why the callback is not fired.

One solution would be to hide the element and append the loading image, like following:

$('#my_link').on "ajax:send", (event, xhr, settings) ->
        $('#my_link').hide()
        $("#my_link_container").append("<image src = 'img.gif' />")

Then the success and complete callback will be fired. Hope it helps somebody :)