Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When doing a .replaceWith() in jQuery the event bindings are not preserved

Here's a condensed example.

Keep in mind that the .chat-reply class has a click event handler bound to it.

The HTML (Reply Button):

<div class="container">
    <a href="#" class="btn small chat-reply">Reply</a>
</div>

This jQuery function is called when someone clicks another button that sends a message to the server to be saved in the database. This is done via ajax and is done successfully. In the aforementioned .ajax() success() callback this function is called:

$.ajax({
      type      :  'GET',
      url       :  '/some_controller/some_method',
      success   :  function(data) {

      $('.container').replaceWith(data);
    }
});

The 'data' in the success callback above will replace the entire .container div including the child .chat-reply button. After this replaceWith(), the click event is no longer bound to the button.

Logically, I'm attempting to have the end user post a message to a timeline, then have that message display in the timeline without needing to refresh the screen.

like image 763
generalopinion Avatar asked Feb 14 '12 03:02

generalopinion


2 Answers

Grab jquery 1.7 that now uses 'on' to bind: http://blog.jquery.com/2011/09/28/jquery-1-7-beta-1-released/

Or if < 1.7 use 'live' instead of 'bind' as it will look for DOM changes and re-apply the events of changed content. If not you can reapply the event on your callback.

Old api to replacement to bind with live type event handlers after DOM changes.

this $(selector).live(events, fn)

becomes this $(document).on(events, selector, fn)

Or in code

This

$(".container a.chat-reply").live("click", function(){
 // do it live!
});

Becomes this in 1.7

$(".container").on("click", "a.chat-reply", function(event){
 // do it live!
});

With various options to selecting the object you want.

like image 60
Ryan Christensen Avatar answered Sep 30 '22 03:09

Ryan Christensen


In your click handler, use .on() as a delegate instead

$("div.container").on("click", "a.chat-reply", function(even){
  //click handler here
});

the event will 'bubble' up to container, and if it matches a.chat-replay it will trigger.

like image 24
Vigrond Avatar answered Sep 30 '22 04:09

Vigrond