ajax pager working depends on if js file is loaded in module .info file I'm using the code I've outlined in my blog post for a custom image search, and I'm having a problem with the pager, but only on one site. The first page of results renders just fine, but when I try to go to a subsequent page, I get a white screen with JSON; the page modal window is not rendered.

Here's the relevant code where it breaks:

  $form_state['values']['title'] = t('Search Results - Page !page', array('!page' =&gt; $pager + 1));
  $output = ctools_modal_form_render($form_state['values'], $build);

  print ajax_render($output);
  drupal_exit();


What's weird is that I have this exact same code working on two different sites, and it works fine on one, but not the other. I've looked at every possible variable I can think of, and they're all the same:


Drupal core version
jQuery version
module code (custom and contrib, Filefield Sources in this case)
form output sent to ajax_render
returned output from ajax_render


What else could I be missing that causes the JSON not to be rendered? I'm not looking for code specific info, just bigger picture items I could be missing.

Thanks.

UPDATE: So it looks like the problem has to do with the loading of my Drupal behaviors js file (seen at the bottom of this post. If I load it in the module .info file, the pager works fine, but if I attach it anywhere else - either to the node edit form or the ctools modal form - the pager chokes. I've inspected the page, and my js file is loaded in the page and ctools classes assigned to the pager buttons before clicking the pager, so it's not like they're not there. Unfortunately, for some reason, loading this file in the .info file causes other problems, so we can't do it globally.

But why would the method of loading the file make a difference as long as it's loaded?
It is the Drupal behavior JS code copied form your blog post.

(function ($) {
  Drupal.behaviors.addCtoolsModalClass = {
    attach: function (context) {
        $('#modalContent .pagination ul li a').addClass('ctools-use-modal');
        $('#modalContent .pagination ul li a').addClass('ctools-modal-imgsearch-modal-style');
    }
  }
})(jQuery);


The most meaningful thing I can find here is the class name ctools-use-modal. Obviously, this class name is used for ctools module. So I search this class name and find below snippet from js/modal.js in ctools module (version 7.x-1.9).

  Drupal.behaviors.ZZCToolsModal = {
    attach: function(context) {

      $('area.ctools-use-modal, a.ctools-use-modal', context).once('ctools-use-modal', function() {
        var $this = $(this);
        $this.click(Drupal.CTools.Modal.clickAjaxLink);


Now we have the full picture.

In your JavaScript code, you want to add a class name which is required for Ctools JavaScript code. AJAX does not work because the Ctools JavaScript code is run before adding the class name, so Drupal.CTools.Modal.clickAjaxLink never bind to the link.

Yu can fix it by manually run the attach behavior again after adding classname.

Solution

(function ($) {
  Drupal.behaviors.addCtoolsModalClass = {
    attach: function (context) {
        $('#modalContent .pagination ul li a', context)
          .addClass('ctools-use-modal')
          .addClass('ctools-modal-imgsearch-modal-style');

        Drupal.behaviors.ZZCToolsModal.attach(context);
    }
  }
})(jQuery);


Note: since all the code inside Drupal.behaviors.addCtoolsModalClass is wrapped with jQuery.fn.once, which means every code inside is only be implemented once if the selector finds the element. So you don't need to worry about binding the same event twice.