1

I have a few pages with sub pages as tabs. Each pages are in a custom menu. I'd like to convert the menu links to load each page using AJAX, is this possible?

I know how to load a page using a regular AJAX link, but not a menu, or menu tab link. One way is to replicate the menu links using AJAX and binding the events to the corresponding menu links, which works, but there must be a better way?

3 Answers 3

1

Assuming I understand your question correctly, it is possible. This is how I would do it (not sure how much this differs from the way you mentioned). Obviously you would need to change your page callback function, which you set for the tab in hook_menu(), to return a json object rather than a rendered page.

At the end of your page callback function you should add something like this:

// Return the rendered view in a JSON object. The object will contain a property 
// named “contacts”, which containes the rendered view.  This will be sent to the 
// browser and is accessable to javascript.
return drupal_json_output(array('contacts' => $view));
exit;

You would then need to include some javascript on the client-side to send an ajax request to the server using the URI/path you set for the tab in hook_menu. This same client-side javascript would then process the returned data.

  currentMenuLink.click(function() {
      var updateContacts = function(data) {
        // The data parameter is a JSON object. Do something with the returned data here. 
      };

      // Send ajax request.
      $.ajax({
        type: 'POST',
        url: this.href, // Which url should be handle the ajax request. This is the url defined in the <a> html tag
        error: function() {
          $('#namecards-get-contacts-by-nid-row-' + currentNid).show();
          $('#namecards-get-contacts-by-nid-cell-' + currentNid).html($('<div class="">An error has occurred while retrieving the list of contacts.  Please try again.  If the problem persists, please inform your website administrator.</div>'));
        },
        success: updateContacts, // The js function that will be called upon success request
        dataType: 'json', //define the type of data that is going to get back from the server
        data: 'js=1' //Pass a key/value pair
      });
      // return false so the navigation stops here and not continue to the page in the link.
      return false; 
    }
  });
3
  • Thanks for the reply. I need to do this through the Drupal AJAX framework because I need to insert Drupal Forms, so would need all the behaviours, settings etc attached. Commented Jul 26, 2012 at 11:28
  • By Drupal AJAX framework, do you mean the AJAX component of Drupal Forms? Might be helpful if you describe a little more about what you want to do. Are you trying to load a form via AJAX? If that is the case you could always reattach any form related javascript behaviours at the end of your AJAX success callback.
    – Benjen
    Commented Jul 26, 2012 at 12:17
  • Sorry, I realise my question didn't really provide much information. I think I got it working now though, thanks for your help. Commented Jul 26, 2012 at 12:18
1

I managed to get this working by manually adding AJAX to each menu item:

(function ($) {

Drupal.behaviors.test = {
  attach: function(context, settings) {
    $('#sidebar-first ul.menu a').addClass('use-ajax').addClass('ajax-processed').each(function () {
      var element_settings = {};
      element_settings.progress = { 'type': 'throbber' };
      if ($(this).attr('href')) {
        element_settings.url = $(this).attr('href');
        element_settings.event = 'click';
      }
      var base = $(this).attr('id');
      Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
    });
  }
};

Each of the menu items then checks to see if AJAX was used, if so it delivers the page using ajax_render(). })(jQuery);

1
  • i am also stuck with same issue could you please help me in this this code is not working for me Commented Aug 18, 2016 at 12:01
-1

I use hook_menu_alter() for this:

function THEMENAME_menu_link(array $variables) {

  //mlid - menu link ID. I want AJAX only some menu link
  if ($variables['element']['#original_link']['mlid'] == 1177) {
    drupal_add_library('system', 'drupal.ajax');
    $element = $variables['element'];
    $output = l('YOUR_LINK', $element['#href'].'/nojs', array('attributes' => array('class' => array('use-ajax'))));
    return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . "</li>\n";
  }

  // render other items dy default way
  return theme_menu_link($variables);
}

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.