0

This Drupal example is working with the 'virtual' paths that are not actual nodes, and when I add a node/page with the same fake path 'vms-custom-path/trigger-page but with an existing named node/page like my_drupal_site/test-ajax-page and adding $items['my-ajax-page'] = array() never seems to get called.

//PHP Module 
/// path to our REAL page with a menu block on it in Drupal site
// first to load the js file only on this page 

  $items['test-ajax-page'] = array(
    'title' => 'My custom ajax callback',
    'page callback' => 'addCustomJS',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  ); 

 // then to register the actual ajax call back 

  $items['test-ajax-page/ajax'] = array(
    'title' => 'My custom ajax callback',
    'page callback' => 'My_ajax_callback',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );

I need to use AJAX to update a Drupal page when it loads with data look ups from the server. Most examples use a click or other form event, this for a menu page without any forms and has to happen when the page loads without any user events.

I found a deeson-online's example using Drupal.ajax.prototype.specifiedResponse but it is throwing AJAX errors.

How can I run Drupal AJAX with jQuery when the page finishes loading?

Here's the basic version that did work with the Drupal AJAX Object approach - when I have the jQuery version, as Austin suggested, working for our situation I'll add that.

//PHP Module 
// Returns AJAX commands if the URL has 'ajax' in it
$items['My-custom-path/ajax'] = array(
  'title' => 'My custom ajax callback',
  'page callback' => 'My_ajax_callback',
  'access arguments' => array('access content'),
  'type' => MENU_CALLBACK,
);

/**
* AJAX callback that prints text and link ID. ID will be used for looking up additional data.
*/
function My_ajax_callback() {
  // Define a new array to hold our Drupal AJAX commands.
  $ajax_commands = array();

  // Create a new AJAX commands that will be run in the Browser

  //In this case arg(3) is the Node ID in the URL passed back
  if(is_numeric(arg(3)) ){
  $ajax_commands[] = ajax_command_after('#'.arg(3), 'Hello '. '#'.arg(3) . '!!!'); 
  $ajax_commands[] = ajax_command_append('#'.arg(3), 'Updated');
  $ajax_commands[] = ajax_command_append('#'.arg(3), arg(3));
  }
  else {      
    //return;
    $ajax_commands[] = ajax_command_after('#'.arg(3), 'No data available.'); 
  }

  // Return our commands in JSON.
return drupal_json_output($ajax_commands); 
}
// JavaScript
(function ($) {
  Drupal.behaviors.My_ajax = {
  attach: function(context, settings) { 
  var $MyAjaxLink = $('.My-ajax-link');  

  // Add IDs to the Menu links to query them on the server
  $('div.block div.content div.menu-block-wrapper ul.menu li.leaf a').each(function(index, element) {
        var url =      $(this).attr('href');
        var urlArray = url.split("/");
        var lastPath = urlArray.length -1; 
      $(this).attr('id', urlArray[lastPath]); 
    });

  /**
   * Add an extra function to the Drupal ajax object
   * which allows us to trigger an ajax response without
   * an element that triggers it.

   * From post on  http://deeson-online.co.uk/labs/trigger-drupal-managed-ajax-calls-any-time-drupal-7 
   */
  Drupal.ajax.prototype.specifiedResponse = function() {
    var ajax = this;

    // Do not perform another ajax command if one is already in progress.
    if (ajax.ajaxing) {
      return false;
    }

    try {
      $.ajax(ajax.options);
    }
    catch (err) {
      alert('An error occurred while attempting to process ' + ajax.options.url);
      return false;
    }

    return false;
  };

  $('div.block div.content div.menu-block-wrapper ul.menu li.leaf a:not(.ajax-processed)').each(function(index, element) {
        var $MyAjaxLink = $(this);       
        // make sure it is a numeric ID
        if( !isNaN(this.id) ) {
          DrupalAjax =  new Drupal.ajax('.My-ajax-link', $MyAjaxLink, { 
            url: $MyAjaxLink.attr('href'),
            settings: {},
            event: 'onload'
            //event: 'click tap'
          });

          $(this).addClass('ajax-processed');   

          // not working yet did loop and throw errors   
          DrupalAjax.specifiedResponse()    
        }
    });           
    }
  }    
})(jQuery); 
4
  • Most examples use the click event or a form GET. In this case it has to present itself totally to the user as the page loads.
    – omcode
    Commented Apr 4, 2013 at 13:57
  • did you check out drupal.org/node/305747 ?
    – au_stan
    Commented Apr 4, 2013 at 14:14
  • yes, thanks Austin, but that also uses the Click event, right?
    – omcode
    Commented Apr 4, 2013 at 14:22
  • just dont bind the click event...
    – au_stan
    Commented Apr 4, 2013 at 14:25

2 Answers 2

1

i've done this a few different ways but there are many ways to handle this. i dont know whe version you are using so i just pulled a d6 implementation. also, $(document.ready()function() {} ); should fire off right when the DOM is ready.

also, have you reviewed ajax in drupal using jQuery ?

one way i've done this is to write my own module that has an external js file. first i need to have a path available for the ajax callback. in mymod_menu() i added something like

$items['some_path/update'] = array(
    'page callback' => 'mymod_json_update',
    'type' => MENU_CALLBACK,
    'access arguments' => array('access content'),
);

i created another function called mymod_json_update which you see in the page_callback option.

function mymod_json_update() {
// do some work and get your data together to be pushed to JSON output
print drupal_json(array('html' => $html));
exit();
}

in my js file, i make the actual ajax call. Note you could also use something like $.getJSON() but $.ajax() works too. up to you

(function ($) {
  $(document).ready(function() {
    var type = Drupal.settings.type;  // some value i've attached to Drupal.settings so i can pass a value back to the mymod_json_update() function in my module. 
    $.ajax({
       type:    "GET",
       url: "some_path/update",
       cache:   false,
       data:    'type='+type,
       success: function(html) {
          var result = Drupal.parseJson(html);
          $('div.content').html(result['html']);
       }
    });
  });
})(jQuery);
8
  • Thank you Austin. I'm using the Drupal behavior approach, it looks like the errors may be coming from un-processed links on the page including url() links in the header. PHP 'code' $items['vms-custom-path/ajax'] = array( 'title' => 'VMS custom ajax callback', 'page callback' => 'vms_ajax_callback', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, );'code'
    – omcode
    Commented Apr 4, 2013 at 13:43
  • also, dont forget to add the js file with drupal_add_js()
    – au_stan
    Commented Apr 4, 2013 at 13:45
  • yeah it's loaded // Load in our custom JavaScript. drupal_add_js(drupal_get_path('module', 'vms_ajax') . '/vms_ajax.js'); I'll paste my full first reply below it was cut off
    – omcode
    Commented Apr 4, 2013 at 13:52
  • sorry, am trying to share the code but it's too long
    – omcode
    Commented Apr 4, 2013 at 13:53
  • yea actually because its D7 i would use the behaviors property because drupal.js already makes the $(document).ready() call.
    – au_stan
    Commented Apr 4, 2013 at 13:54
0

Appears you cannot register an existing page. But you can code in the callbacks with your own path defined in the module menu callback. One thing I did find is no matter what any example may show you, do not use any leading or trailing slashes "/" in either the module hook_menu or in the url used in the javascript ajax call. Thanks again everyone, and austin in particular, your replies were great clues in getting to the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.