form fieldsets cannot be made collapsible with ahah.

Comments

Ocyrhoé’s picture

Status: Active » Closed (fixed)

Thanks to this issue http://drupal.org/node/185755 and http://docs.jquery.com/Tutorials:AJAX_and_Events I've found the solution by rebinding javascript behaviors after ahah refresh.

jefkin’s picture

Title: keep fieldsets collapsible » keep fieldsets collapsible for Drupal 6 too

I realize this is a very old topic, but I wanted to mention the meat that I think Ocyrhoé meant when he said:

I've found the solution by rebinding javascript behaviors after ahah refresh.

At least as it applies to me, using Drupal 6. Following his bread trail, lead me inexorably to the Drupal core. In the file "misc/drupal.js" I found a telling comment:

============================================================
...
22 * Drupal.attachBehaviors is added below to the jQuery ready event and so
23 * runs on initial page load. Developers implementing AHAH/AJAX in their
24 * solutions should also call this function after new page content has been
25 * loaded, feeding in an element to be processed, in order to attach all
26 * behaviors to the new content.
...
============================================================
(my bolding)

What I gleaned from this was that my AHAH php callback function can do something like this:

function mymodule_ahah_callback()
{
  $lineid = (int) $_POST['lineid'];

  $collapsible_fieldset = drupal_get_form('mymodule_some_form', $lineid);

  $maybe_some_other_content = "<h1>hello there!</h1>";

  $output = <<<___AHAH_Response

<div id="ahah-output-$lineid">
  $collapsible_fieldset
  $maybe_some_other_content
</div>
<script>
Drupal.attachBehaviors('#ahah-output-$lineid');
</script>

___AHAH_Response;

  // Write and send output to js
  print drupal_to_js( array ( 'status'=>true
                          ,   'data'  =>$output
                          , ));
  exit;
}

The important parts, for me, were first of all, to call Drupal.attachBehaviors(), which sort of "restarts" the Drupal Behaviors that were run at page initialization, including, for instance, the collapse behavior.

Secondly, I put a wrapping <div> or other element around my generated content, and use that "id" as an argument to the Drupal.attachBehaviors.

This code pretty much works like a charm for me in a module I just built.

Though, to be honest, one part still bothers me. The js code in drupal.js isn't quite clear what is meant by the "context", so it is possible that we should have:

<script>
Drupal.attachBehaviors($('#ahah-output-$lineid'));
</script>

Passing the string '#ahah-output-$lineid' seems to be working, but it could be that Drupal.attachBehaviors() is simply reprocessing the whole document. I would love to find out if I'm making the call correctly/efficiently, or if I need to invoke the jQuery $().

But everything is working for now, so thanks to Ocyrhoé!

And thanks also to which ever semi-anonymous Drupal dev put that comment in drupal.js!