2

There are many examples how to make ajax form submits and also many examples how to make drupal ajax links. But how to attach ajax click events for example on <button> or <div> elements?

0

You need to write code for this element. Copied from d.o..

STEP BY STEP

Select the element to attach Drupal.ajax object to. Lets create HTML element first.

/**
 * Menu  callback. 
 * 
 * Build container to load ajax content to. 
 */
function my_module_remote() {
  $wrapper = array();
  $wrapper['#attached']['js'] = array(
    drupal_get_path('module', 'my_module') . '/my_module_ajax.js'
  );
  $wrapper['#attached']['library'] = array(
    array('system', 'drupal.ajax')
  );
  $wrapper['container'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'id' => 'remote-content-wrapper',
      'title' => t('click to reload')
    )
  );
  $wrapper['container']['content'] = array(
    '#markup' => t('Loading data...')
  );
  return $wrapper;
}

This callback will create simple page with div container and text "Loading data..." on it. Pay attention to element with id "remote-content-wrapper". This div container we will be base DOM element for our Drupal.ajax object. In JS code we select it is with #:

$('#remote-content-wrapper').once('remote-content-wrapper', function() {
  var base = $(this).attr('id');
...
});

NOTE: I use '$.once()' method here to attach behaviour only once. Read more. So, the HTML element selected and it is div#remote-content-wrapper.

Build object of options for new AJAX element. ...

    var  element_settings = {
          url: window.location.protocol + '//' + window.location.hostname +  settings.basePath + settings.pathPrefix + 'ajax/remote',
          event: 'click',
          progress: {
            type: 'throbber'
          }
        };

... The only required keys is:

'url' - the path to make ajax call to, any drupal full path.
'event' - the javascript/jQuery event to react to, any string or one of the registered like 'click', 'change', 'keypress'
'progress' - the progress type. Object contain 'type' key, which can be either 'throbber' or 'bar'.

Other settings:

    keypress: true, 
    effect: 'none', // jQuery effect.
    speed: 'none', // setting for jQuery effect. 
    method: 'replaceWith', // Will be rewritten with ajax command.
    // The additional data to submit.
    submit: { 
      'js': true
    }

Add the new AJAX object to global Drupal.ajax object. It is simple easy:

Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
Drupal.ajax() function-constructor takes 3 parameters:
- element id,
- DOM object,
- settings object

NOTE: The new element should be stored in global Drupal.ajax array of ajax objects under the element id key. Every Drupal.ajax object on the page are stored in this array.

That it! The Drupal.ajax element created. To trigger new ajax reaction we should call registered in element_settings object event:

$(this).click(); // $('#remote-content-wrapper').click();

I use here click, but you could pass as parameter any event you want, and then trigger it with .trigger() method. AJAX callback should return array of Drupal commands or any custom registered AJAX commands which will be executed after success ajax call.

The complete js part:

(function ($) {
  /**
   * Load remote content after the main page loaded.
   */
  Drupal.behaviors.my_module_load_remote_content = {
    attach: function(context, settings) {
      $('#remote-content-wrapper').once('remote-content-wrapper', function() {

        var base = $(this).attr('id');

        var element_settings = {
          url: window.location.protocol + '//' + window.location.hostname +  settings.basePath + settings.pathPrefix + 'ajax/remote',
          event: 'click',
          progress: {
            type: 'throbber'
          }
        };
        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
        $(this).click();
      });
    }
  };
})(jQuery);

The complete PHP part:

/**
 * Implements hook_menu().
 */
function my_module_menu() {
  $items['ajax/remote'] = array(
    'title' => 'Data',
    'page callback' => 'my_module_remote_ajax',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  $items['page'] = array(
    'title' => 'Data',
    'page callback' => 'my_module_remote',
    'access arguments' => array('access content'),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Menu callback.
 *
 * Output the page with the container to load AJAX content to.
 */
function my_module_remote() {
  $wrapper = array();
  $wrapper['#attached']['js'] = array(
    drupal_get_path('module', 'submit_ajax') . '/submit_ajax.js'
  );
  $wrapper['#attached']['library'] = array(
    array('system', 'drupal.ajax')
  );
  $wrapper['container'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'id' => 'remote-content-wrapper',
      'title' => t('click to reload')
    )
  );
  $wrapper['container']['content'] = array(
    '#markup' => t('Loading data...')
  );
  return $wrapper;
}

/**
 * Ajax callback.
 *
 * Load remote information.
 */
function my_module_remote_ajax() {

  $commands = array();

  $selector = '#remote-content-wrapper';
  $html = my_module_function_to_request_data_form_remote_server_and_build_html();
  // Debug messages, we can use dpm() here.
  $messages = theme('status_messages');
  $commands[] = ajax_command_prepend('body', $messages);
  // Add command with insert new requested content
  $commands[] = ajax_command_html($selector, $html);

  print ajax_render($commands);
  drupal_exit();
}

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.