Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Advanced CTools - Run a CTools Javascript call at any time

Parent Feed: 

Posted by John Ennew on Friday, 23 September 2011 at 12pm

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

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web