7

I need to do some extra things after Drupal ajax is done inserting some stuff into the DOM. With jQuery this was brain-dead simple, but I can't for the life of me figure out how to do it in Drupal 7 :s

Do I add something to my ajaxified link? I read something about attaching a behavior...confusion is setting in...

1
  • 3
    1. What is triggering the AJAX call? 2. Behaviors are the right approach. 3. They are not really hard ;) Commented Jan 5, 2012 at 0:56

7 Answers 7

6

I ended up adding some additions commands to the page that is being returned by the ajax handler like this:

$commands = array(); $commands[] = ajax_command_invoke(NULL, 'grid_content_loading', array('argument1', 'argument2')); $commands[] = ajax_command_append('#grid-content-target', $html); $commands[] = ajax_command_invoke(NULL, 'grid_content_loaded', array('argument1', 'argument2')); $page = array('#type' => 'ajax', '#commands' => $commands); ajax_deliver($page); 

And on the client side I created 2 javascript funtions through jQuery:

(function($) { $.fn.grid_content_loading = function($argument1, $argument2) { ... }; $.fn.grid_content_loaded = function($argument1, $argument2) { ... }; })(jQuery); 
2
  • 1
    Have you looked at Drupal.Behaviors, like amateur barista suggested? Commented Jan 5, 2012 at 8:08
  • For example, if you want to update a hidden field with id "block", you can use: $commands[] = ajax_command_invoke('#block', 'val', array($value)); Commented Apr 26, 2013 at 14:33
3

In my project, I had already written well-defined JavaScript code that updated the page stats after an AJAX call.

Since I wanted to reuse the functions without going to the extent of "extending jQuery", I ended up with the following solution, using an existing jQuery function, instead of defining a new one. This was inspired by what the 'flags' module does -- it simply triggers an event, and allows many Javascript event listeners to act in response, as opposed to having just a single hard-coded, custom jQuery plugin/extension as in the solution explored in the previous answers.

In a Drupal Module:

// in_some_ajax_function() $commands[] = ajax_command_invoke('html', 'trigger', array('MY_EVENT')); 

In Javascript:

// Added an event binding to my $(document).ready(); $(document).ready(function(){ $(document).bind('MY_EVENT', function() { alert('MY_EVENT'); }); }); 

I had to note that the first parameter for ajax_command_invoke is NEVER any native JavaScript objects, so the following never works, because it translates into a 'document' (element) selector:

// This tries to select $('document') // ... which is nothing, since there are no 'document' elements. $commands[] = ajax_command_invoke('document', 'trigger', array('MY_EVENT')); 

Curiously, binding on $(document) and triggering on $('html') are compatible. I suppose you can get very creative, and bind/trigger on more specific, deeper-level elements. If you can think of a scenario where doing so makes more sense than a top-level event trigger, please comment!

1
  • Thanks! Also you can add a second argument, next to "MY_EVENT" in this answer, to pass it to the function executed by your event in your JS code. For passing multiple arguments or objects you could use json_encode. Your JS event should receive 2 arguments, your first argument is the event itself and the second argument is your JSON_ENCODED thing. PHP: ajax_command_invoke('html', 'trigger',['agregar_qtip',json_encode(['#edit-linea-0-id-producto','No existe'])]) JS: $(document).bind('MY_EVENT', function (event, args) { }); Hope that helps! Commented May 20, 2015 at 0:57
3

Code sample:

$commands = array(); $commands[] = array( 'command' => 'your_js_callback', // the name of your javascript callback 'value1' => 'My first value', 'value2' => 'My second value', ); ajax_render($commands); 

JS Code:

(function($, Drupal) { Drupal.ajax.prototype.commands.your_js_callback = function(ajax, response, status) { alert(response.value1); alert(response.value2); } })(jQuery, Drupal); 
2

I think that the best option is use the jQuery ajaxComplete function:

(function($){ $(document).ajaxComplete(function(e, xhr, settings) { alert(settings.url); }); }(jQuery)); 

And if you want use the function for specific ajax function you can use the identified settings.url for your field and change that to:

(function($) { $(document).ajaxComplete(function(e, xhr, settings){ if (settings.url == "the path from step 1") { // Code to populate your fields here } }); }(jQuery)); 

This worked for me for Drupal 7 and 8.

0

Quick hack solution: Place an image inside the loaded content and give it the onload="[javascript function]()" attribute. Not sure this is actually what you're looking for... Or if this is easier than the correct way... But maybe better than nothing?

0

I've posted an answer to this question on so

https://stackoverflow.com/a/19404566/894487

I'm not sure of the real differences between extending Drupal.ajax.prototype.commands or $.fn

I imagine the former would be more efficient as their is no dom traversal required to hit your function. Not sure if that is important.

0

I wrote a tutorial on how to do this in Drupal 7: https://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.