Loading additional CSS and JS with AJAX/AHAH requests

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
nedjo's picture

An issue when loading and rendering content via AHAH is that the content may rely on CSS or JS code not present on the original page. In this case, there is a need to load and execute the additional code (CSS and JS files, inline scripts, Drupal.settings data).

There are now two API modules to provide this functionality.

The first is Ajax load. Ajax load introduces a drupal_alter() hook. By passing response data through a drupal_alter('ajax_data') call before returning it, module authors can allow other modules to add to or alter the data being returned. Ajax load implements this hook, providing CSS and JS loading and handling.

The second is a set of five modules. Like Ajax load, Ahah response enables the altering of AHAH response data. Rather than passing the response data through a drupal_alter() call, modules implementing ahah_response must replace drupal_json() with a custom theme function. Ahah style ensurer and Ahah script ensurer load and handle CSS and JS data while Ahah page storage and jQuery OAP are additional dependencies.

CSS and JS loading and handling has also been introduced independently in at least two other modules: Popups and Asynchronous. these implementations meet the needs of these modules but aren't exposed for other modules to use.

Like AHAH form validation and submission, the proliferation of contrib implementations of AJAX/AHAH JS and CSS loading suggests two needs:

  1. Standardization on a common API to be jointly developed and maintained.
  2. Consideration of introducing additional JS and CSS loading to Drupal core.

This post is an invitation to discussion of these topics.

Is there interest in working up a core patch introducing additional CSS and JS loading? If so, what are our best starting places? What is our best approach for D6?

Comments

There are some hairy edge

starbow's picture

There are some hairy edge cases to a general solution. Like ahah loading a reorderable table into a page that already has one.
The solution in popups has it easy, because we ignore the background page and then restore it, rather than embedding the new ahah fragment.

I'm a huge supporter of

skilip's picture

I'm a huge supporter of loading scripts dynamically using jQuery's $.getScript. This is not possible with CSS, but I assume we could create similar functionality in a Drupal behavior which allows loading both CSS and Javascript files dynamically. Loading the scripts / styles would be very cool by setting drupal_add_js' / drupal_add_css' parameter to 'ajax'. eg: drupal_add_js('path/scripts.js', 'ajax');

Another approach would be letting drupal_add_js / .._css, print out the whole script / style contents when type is 'ajax'. You'll get ugly source code, while everything is put inline. But this is by most the easiest way to load the styles / scripts alongside with AJAX loaded content.

Regarding Drupal.settings

quicksketch's picture

As starbow and I found with Popups, you need not only CSS/JS files but also the Drupal.settings from the AJAX request to make all the loaded content operate properly (say you load a tableDrag table via AHAH, it needs not only tabledrag.js but also the contents of Drupal.settings.tableDrag).

The solution to this particular problem (the one that starbow mentioned above) is really quite simple. We simply pass in the "settings" variable to behaviors in addition to context. This makes it so we can get the settings from the called page (like Popups already does), then when we attach the behaviors we simply pass in the settings array we received in the returned JS.

I've already submitted a patch to fix this: http://drupal.org/node/251578

The method that we use for actually obtaining that JS and attach it to the page is still up for consideration, but once that problem is solved we'll have a way to actually make those JS behaviors work.

Hello quicksketch, i think

dennis605's picture

Hello quicksketch,

i think your patch is only applied in drupal 7.x, am i right.

Could you tell me, how to do this in drupal 6.x?

Thanx

dennis605