0

I am using Ruby on Rails 4 and I would like to handle links with data-* attributes the correct way when some HTML element is dynamically added to the DOM. That is, in my view file I have the following:

<div id="css_id">
  <%= link_to("Title 1", link_path, :remote => true, "data-custom-target" => "css_id"}) %>
</div>

In my application.js file I have:

$(function() {
  $('a[data-custom-target]').on('ajax:success', function(xhr, data, status) {
    css_selector = $(this).data('custom-target');
    target = $("#" + css_selector);

    target.replaceWith(data);
  });
});

When I click on the above link then (on AJAX response success) the container div is replaced with the following rendered code:

<div id="css_id">
  <%= link_to("Title 2", link_path, :remote => true, "data-custom-target" => "css_id"}) %>
</div>

As you can see, the new rendered code contains a similar link element with the data-custom-target attribute set. However, if I re-click on the link then the application.js seems to not have effect as in the first case: it seems do not "bind" the $('a[data-custom-target]').on('ajax:success', ...) to the new rendered link.

What is the problem? How can I solve that? What do you advice about?

user502052
  • 14,088
  • 30
  • 102
  • 181
  • Because you're adding elements to the DOM you need to delegate the events. For example `$('body').on('click', 'a[data-custom-target],...` will bubble up to body and be handled there. – Jay Blanchard May 28 '14 at 17:05
  • I never delegated a method. How can it be made in my case? – user502052 May 28 '14 at 17:06

1 Answers1

1

use event delegetion for that, which will help you to bind events to the future elements.

$(function() {
  $(document).on('ajax:success',"a[data-custom-target]", function(xhr, data, status) {
    css_selector = $(this).data('custom-target');
    target = $("#" + css_selector);

    target.replaceWith(data);
  });
});
Anoop Joshi
  • 24,460
  • 8
  • 28
  • 49
  • In the `jquery_ujs.js` Rails' file there are many statements like `$document.delegate(...)`. If I would like to use `$document.delegate(...)` what I have to make? – user502052 May 28 '14 at 17:11
  • You don't have to use `$document.delegate` because what @AnoopJoshi has shown you will take care of it. – Jay Blanchard May 29 '14 at 12:40