1

I using ThickBox to display large image when thumbnails are clicked. This works great with static content that;s loaded with the page.

However, I'm now trying to use Ajax calls to display some of the content, as it involves API calls that can slow down the page generation. I've placed a small JQuery document.ready script like this:

Drupal.behaviors.brickFilterBehavior = function (context)  {
  var element = this;
  $('.brick-filter-test').each(function () {
    var element = this;
    $.get('/brick_filter/test/', function(data) {
      element.innerHTML = data;
    });
  });
});

This fetches HTML from the URL and inserts it into a <div> with the class "brick-filter-test". The handler for the URL looks like this:

function lego_filter_test()
{
  // Print out HTML directly.
  print ('<a href="https://images.brickset.com/sets/images/928-1.jpg" rel="lightbox" title="Space Cruiser And Moonbase"><img src="https://images.brickset.com/sets/small/928-1.jpg" alt="Space Cruiser And Moonbase" class="lego-filter-set-image"></a>');
  // Return success.
  exit(0);
}

The real handler uses API calls to generate the content, so I've simplified for this example. This just returns a static HTML snippit.

On my test page, I have the following HTML:

<div>
  <a title="Space Cruiser And Moonbase" href="https://images.brickset.com/sets/images/928-1.jpg" rel="lightbox">
    <img src="https://images.brickset.com/sets/small/928-1.jpg" alt="Space Cruiser And Moonbase" class="lego-filter-set-image">
  </a>
</div>
<div class="brick-filter-test">Loading test content...</div>

You can see this in action here: http://www.neoclassicspace.com/test

In the example, I have two thumbnail images, one statically included in the page, the other dynamically loaded. The static one behaves correctly, and the ThickBox pop-up gets applied. The dynamic one isn't getting the Thickbox treatment, even though it uses the same HTML.

I have tried adding alerts into the JS for both my code and Thickbox, and this has shown that my code runs before Thickbox initialises, so my dynamic DOM objects should be present when it runs.

I've also tried adding Drupal.behaviors.initThickbox(context); to the end of my function, which should cause Thickbox to reinitialise. I've confirmed this runs twice with an alert statement when I do this.

I'm really appreciate any suggestions on this.

Thanks,

James

  • Is your script even running? try putting an alert('hello world'); – No Sssweat May 22 '18 at 4:50
  • My script is definitely running (I did use plenty of alerts while debugging it). The <div> placeholders on the page get replaced with the content from the callback URL. My problem is that the links in the form <a href="..." rel="lightbox" title="..."> are not getting processed by ThickBox because they are loaded after ThickBox has processed the page. – James Shields May 22 '18 at 9:06
  • Well you need to add Drupal.behaviors to the ThickBox code so it runs on AJAX. – No Sssweat May 22 '18 at 9:47
  • Oh, that looks like it might be the problem! Thanks for your help. – James Shields May 22 '18 at 10:30
  • I changed my $(document).ready() to a Drupal.behaviours function. It's adding the images, as before, but still not processing them so they behave as pop-ups with Thickbox. I had a look at the ThichBox JavaScript, and it uses a function Drupal.behaviors.initThickbox(context) to initialise. I've tried calling that after the new images have been added, but that hasn't made any difference. Thanks for the suggestions, but any other ideas? – James Shields May 22 '18 at 22:43
1

You need to add the behaviors like this:

Drupal.attachBehaviors($('.ajax-container'));

So looks like in your case it would be:

Drupal.attachBehaviors($('.brick-filter-test'));

This should do the trick

$.get('/brick_filter/test/', function(result){
  element.innerHTML = data;
  Drupal.attachBehaviors($('.brick-filter-test'));
});
  • 1
    Thanks so much! That seems to have done it. I did have a slight complication that attachBehaviours applies behaviours to the specified element, and my code is itself a behaviour, so it was getting into a kind of infinite loop! I solved this by adding a line $(this).removeClass('brick-filter-test').addClass('brick-filter-test-processed'); and then applying the behaviours to the new class with Drupal.attachBehaviors($('.brick-filter-test-processed'));. This prevents my .each function from being applied again. – James Shields May 24 '18 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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