Labs
Advanced CTools - Run a CTools Javascript call at any time
CTools is a widely used Drupal API module which provides functional frameworks for modules such as Views, Panels, Context and more. In addition to its many uses, it has great JavaScript capabilities.
Tutorials on the web only tend to describe how to fire off a CTools AJAX call when clicking on a link. What we will show you is how to fire off a CTools call on other events, such as on page load.
To do this, you will need to create a custom module; our code assumes you've called your module 'mymodule'.
In your module code, start by defining a hook_menu path (if you haven't already), this will give us a URL to ping for updates via AJAX:
function mymodule_menu() { $items = array(); $items['mymodule/%ctools_js/refresh-elements'] = array( 'title' => 'AJAX callback - refresh the elements on the page', 'page callback' => 'mymodule_refresh', 'page arguments' => array(1), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; }
Note that the '%ctools_js' part of the path that gets replaced by JavaScript on page load if the client's browser has JavaScript enabled. If JavaScript is disabled it will stay as it is and fall back on nojs. As it's an argument we can pass it to our callback function. In our example this is more convention than a requirement as we won't be providing a no JavaScript fallback.
Next, define the callback function referenced in the menu item:
function mymodule_refresh($js = FALSE) { if (!$js) { // this is js only return; } ctools_include('ajax'); $commands = array(); $commands[] = ctools_ajax_command_html('.some-class', 'some-value'); ctools_ajax_render($commands); }
This function will only work when the menu is called via a CTools AJAX request. When it runs it will replace the inner HTML of all elements on the page with a class of 'some-class' with the string 'some-value'.
In order to perform this action on an event other than clicking on a link, we need to implement custom JavaScript which will be run on page load.
In your module make a directory called 'js' and within that, a file called 'mymodule.js' with the following contents:
Drupal.CTools.AJAX.refreshElements = function() { var url = '/mymodule/ajax/refresh-elements'; try { $.ajax({ type: "POST", url: url, data: { 'js': 1, 'ctools_ajax': 1}, global: true, success: Drupal.CTools.AJAX.respond, error: function(xhr) { Drupal.CTools.AJAX.handleErrors(xhr, url); }, complete: function() { }, dataType: 'json' }); } catch (err) { alert('An error occurred while attempting to process ' + url); return false; } return false; }; $(document).ready(Drupal.CTools.AJAX.refreshElements);
This JavaScript code will attempt an AJAX call to the menu link you defined earlier and will pass the return value over to the CTools JavaScript handler. When passed to the CTools handler, it will perform the commands you specified in the callback 'mymodule_refresh'. The last line is the trigger point (document ready) where our JavaScript behaviour is called.
You need to include the JavaScript file on every page you want this to run. If this is every page on the site, then you can implement a hook_init function and use ctools_add_js. Note that the function ctools_add_js requires that your JavaScript file lives within a 'js' folder in your module, and must have a '.js' file extension.
function mymodule_init() { ctools_add_js('mymodule', 'mymodule'); // first arg is the javascript filename without the .js, second arg is the modulename }
In the above code, the first argument for ctools_add_js is the name of the JavaScript file without the '.js' file extension, the second argument is the module name.
And that's it! CTools provides a lot of functions which you can add to the $commands array in the menu callback function to effect the page via ajax. For a full list of functions visit:
http://drupalcontrib.org/api/drupal/contributions--ctools--includes--ajax.inc/6
Comments
payday loan - payday loan , http://quickpaydayloannocreditchecks.com/#4112 payday loans no credit checks
Thanks to all. It was very helpful.
But when I call the callback url I get the entire JSON array with values from other modules like ligtbox2, jcarousel an views slideshow.
Therefore, after calling "ctools_ajax_render ($ commands)", all JSON objects are being reinterpreted. Is there a way to limit this json response (for example to only one element of the commands-array from the "function mymodule_refresh($js = FALSE)" )
best regards,
André
I don't really understand why this is happening to you. The commands array is limited to the ones you put into it in the function mymodule_refresh. In the example this is a single simple class change and as far as I can tell this is all that would happen on page load.
i am trying to use the javascript you provided in drupal 7 with no success.
please help
below is what i am trying ,getting error Undefined.
@John Ennew , You are the man,thank you alot.
now ts working like a charm.
Hi Chaz,
This article only works with Drupal 6. I was meaning to write a Drupal 7 equivalent and so have now done so which you can find here:
https://deeson-online.co.uk/labs/trigger-drupal-managed-ajax-calls-any-ti...
Kind regards,
John
Thanks for this. It was very helpful. One thing though: I think you need to add
to the beginning of your mymodule_init() function. My version of your example would not run until I did that, because Drupal.CTools.AJAX was undefined.
Add new comment