Hi all,

Please double check my understanding because I'm not sure: Drupal.attachBehaviors() is not executed on the AJAX content loaded by the Views pager. Am I right?

Please let me know if this is as-designed or a bug :) I could see arguments either way.

Comments

raspberryman’s picture

Status: Active » Closed (fixed)

Yes, it is called by Drupal.Views.Ajax.ajaxViewResponse(), so I am doing something wrong. Answered question myself :)

raspberryman’s picture

Status: Closed (fixed) » Active

Well I could not figure this out :(

Drupal.Views.Ajax.ajaxViewResponse() seems to pass the old target to Drupal.attachBehaviors(), and not the newer response.display

So I could not reattach behaviors to the new AJAX content. Is this a bug?

For reference, here is Drupal.Views.Ajax.ajaxViewResponse():

Drupal.Views.Ajax.ajaxViewResponse = function(target, response) {

  if (response.debug) {
    alert(response.debug);
  }

  // Check the 'display' for data.
  if (response.status && response.display) {
    var view = $(target).replaceWith(response.display).get(0);
    Drupal.attachBehaviors(view);
  }
};
merlinofchaos’s picture

That replaceWith should cause the new code to be sent to attach behaviors. To the best of my knowledge this works since ajax pagers continue to work after AJAX page loads, and it wouldn't if that were broken.

darrenmothersele’s picture

There must be something strange going on here. I am having the same problem with behaviors not being re-attached to content within a view pager when the page changes via AJAX.

I have the following code in script.js to attach my behaviours to the block:

Drupal.behaviors.discussion = function (context) {
  $('.myclass:not(.discussion-processed)', context).addClass('discussion-processed').each(function () {
   // custom code in here     
  });
}; 

It works and attaches the behaviour to the first page of results but when the page changes via AJAX the behaviours are not reattached.

This must be something to do with the context being provided because if I substitute 'document' instead of context then my behaviours get reattached correctly...

Drupal.behaviors.discussion = function (context) {
  $('.myclass:not(.discussion-processed)', document).addClass('discussion-processed').each(function () {
   // custom code in here     
  });
}; 

Does this suggests that attachBehaviors is being called, but with the context provided it is not picking up my behaviours?

merlinofchaos’s picture

Status: Active » Closed (won't fix)

I don't know why it wouldn't be picking up your class there. That's beyond my ability to help you debug, though; I know it works for the Views ajax pagers. Your code looks right but I'm not sure. Perhaps something you're using to select your class is relying on something that's outside the context? If that's the case it is probably safe enough to ignore the context since you're using the .processed check anyway.

raspberryman’s picture

darrenmUK - I ended up just using the entire page rather than context. As merlinofchaos said, the code is all technically correct and works as expected for views ajax. I am probably just missing something but I don't know what.

I know we can rule out the idea of the jquery selector trying to use an element outside of 'context'. I tried dozens of different selectors and never made progress.

darrenmothersele’s picture

Yes raspberryman, as much as I love trying to debug Javascript code, I'm pretty much lost on this one so I'm sticking with using document rather than 'context'.

As everything is technically correct in the views implementation of behaviours - does that mean this is looking like an issue for the core javascript?

raspberryman’s picture

As everything is technically correct in the views implementation of behaviours - does that mean this is looking like an issue for the core javascript?

I think it is option #3 - there is something wrong with my knowledge of javascript :)