Hi,

Problem/Motivation

Faced with issue that when add conditional fields dependency to hide/show fields inside the group, group is always visible.

Would be great to have a feature that hide group when all fields inside of it are hidden.

Steps to reproduce

  1. Create a content type that contains the text fields field_test_trigger, field_hidden_by_trigger
  2. Add a field group to the form and move field_hidden_by_trigger to be a group child
  3. Add a hook_form_FORM_ID_alter to apply javascript states to hide field_hidden_by_trigger when field_test_trigger is not empty (see example code below)
  4. Go to the form and enter a value into field_test_trigger
  5. The field group is still visible even though field_hidden_by_trigger is now hidden. The field group should also be hidden unless the Display element also when empty setting is enabled.
  /**
  * Implements hook_form_FORM_ID_alter().
  */
  function my_module_form_node_test_content_form_alter(&$form, FormStateInterface $form_state): void {
    $form['field_hidden_by_trigger']['#states'] = [
      'visible' => [
        ':input[name="field_test_trigger[0][value]"]' => ['value' => ''],
      ],
    ];
  }

Proposed resolution

  1. Add a field_group.js Javascript state:visible event listener
  2. This listener will call a new Drupal.FieldGroup.setParentFieldGroupVisibility method and pass in the element from the state:visible event (i.e. the element being hidden or shown)
  3. Drupal.FieldGroup.setParentFieldGroupVisibility will check if the element is a field group child and if it is, find the element's parent field group and pass that into a new Drupal.FieldGroup.setFieldGroupVisibility method. It will also call itself passing in the group, to handle the hiding/showing of nested groups.
  4. Drupal.FieldGroup.setFieldGroupVisibility will check if the current field group is empty by calling a new Drupal.FieldGroup.isGroupEmpty method. Depending on if the group is empty or not, a new field_group:group_empty or field_group:group_not_empty event will be triggered.
  5. field_group:group_empty and field_group:group_not_empty event listeners are added to specific group type js files to handle hiding and showing the group element/s
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

MariaDenysyuk created an issue. See original summary.

mariiadeny’s picture

StatusFileSize
new2.5 KB
mariiadeny’s picture

Status: Active » Needs review
mariiadeny’s picture

StatusFileSize
new2.34 KB

Fix naming

Status: Needs review » Needs work

The last submitted patch, 4: hide-show-field-group-2978747-4.patch, failed testing. View results

andypost’s picture

