I found a rather odd bug while using field groups with a custom entity type I created. They work great in the entity form, but they don't work at all in the entity view. To be more specific: field groups don't display at all. The same goes for any fields within them. If I move a field out of a field group, it shows up.

I dug in a little and realized that all of my fieldsets had '#access' => FALSE, which caused them to be hidden. I traced it to the function field_group_remove_empty_form_groups(), which looks like this:

<?php

/**
 * Remove empty groups on forms.
 *
 * @param String $parent_name
 *   The name of the element.
 * @param array $element
 *   The element to check the empty state.
 * @param array $groups
 *   Array of group objects.
 */
function field_group_remove_empty_form_groups($name, & $element, $groups, &$form_groups, $entity) {

  $exceptions = array('user__account', 'comment__author');

  $children = element_children($element);

  $hasChildren = FALSE;
  if (count($children)) {
    foreach ($children as $childname) {
      if (in_array($childname, $groups)) {
        field_group_remove_empty_form_groups($childname, $element[$childname], $groups, $form_groups, $entity);
      }
      $exception = $entity . '__' . $childname;
      $hasChildren = $hasChildren ? TRUE : (isset($element[$childname]['#type']) || in_array($exception, $exceptions));
    }
  }

  if (!$hasChildren) {

    // Remove empty elements from the #groups.
    if (empty($element) && isset($form_groups[$name]) && !is_array($form_groups[$name])) {
      foreach ($form_groups as $group_name => $group) {
        if (isset($group->children)) {
          $group_children = array_flip($group->children);
          if (isset($group_children[$name])) {
            unset($form_groups[$group_name]->children[$group_children[$name]]);
          }
        }
      }
    }

    $element['#access'] = FALSE;

  }

}

?>

It seems that for some reason, my fields (mostly integer and float fields) don't have a ['#type'] set... so they are making $hasChildren = FALSE in the line that reads:

<?php
$hasChildren = $hasChildren ? TRUE : (isset($element[$childname]['#type']) || in_array($exception, $exceptions));
?>

I'm not very familiar with the Field API and whether or not that ['#type'] value should always be set. Is this somehow an issue with my fields? Or does the Field Group module need a different way of checking for children?

It seems odd that this issue hasn't come up before (maybe it has), which makes me wonder if it's a problem on my end.

Comments

m.stenta’s picture

Status: Active » Closed (works as designed)

I figured this out. It isn't an issue with Field Group. My custom entity view function wasn't adding the 'view_mode' to the build array, which was causing the field_group_field_group_build_pre_render_alter() function to think that it was displaying an entity form, not an entity view.

Closing this issue!

n8j1s’s picture

Thanks man. I was running into the exact same problem. I appreciate you posting the solution.

geek-merlin’s picture

Title: Field groups always hidden in display » Nonempty field group not displayed
Priority: Normal » Major
Status: Closed (works as designed) » Active

I do consider this a bug: It is totally legal to omit #type in form api.
Nonetheless field group uses this to check for emptyness. This is plain wrong.
Raising prio to major as it wasted too many dev hours.

Why not simply this?

$hasChildren = $hasChildren || !empty($element[$childname];
nils.destoop’s picture

Status: Active » Fixed

It used to be !empty($element[$childname]). But some modules give a non-empty element, but display nothing.
A better solution got committed today. See #2311789: Group is incorrectly determined to be empty with nested form elements. (this commit: http://cgit.drupalcode.org/field_group/commit/?id=5564892)

nils.destoop’s picture

Status: Fixed » Closed (duplicate)