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?

2
  • 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. Commented Jun 27, 2011 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
    Commented Jun 27, 2011 at 5:39

5 Answers 5

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.

1
  • 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
    Commented Jun 30, 2011 at 4:34
5

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');
  ?>
1
  • The ajax_base_page_theme tip helped me out on a Backdrop CMS site today. Thx!
    – Laryn
    Commented Nov 7 at 16:16
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.

1
  • I've made exactly the same mistake :)
    – sobi3ch
    Commented Feb 9, 2015 at 21:21
2

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;
}
1

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));
}

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.