1

I have a view, that is refreshed with ajax. I'm using Jquery 1.7.2

You click a button, that call a javascript function :

$(view_identifier).trigger('RefreshView');

Before this refresh, I've attached on click handler to an ajax link. The link call a modal popup and must trigger a javascript function. The link contains a picture, but I have tested with just text and I get the same result. So I'm trying to attach an handler to an ajax link.

Here is the html :

<body>
 //lot of things .... 
   <a class="use-ajax">
      <img width="25" height="25" src="/sites/default/files/picture.png">
   </a>
 //lot of things
</body>

And here is the javascript :

$('a.use-ajax > img').on('click',function(){
  console.log('test');
  foo();
});

That work fine, until the view is refreshed. After the refresh, the function foo isn't being called anymore. Thats because the handler is not being attached to dynamic elements.

So I change the part above to this :

$(document).on('click','img',function(){
  console.log('test');
  foo();
});

So that I can use the event delegation provide by Jquery.

And it isn't working. When I click on the link, nothing is happening. The strange part is when I remove the use-ajax on the link (become a normal link without the Drupal ajax part), it works.

I've tested a lot of variation and nothing seems to work.

I've used an old jquery code :

$(document).click(function(event){
   //check if its a click on the link with event
   console.log('test');
})

and It doesn't trigger either. If I click anywhere on the page, the 'test' show up in console, but not when I click an ajax link. I don't understand this because, it would mean that the link isn't in the dom.

Does anyone have an idea ?

6
  • Without checking (so might be wrong), I'll bet the click handler on .use-ajax elements either returns false, or does a nice little e.stopPropagation(), shorting out your code
    – Clive
    Commented May 25, 2016 at 14:44
  • Thanks a lot ! I've run this small code : $('a.use-ajax').on('click', function(event){console.log(event.isPropagationStopped());}) and it return true ! Imight be this but I'm not sure.
    – Once a Dev
    Commented May 26, 2016 at 9:05
  • Yep that'll be it - delegation in ($.on works because of event bubbling, so when you click on a link all its parents receive the click too, with the order going from deepest (i.e. the link itself), out to the shallowest (document). If the link has an explicit event handler which stops propagation, or if any other element up the chain does the same thing, the event will simply never bubble up to the document, which your event handler is attached to, so the code will never run
    – Clive
    Commented May 26, 2016 at 9:11
  • The problem is that the stopPorpagation method is called in drupal's javascript, when the page is rendered and I cannot modify it. Is there a workaround ? And I've seen that when I try to attach an handler like this : $('body').on('click', 'a.use-ajax', function(e){ alert('test'); });, the number of event does not change when I run this console.log($("a.use-ajax").first().data('events'));. It always print 1. The on function fails to attach the handler.
    – Once a Dev
    Commented May 26, 2016 at 9:37
  • Stick your code in a Drupal behavior? That should do the trick as the events will be re-attached every time Drupal AJAX runs
    – Clive
    Commented May 26, 2016 at 9:39

1 Answer 1

0

Thanks to Clive, I've found one way to make it work : wrap the code into a drupal behavior.

It look like this :

(function($) {
  Drupal.behaviors.refresh_views = {
    attach: function () {

        var view_identifier = '#view_id'; 

        //attach the on click handler to all links of class 'use-ajax'
        $('a.use-ajax').on('click',function(){
            $(view_identifier).trigger('RefreshView');
        });
    }   
  };
})(jQuery);

I'm attaching an handler with my first version of the onclick function :

$('a.use-ajax').on('click',function(){
    foo();
});

So without the delegate part (does not work when an element is created after the script execution). In my case, I'm reloading the view with an ajax request. And in drupal 7, each time a request finishes the ajax behavior is called again. So the code is executed and it bind the on click event into the new elements.

I'm leaving a little warning here : This script is executed on every ajax request (if you open a modal popup in the ajax way, it will add an event into the click handler). So it might bind a lot of time the same event ! So don't forget to control the amount of events that your are adding to the same handler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.