Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional fieldgroups/fieldsets in Drupal 7

Background: In Drupal 7, I have created a form with CCK (aka the Field UI). I used the Field group module to create a fieldgroup, but I need it to be conditional, meaning it will only display depending on a previous answer.

Previous research: To create a conditional field, you can use hook_form_alter() to edit the #states attribute like so:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'person_info_node_form') {
    // Display 'field_maiden_name' only if married
    $form['field_maiden_name']['#states'] = array(
      'visible' => array(
        ':input[name="field_married[und]"]' => array('value' => 'Yes'),
      ),
    );
  }
}

However, there seems to be no way to use the States API for fieldgroups. One thing to note is that, while fields are stored in $form, fieldgroups are stored in $form['#groups'] as well as in $form['#fieldgroups']. I don't know how to distinguish between these, and with this in mind, I have tried to apply a #states attribute to a fieldgroup in the same manner as above. However, it only produces server errors.

Question: Is there a way to make a fieldgroup display conditionally using the States API or some alternative approach?

like image 992
seane Avatar asked Jun 14 '12 23:06

seane


2 Answers

you have to use the hook_field_group_build_pre_render_alter()

Simply :

function your_module_field_group_build_pre_render_alter(&$element) {
  $element['your_field_group']['#states'] = array(
    'visible' => array(
      ':input[name="field_checkbox"]' => array('checked' => TRUE),
    ),
  );
}

This works perfecly. If the group A is in an another group, do this

$element['groupA']['groupB']['#states'] etc....

You may need to add an id attribute if none exists:

$element['your_field_group']['#attributes']['id'] = 'some-id';
$element['yout_field_group']['#id'] = 'some-id';
like image 54
bobylapointe Avatar answered Nov 10 '22 18:11

bobylapointe


Here's the simplest solution I came up with. There are essentially 2 parts to this: (1.) programmatically alter the display of the form, and (2.) use the GUI to alter the display of the content.

(1.) First, I used hook_form_alter() to programmatically create the conditional fieldset and add existing fields to it. The code is shown below.

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'FORM_ID_node_form') {
    // programmatically create a conditional fieldset
    $form['MYFIELDSET'] = array( // do NOT name the same as a 'Field group' fieldset or problems will occur
      '#type' => 'fieldset',
      '#title' => t('Conditional fieldset'),
      '#weight' => intval($form['field_PARENT']['#weight'])+1, // put this fieldset right after it's "parent" field
      '#states' => array(
        'visible' => array(
          ':input[name="field_PARENT[und]"]' => array('value' => 'Yes'), // only show if field_PARENT == 'Yes'
        ),  
      ),  
    );

    // add existing fields (created with the Field UI) to the
    // conditional fieldset
    $fields = array('field_MYFIELD1', 'field_MYFIELD2', 'field_MYFIELD3');
    $form = MYMODULE_addToFieldset($form, 'MYFIELDSET', $fields);
  }
}

/**
 * Adds existing fields to the specified fieldset.
 *
 * @param  array   $form Nested array of form elements that comprise the form.
 * @param  string  $fieldset The machine name of the fieldset.
 * @param  array   $fields An array of the machine names of all fields to
 *                   be included in the fieldset.
 * @return array   $form The updated form.
 */
function MYMODULE_addToFieldSet($form, $fieldset, $fields) {
  foreach($fields as $field) {
    $form[$fieldset][$field] = $form[$field]; // copy existing field into fieldset
    unset($form[$field]); // destroy the original field or duplication will occur
  }

  return $form;
}

(2.) Then I used the Field group module to alter the display of the content. I did this by going to my content type and using the 'Manage display' tab to create a field group and add my fields to it. This way, the fields will appear to be apart of the same group on both the form and the saved content.

like image 23
seane Avatar answered Nov 10 '22 17:11

seane