4

For some crazy reason, using ajax_deliver() in a menu callback is causing 4 theme CSS files to be loaded into my page, breaking the page styles.

What I'm doing:

  • Using Seven as my admin theme
  • Created a basic admin page for a module
  • Admin page has a link (no form) which should return content via AJAX
  • Link points to a menu path which uses a custom callback
  • Custom callback uses the /nojs trick and returns content via ajax_deliver()

What's happening:

  • AJAX content is loading into the page just fine, working as expected
  • 4 Bartik CSS files are being dynamically added to my admin page (using Seven theme)

Anyone experienced this? Any ideas on how I can prevent this CSS from loading?

  • Please file a bug report on drupal.org, with steps to reproduce with the custom code you're using and screenshots. Drupal Answers is not the place to solve an actual bug. – tim.plunkett Jun 27 '11 at 3:50
  • Sure, I'll file an issue. However, adding CSS is a 'feature' of ajax_deliver(). I never, ever want CSS to be loaded this way, so I'm asking how it can be suppressed. – wynz Jun 27 '11 at 5:39
3

Just to answer your question of how to do this.

ajax_render() calls drupal_alter('css') which would allow you to create a hook_css_alter() in your code.

This could check the delivery method (or check for ajax in the path) and remove style sheets if you wanted to.

Most of the time you won't want to do this as they will be needed for the returned markup but it is possible that you would want to tweak it.

| improve this answer | |
  • Ah, nice suggestion. I get the part about checking the request path for 'ajax', but how can I check the delivery method from within the alter function? – wynz Jun 30 '11 at 4:34
4

Figured out the reason Bartik CSS was loading when the admin page was using Seven.

My admin page was located at /admin/mymodule/settings

My menu callback for the AJAX link was /mymodule/special-form

Because /mymodule is outside the admin area, the theme would be Bartik when actually visiting that page. So Drupal's AJAX system assumes I want the CSS that goes along with that page. Not a bug, but a feature to be aware of.

| improve this answer | |
  • I've made exactly the same mistake :) – sobi3ch Feb 9 '15 at 21:21
4

The correct drupal way is to use ajax_base_page_theme in hook_menu theme callback. as explained in http://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_base_page_theme/7

or you can force ajax to use admin theme by altering its Drupal.settings.ajaxPageState

something like :

  <?php
  // Force ajax to use admin theme
  $admin_theme = variable_get('admin_theme', '0');
  $settings = array(
    'ajaxPageState' => array(
        'theme' => $admin_theme,
      'theme_token' => drupal_get_token($admin_theme),
    ),
  );
  drupal_add_js($settings, 'setting');
  ?>
| improve this answer | |
1

A very handy work around that I used for this was to implement hook_admin_paths() to define the ajax path as an admin path. For example, I had an issue where hierarchical_select on admin pages (i.e node edit) was loading the entire front end theme's css into the page causing all sorts of issues. The fix was simply this:

/**
 * Implements hook_admin_paths().
 */
function my_module_admin_paths() {
  $paths = array(
    'hierarchical_select_ajax/*' => TRUE,
  );
  return $paths;
}
| improve this answer | |
0

Following Jason's recommendation I came to use ajax_base_page_theme() I came to this simplified solution as mentioned on https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_base_page_theme/7.x

All code is written into custom.module

/**
 * Implements hook_menu().
 *
 * Provide an AJAX menu callback.
 */
function custom_menu() {

  $items['custom/ajax/%'] = array(
    'page callback' => 'custom_ajax_response',
    'page arguments' => array(2),
    'type' => MENU_CALLBACK,
    // Use the current page's theme instead of always the admin theme:
    'theme callback' => 'ajax_base_page_theme',
  );

  return $items;
}

/** 
 * AJAX response callback. 
 * 
 * Writes "foo replacement" into <div id="ajax-placeholder"></div>
 */ 
function custom_ajax_response($argument) {
  $output = 'foo replacement';
  $dom_id = '#ajax-placeholder';
  $commands = array('effect' => 'slide', ajax_command_replace($dom_id, $output));
  return ajax_deliver(array('#type' => 'ajax', '#commands' => $commands));
}
| improve this answer | |

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.