Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery bind ajax:success not working in rails 3 app for newly created (ajax) items

**Edited this post because I found the problem is really in the inability of rails to bind to the ajax:success function.

***Using rails 3.2.3

Thanks for taking the time to read and try to help.

I am adding a simple fade out function on the ajax:success of an item being deleted, as follows:

$(document).ready( jQuery(function($) {
    $('.delete').bind('ajax:success', function() {
        $(this).closest('div').fadeOut();
    });
}));
#For some reason had to pass the $ into the function to get it to work,
#not sure why this is necessary but doesn't work unless that is done.

After this, I wanted to create an object with unobtrusive jQuery when the user adds something, and have working delete buttons on those as well. I made a create.js.erb file that is called after creating a new item - and the creation works fine, but the delete button cannot access the ajax:success event.

It does delete the data from the db when clicked, but the .fadeOut is never bound to it, so it doesn't disappear. The create.js.erb is as follows:

#$("div").append(html) here, then call the function below to try and bind the ajax:success function
$('.delete').bind('ajax:complete', function() {
    $(this).closest('div').fadeOut();
});

If I change this to bind to the click function, it works, but this doesn't account for a failed ajax call:

#$("div").append(html) here, then call the function below to try and bind the ajax:success function
    $('.delete').bind('click', function() {
        $(this).closest('div').fadeOut();
    });

So something must be up with binding to the ajax:success after the item is created. You guys have any idea why this might be happening? Do I need to do something special in rails to get the newly rendered item to recognize ajax events? Any direction would be much appreciated!

P.S. The controller for the delete method is below in case anyone might be able to detect a problem there:

def destroy
    @user = User.find(params[:user_id])
    @item = @user.item.find(params[:id])
    @item.destroy

    respond_to do |format|
      format.html { redirect_to user_path(@user) }
      format.json { head :no_content }
      format.js { render :nothing => true }
    end
end
like image 274
Anthony Avatar asked Jul 10 '12 04:07

Anthony


4 Answers

The problem sounds like the bind is happening before the element is generated. Try this:

$(document).on('ajax:success', '.delete', function(e) {
    $(e.currentTarget).closest('div').fadeOut();
});
like image 193
Ivan Fong Avatar answered Nov 14 '22 18:11

Ivan Fong


I had the same issue, because my form handler method returned a plain string. Be sure to render something jQuery can process:

def handle_form
  ...
  render :json => {:what => 'ever'}
  # or
  render :nothing => true
end
like image 28
André Pankratz Avatar answered Nov 14 '22 19:11

André Pankratz


I've done similar things recently using Rails 3.2.3. I also use

$('#dialog-form').bind('ajax:success', function() {
})

and it works fine...

like image 1
xiaodaidai Avatar answered Nov 14 '22 18:11

xiaodaidai


Even though this is an old question, I have an updated answer for what works out to be the same issue.

As of version 1.9, jQuery will no longer consider an empty repsonse(render nothing: true) to be a success/done. This means that in your controller you should return an empty JSON object instead.

respond_to do |format| format.json { render: {}.to_json } end

like image 1
Ravenstine Avatar answered Nov 14 '22 20:11

Ravenstine