+++ b/field_group/src/FieldGroupFormatterBase.php
@@ -154,6 +154,7 @@ public static function defaultContextSettings($context) {
     $classes = array();
+    $classes[] = 'field-group';

any reason to duplicate?

savkaviktor16@gmail.com’s picture

Status: Needs work » Needs review
StatusFileSize
new2.23 KB

Re-rolled

tessa bakker’s picture

Status: Needs review » Needs work

Doesn't work with horizontal tabs, all tabs are hidden.

Tested with the latest dev version (072bf212d8e13aa242a4e274e5a4837a0e0ffc5e)

piggito’s picture

Status: Needs work » Needs review
StatusFileSize
new2.05 KB
new1.39 KB

Fixed the issue about all tabs hiding + I also noticed that on Accordion Items the Field Group title wasn't hiding. Including both changes in the attached patch.

publishing future’s picture

I applied the patch in #9 to Field Group 8.x-3.x-dev (i.e. 8.x-3.0-beta1+21-dev) but nevertheless groups that only include fields which are hidden by conditional fields dependency are still visible. The field groups are of type "Details".

publishing future’s picture

Patch in #9 seems to work onlywith field groups of type html. However, if I set the _first_ field group to "html", the following field groups with hidden fields of type "details" are hidden as well.

publishing future’s picture

Whereas the patch #9 solves the problem for fields hidden by "conditional fields" module, the problem still persists for fields hidden by "field states ui" module.

andypost’s picture

Yep, it needs own classes which both modules could use

w01f’s picture

Thanks for everyone's time with this!

I applied the patch and it works great for initial page load, but if I apply the correct condition for the fields to become visible, and then undo the condition (in my case unchecking a boolean field) - the fields once again disappear but the empty fieldset group is still shown.

andypost’s picture

larowlan’s picture

Status: Needs review » Postponed (maintainer needs more info)
Issue tags: +australia-nz-friday-triage
inversed’s picture

I believe this is still occurring, specifically, for Tabs (as mentioned in the referenced issue in #16). That's the behavior that I've experienced. When Conditional Fields makes a field "invisible" and that field is the only field in a tab, that tab will still be shown.

If a Tab has no fields in it (i.e. removed using the form display manager), then the tab will not be shown. That is the bug that was fixed successfully in Issue #2986455.

liquidcms’s picture

Category: Feature request » Bug report
Priority: Minor » Normal
Status: Postponed (maintainer needs more info) » Needs work

even without Conditional Fields, with the patch in #9 as well as the patch from #2986455: Empty fieldgroups are showing in forms, i still get empty sidebar details tab showing: https://www.screencast.com/t/JR4Tyo8W

liquidcms’s picture

I changed FG type to simple fieldset instead of details sidebar.. and this still doesn't work. https://www.screencast.com/t/eg5UXCqAp

vinothkannan’s picture

Any luck on Drupal 8.8.4?

miedward’s picture

StatusFileSize
new2.38 KB

Updated patch in #9 to work with Drupal 8.8.6 and a refactor of some code into FormatterHelper.php

miedward’s picture

Status: Needs work » Needs review

Probably doesn't fix the use case the #9 patch didn't but fixes the issues I have on my site.

rp7’s picture

StatusFileSize
new1.42 KB

I can't seem to apply the patch in #21.

I'm having this issue on a multilingual site. I have a content type of which some fields are not translatable. These fields are only visible on the original translation (this is how Drupal core works). For my use case, these untranslatable fields all happen to be in the same field group. When translating a node of this particular content type, the field group still renders although it being empty.

The function responsible for setting the form elements #access key for untranslatable fields to FALSE is located at ContentTranslationHandler::entityFormSharedElements() provided by content_translation module. This is run via a #process callback.

The function responsible for tracking down and removing empty fields group is called field_group_remove_empty_form_groups(). This is also run via a #process callback.

The issue is that the field_group #process callback runs before the content_translation #process callback.

The patches proposed earlier are trying to hide empty field groups through JavaScript. Taking the above into account, I believe running field_group_remove_empty_form_groups() as late as possible (eg. in an #after_build callback) gives you the best chance of having empty field groups correctly being removed. The patch attached implements this.

I can confirm that this fixes the content_translation issue.

As for the Conditional Field module: I'm not using it, so I can't validate if this patch also fixes that issue. If not: the issue is probably of the same nature (Conditional Field doing its thing after field_group_remove_empty_form_groups() has already run).

spadxiii’s picture

Status: Needs review » Needs work

The patch in #23 works good, but not perfect. I think it's also way better than hiding using javascript.

The process method is replaced by an after-build: field_group_form_process_after_build . The doc-block needs a little more update: an after-build has a return-value :)

What does not work is nested groups that are empty: these still force the parent group to be visible, because their access is never set to false. I think this is because the after-build is only run once for the whole form. Perhaps this after-build needs to be recursive? (and do a depth-first check: the deepest child first, then bubble back up).

prudloff’s picture

StatusFileSize
new500 bytes
new3 KB

#23 does not work for our use case, because we are using states to hide the field, so it has to be in JS.

#21 does not work for nested field groups, because they don't have the field-group class (it is overridden by field-group-child-field). The attached patch fixes that.

tim-diels’s picture

Status: Needs work » Needs review
StatusFileSize
new3.12 KB
new1.01 KB
  1. +++ b/field_group.libraries.yml
    @@ -26,7 +26,7 @@ formatter.accordion:
    +    - jquery_ui_accordion/accordion
    

    Does not apply anymore.

  2. +++ b/src/Plugin/field_group/FieldGroupFormatter/Fieldset.php
    @@ -43,7 +43,7 @@ class Fieldset extends FieldGroupFormatterBase {
    +      $element['#attributes']['class'] = array_merge($element['#attributes']['class'], $classes);
    

    We should keep the original thinking method here. As you can see, they add the class array. Default there are is no class array. So checking would be better and then merge or add.

james.williams’s picture

Title: Hide group if all fields are hidden » Hide group if all fields are hidden by javascript

#25 makes a good point that groups may be hidden in javascript, which would require a javascript-only solution.

For the server-side solution, to solve groups hidden on the server-side (most commonly by content translation), #3069365: Emptiness check in field_group_remove_empty_form_groups() does not account for empty containers contains something that looks good to me.

I suggest this issue focuses on hiding groups when they are hidden by javascript, if that's needed.

james.williams’s picture

Sorry, I'd misinterpreted that other issue, although it is indeed a server-side change. #3127179: Empty group due to hiding fields on translation form are not hided now has a patch for the server-side issue, and matches #23's report of content_translation causing the issue.

dunebl’s picture

I think that #25/#26 are targeting only accordions.
I tested it without luck on a details group rendered by the default olivero theme.

Here is the rendered html of my "not hided" group

<details class="field-group required-fields field-group-details js-form-wrapper form-wrapper olivero-details accordion-item" data-drupal-selector="edit-group-cc" id="edit-group-cc">
    <summary role="button" aria-controls="edit-group-cc" aria-expanded="false" aria-pressed="false" class="olivero-details__summary">My Title<span class="summary"></span>
    </summary>
    <div class="olivero-details__wrapper details-wrapper">
        <div class="field-group-child-field js-form-wrapper form-wrapper" data-drupal-selector="edit-field-my-field" id="edit-field-my-field">
        </div>
    </div>
</details>

As you can see, there isn't any .accordion-item class

Note: The field (in the group) has been hidden by setting the '#access' key to FALSE in the regular form_alter

heikkiy’s picture

Tested the patch with 3.2 and it doesn't seem to work with tabs.

I have one field group marked as a tab and adding the condition to it, hides the fields inside it but it doesn't hide the actual tab.

I checked that there is no change in the HTML code.

Looking at the patch, it seems like its only triggering for elements with the class .accordion-item where as the tabs have the following HTML structure:
<li class="horizontal-tab-button horizontal-tab-button-1 last selected" tabindex="-1" data-horizontaltabbutton="1"><a href="#edit-group-researcher-profile"><strong>Researcher profile</strong><span class="summary"></span><span id="active-horizontal-tab" class="visually-hidden">(active tab)</span></a></li>

dtamajon’s picture

I confirm the patch is not working with horizontal neither vertical tabs.

This is the JS version for tabs working, but we should find the way to work with all group elements.

      $(document).ready(function () {
        $(context).find('.field-group .js-vertical-tabs-menu-item').each(function(index) {
          hideGroupIfEmpty($(this), index);
        });
      });

      $(document).bind('state:visible', function(e) {
        $(context).find('.field-group .js-vertical-tabs-menu-item').each(function(index) {
          hideGroupIfEmpty($(this), index);
        });
      });

      // Check group's child fields state and hide/show group.
      function hideGroupIfEmpty(group, index) {
        var group_empty = true;
        $(context).find('.field-group details.field-group-child-field').each(function (i, el) {
          if (index == i) {
            if ($(el).css('display') !== 'none') {
              group.show();
            }
            else {
              group.hide();
            }
          }
        });
      }
kay_v’s picture

Status: Needs review » Needs work

housekeeping....

I'm changing status to 'needs work' based on comments posted over the course of the last year; I'm guessing it was meant to be changed earlier

tame4tex’s picture

StatusFileSize
new13.08 KB
new12.74 KB

My attempt to get it working for all field group formatters, inspired by previous patches.

I went a slightly different route and provided a field group js function to hide a field group and its tab (if applicable). Then each formatter is required to call the function during its process or attach function and provide the function parameters as needed. The formatter is also required to bind to the `states:visible` event.

Preliminary manual testing has been done on tabs, accordion items, fieldsets and details.

This really needs tests written, which is beyond my current scope.

tame4tex’s picture

Status: Needs work » Needs review
tim-diels’s picture

StatusFileSize
new14.14 KB
new1.93 KB

Thanks for the work, this did the trick for me and looks good. I added this also to the HTML element.

tim-diels’s picture

StatusFileSize
new14.14 KB
new1.93 KB

Apologies for the error in code. Fixed in new patch.

JoshHytr made their first commit to this issue’s fork.

joshhytr’s picture

StatusFileSize
new14.17 KB
new3.26 KB

Re-rolled patch 36 for module tag 8.x-3.4 and added semi-colons at the end of let variable declarations.

I am providing an updated patch and have also pushed to the issue fork.

Status: Needs review » Needs work

The last submitted patch, 38: field_group-2978747-38.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

sokru’s picture

Status: Needs work » Needs review
StatusFileSize
new14.7 KB
new3.76 KB

This should resolve the Drupal 10 issues.

dunebl’s picture

This patch is nice and working well except if we are adding fields in an empty group in the hook form_alter.
I am using the following function to add $form[$field_name] to a group (id=$group_name):

function addToGroup(array &$form, string $field_name, string $group_name)
{
  /** @var EntityFormDisplay $form_display */
  $form_display = $form['#process'][1][0];
  $form[$field_name]['#group'] = $group_name;
  $field_group = $form_display->getThirdPartySettings('field_group')[$group_name];
  $field_group['children'][] = $field_name;
  $form_display->setThirdPartySetting('field_group', $group_name, $field_group);
  }
}

If I add $form['field_to_add'] in a group which is empty but which have the option "Display element also when empty" checked; then the group is not displayed.

To summarize, there are 2 issues:
1-The patch doesn't take into account the option Display element also when empty
2-The patch doesn't take into account any element added to the group in the form_alter hook

prudloff’s picture

The patch works correcly on initial load, but it does not seems to work correctly when detecting a change.
We have a fieldset containing 3 fields that can be shown/hidden depending on when another checkbox field is checked (we use conditional_fields for this).
The field group is initially hidden but if I make the fields visible then hide them, the field group is not hidden and is displayed empty.

This seems to happen because when Drupal.FieldGroup.hideGroupIfEmpty() evaluate the display property of the fields, the last does not have none yet. So it might be some kind of race condition that makes it check the field too soon.
If I do something like this, then it works correctly:

diff --git a/formatters/fieldset/fieldset.js b/formatters/fieldset/fieldset.js
index 7349be4..3a2f052 100644
--- a/formatters/fieldset/fieldset.js
+++ b/formatters/fieldset/fieldset.js
@@ -34,7 +34,9 @@
         if ($(e.target).hasClass('field-group-child-field')) {
           let $group = $(e.target).closest('.field-group-fieldset');
           if ($group.length !== 0) {
-            Drupal.FieldGroup.hideGroupIfEmpty($group, null, true);
+            setTimeout(function () {
+              Drupal.FieldGroup.hideGroupIfEmpty($group, null, true);
+            }, 500);
           }
         }
       });

