views:

558

answers:

3

When using

$('.foo').click(function(){  
    alert("I haz class alertz!");  
    return false;
  });

in application.js, and

<a href = "" class = "foo" id = "foobar_1" >Teh Foobar </a>

in any div that initializes with the page, when clicking "Teh Foobar" it alerts and doesn't follow the link. However, when using the same code in application.js, and

<a href = "" class = "foo" id = "foobar_1" >Teh Foobar </a>

is being returned into a div by a

form_remote_tag

when clicked, "Teh Foobar" fails to alert, and functions as a link.

What is happening, and how do I get around it?

+3  A: 

Markup returned from an AJAX call isn't present when you set up the page, so it doesn't have any onclick handlers associated with it. You'll need to hook into the Rails AJAX support so that when it loads your AJAX-powered div, it also executes your event setup code again.

John Millikin
+2  A: 

New elements added to the document after you bind your events don't automatically get those event handlers. One way to fix this is - as John Millikin says - re-bind your events after you create new elements.

The other standard way is event delegation. Because events go all the way up and down the stack through all their parent elements, you can bind an event to an element that will be an ancestor of all your target elements.

For instance, this jQuery code would work (your syntax may vary for other JavaScript libraries):

$(document).ready(function() {
  $('body').click(function(event) {
    if ($(event.target).is('.foo')) { // <- this is the magic
      alert('Something of class foo was clicked.');
      return false;
    }
  });
});

Now when you click something of class foo this event will get fired unless something in between catches the event and cancels the bubbling. Actually, event will be called when almost anything is clicked - the "if" statement just filters out which events deserve the alert.

Neall
+3  A: 

You could also use Live Query jQuery plugin which is able to automatically bind events for matched elements after the DOM is updated. In your case it would be:

$('.foo').livequery('click', function() {  
    alert("I haz class alertz!");  
    return false;
});
Alexander Prokofyev
Yeah. I came across this solution later while searching for something else. I might end up refactoring into it.
DA
This plugin is no longer needed if you are using jQuery 1.3.2 `live` function
Eduardo Molteni