Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I've got a form which has a textfield and a submit button. When the user clicks on the submit button, a list of search results are displayed in a fieldset. Each result item is displayed as a nested fieldset (search results contains additional data which needs to be expanded/collapsed). However, the collapsible behaviour for fieldsets seems to break whenever the fieldsets are served through AJAX.
This bug (if that is what it is) is consistent on all major browsers that i've tried (MSIE, Chrome and Mozilla).
Comments
Comment #1
rfayDuplicate of #561858: [Tests added] Fix drupal_add_js() and drupal_add_css() to work for AJAX requests too by adding lazy-load to AJAX framework, I'm pretty sure.
Comment #2
nerdacus CreditAttribution: nerdacus commentedOk, I just spent good amount of company time figuring this one out as well... it is not a duplicate post...
My problem was in creating the form array from scratch (essentially) in the callback function and returning it. Even if you added the array properly to the $form variable that was passed into the callback function, this will not work. This creates issues with rendering the array.
My solution was to set up my original form function to expect the new arrays. That is, specifically, I created a counter in $form_state that initializes if it is not set, but increments otherwise. My form function, then, builds the new arrays based on the counter. And in the callback function the only task is tell what array branch I care about (the new array).
Since the original form function is used in the AJAX rebuild everything will be processed properly, the new form array will have the correct HTML classes & IDs, which is the problem with fieldsets.
So in a summed up conclusion:
Build your form function to expect changes to a specified variable in $form_state and use that variable in the callback function to target what you want specifically.
-Marcus
Comment #3
BenjamiB CreditAttribution: BenjamiB commentedMarcus, I tried you solution but I'm sure I didn't quite get how you solved this since I change my structure 2 time (tried to rebuild entirely the form) tried to modify many options of form_state but still can't get it to work.
Could you be more specific or give an example on how you solved this please.
Thanks in advanced
Comment #4
BenjamiB CreditAttribution: BenjamiB commentedI found it!!
so drupal is rebuilding the form using hook_form in the ajax callback function so all you have to do is to use $form_state['rebuild'] which is set to False when you build it for the first time and true for every ajax calls as the form already exists...
In my case I have the fieldset collapsed by default but on an ajax callback, the fieldset will stay open
$form['filters'] = array(
'#type' => 'fieldset',
'#title' => t('Filters'),
'#collapsible' => TRUE,
'#collapsed' => !$form_state['rebuild'],
'#wrapper_id' => 'filters-wrapper',
'#prefix' => '
'#suffix' => '
',
);
I change the status to support request as in my opinion this is a feature and not a bug. It would be nice to document it somewhere thought ...
Comment #5
Azolia CreditAttribution: Azolia commentedHi,
I've faced the same problem and have found a solution :
Make sure the script '/misc/collapse.js' is included in html head.
If not, use drupal_add_js('misc/collapse.js').
In the JS script code which make ajax call to generate retrieve the html form code, insert, after the html code has been inserted in the DOM, Drupal.behaviors.collapse(jquery_elt).
jquery_elt is the jQuery object corresponding to the form code which has been inserted.
Comment #6
Kvitz CreditAttribution: Kvitz commentedI'm also facing this issue.