(This is obviously not the way to the fix the problem, but it helps demonstrate it.)

vensires’s picture

Issue tags: +GreeceSpringSprint2024
mιχaliς’s picture

Status: Needs review » Needs work

Patch failed on field_group 3.6 and Drupal 10.3

karen-kramek’s picture

StatusFileSize
new13.34 KB

Hello everyone,
Re-holl of patch field_group-2978747-40.patch (8.x-3.0), now covering the module version 8.x-3.6.

a.milkovsky’s picture

Status: Needs work » Needs review
pakmanlh’s picture

Status: Needs review » Needs work

Unfortunately I can confirm the behavior described by #42 working only initially.

vensires’s picture

tgauges’s picture

Would MutationObserver be an acceptable solution for #42? One would need to observe subtree, childList, and attributes.

I will create a new branch in the issue fork based on 2978747-hide-group-if.

tgauges’s picture

You can take a look at https://git.drupalcode.org/issue/field_group-2978747/-/tree/2978747-hide-group-with-mutation-observer for my solution for #42.

There don't seem to be any tests implemented for this issue?

tame4tex’s picture

Version: 8.x-3.x-dev » 4.x-dev

Updating to new major version.

tame4tex changed the visibility of the branch 8.x-3.x to hidden.

tame4tex changed the visibility of the branch 4.x to hidden.

