1

I have a page where a block is dynamically reloaded when the user clicks a link. Rather than writing my own js, I'm trying to do this the Drupal way and using Drupal's own ajax_command_replace() like so:

function page_callback($type = 'ajax') {
    if ($type == 'ajax') {
    // Load block
    // ....
    $commands[] = ajax_command_replace('#block-watch-notifications', $output);
    $page = array(
       '#type' => 'ajax',
       '#commands' => $commands,
    );
    ajax_deliver($page);
}

And all this works just fine.

The problem is that I need to respond to this event on my page. The js event DOMSubtreeModified would work here if it were reliably implemented by browsers, but it's not.

However, jQuery's AJAX command also issues its own series of global events, including ajaxComplete. The problem is that, however Drupal is doing its AJAX magic, it isn't raising this event.

How can I listen for ajax_command_replace() having done its work on my page?

2

The API documentation tells us that ajax_command_replace() is handled in javascript by Drupal.ajax.prototype.commands.insert. At the end of the javascript insert function, Drupal attaches behaviors to the newly added content, passing any settings set in ajax_command_replace().

From this we know that you can add your own behavior and check for a specific setting you set to know that your acting on your content. This will allow you to do some action when the AJAX is "complete".

The other option is to register a Global jQuery AJAX Event Handler. These event handlers are fired for every single AJAX event on a page (assuming of course that jQuery is used for sending the request) and requires a lot of checking and rechecking to make sure you're acting on the request you want.

0
3

From what I can tell, Drupal behaviors are simply callback functions that are called in two cases: 1. when the page is loaded initially, and 2. when content is added/removed via ajax.

You add your callback function to the global js object Drupal.behaviors (US spelling), namespaced by your module's name. My module is called 'watch' so I attach my callback functions to Drupal.behaviors.watch. Drupal.behaviors.MODULE_NAME is itself an object and has two elements that may be named 'attach' and 'detach'.

'Attach' is called during the initial page load and whenever Drupal's ajax adds new content. 'Detach' is called when is Drupal's ajax removes content, either before adding replacement content or removing it forever.

For the record my javascript looked like this:

(function($) {
  Drupal.behaviors.watch = {
    attach: function(context, settings) {
      // This code is fired both when the page is 'ready'
      // in the jquery sense, and when new content
      // is 'attached' via Drupal ajax. The settings
      // values that are available to us here
      // are provided in the third parameter of
      // ajax_command_replace() as an associative array.
      // My new content is already part of the dom
      // so I can act on it here.
    },
    detach: function(context, settings, trigger) {
      // Example detach callback.
    }
  }
})(jQuery);

I'm guessing Drupal behaviors can be extended to include all sorts of other behaviors beyond attach and detach and is probably very flexible besides, but that's beyond me right now.

1

There is hook_ajax_alter: http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_ajax_render_alter/7 This works on php level, but if you do it there, you could search the commands and add your custom command if wanted.

3
  • 1
    The question is specific about responding to a JavaScript event.
    – apaderno
    Aug 20 '11 at 6:56
  • Except I've issued the ajax commands myself (see above). hook_ajax_render_alter() doesn't let me alter the nitty gritty js (eg. to cause it to trigger an event), it just lets me reissue the commands differently (eg. change the selector). Or am I missing something?
    – Torrance
    Aug 20 '11 at 6:57
  • Well you could scan through the commands and look for ajax_command_replace. If there is, replace it with your ajax_command_custom_replace which allows does ajax_command_replace and some random custom stuff. Aug 20 '11 at 7:16

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.