tame4tex’s picture

Issue summary: View changes
Status: Needs work » Needs review

Not only is there an issue with the code only working initially, I also experienced issues with it not working with nested groups. To fix these issues I implemented a different approach.

We need to ensure that when the state:visible event is fired we not only set the visibility of the closest field group but we continue up the DOM to set the visibility of parent field groups. This is easier to handle with one state:visible event listener in the field_group.js than one for each field group type.

Because each field group type might need to do different things when its children are all hidden vs when a child is visible, once we have determined the current visibility of the field group children we need to hand off what is done to the field group to the js file for the different types.

I have updated the Issue Summary with my proposed resolution. Given the significant changes to the previous version and the merge conflict issues in updating the old solution branches, I have added a new 2978747-hide-group-4.x and opened a MR.

I have also added preliminary testing for this bug.

@tgauges: Interesting concept with the MutationObserver, although I am wondering if it is more than what is needed in this instance? Given the new approach, what does it do better?

pakmanlh’s picture

Status: Needs review » Reviewed & tested by the community

I can confirm the last / new approach from 2978747-hide-group-4.x works fine. thank you!

tgauges’s picture

@tame4tex MutationObserver is a catch-all solution which also can work if the DOM is mutated by something other than the Drupal Form API #states property.

In my opinion you are correct: It is probably more than what is needed. I think it's enough to react to changes caused by the #states property.

tame4tex’s picture

Status: Reviewed & tested by the community » Needs review

I have pushed a couple of fixes to the MR due to issues encountered.

`Display element also when empty` setting was not being respected. I have now added a test for this and fixed the bug by adding a css class
if this setting is enabled and then checking for that class in the logic.

I also encountered a weird bug in Safari 18.x where it was ignoring the style attribute on the element being hidden/shown by states and instead determining the display value to be "none" when it was actually "block". I have adjusted the code to specifically check the style attribute on the element first and only get the computed style if the style attribute display value is empty.

I have switched the status back to Needs Review due to these changes.

imclean’s picture

Should this work with forms loaded via ajax? I've applied the patch to the 4.0.x branch but it hasn't made any difference.

In my case, the target fieldset and controlling fields are within a paragraph type. When adding a new paragraph the fields are correctly shown or hidden while the fieldset wrapper is always visible.

imclean’s picture

Ignore the above, I'm having patching issues.

pcambra made their first commit to this issue’s fork.

pcambra’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new50.41 KB

Adding a patch file with the rebase above for 4.0.0

carma03’s picture

StatusFileSize
new17.88 KB

Confirming patch on #62 comment worked good. Tested on D11.2.8 and PHP 8.3.

Bear in mind that the option Display element also when empty should be disabled into the Group Tab for get it to work properly:

Field Group option

Thanks!

er.garg.karan’s picture

Status: Reviewed & tested by the community » Needs work

I am using Drupal 11.2.10 and field group 4.0.0.

I have a field group inside a paragraph. There are a few fields under that field group and I am using #states to show/hide those fields on the change of value of another select field.

When a value in the select field hides these fields, it works fine and the field group also hides as there is no other field to show in the field group. But as soon I make a selection in the select field that has to show the fields under the field group, the fields show but there is no field group as it never existed.