Условные группы/наборы полей в Drupal 7

Предыстория: в Drupal 7 я создал форму с помощью CCK (он же Field UI). Я использовал модуль Field group для создания fieldgroup, но мне нужно, чтобы он был условным, то есть он будет отображаться только в зависимости от предыдущего отвечать.

Предыдущие исследования: чтобы создать условное поле, вы можете использовать hook_form_alter() для редактирования #states атрибут так:

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'),
      ),
    );
  }
}

Однако, похоже, нет никакого способа использовать API состояний для групп полей. Следует отметить, что хотя поля хранятся в $form, группы полей хранятся в $form['#groups'], а также в $form['#fieldgroups']. Я не знаю, как их различать, и, имея это в виду, я попытался применить #states к группе полей таким же образом, как описано выше. Однако это приводит только к ошибкам сервера.

Вопрос. Есть ли способ настроить отображение группы полей с помощью API состояний или какого-либо альтернативного подхода?


person seane    schedule 14.06.2012    source источник


Ответы (3)


вы должны использовать hook_field_group_build_pre_render_alter()

Просто :

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),
    ),
  );
}

Это работает отлично. Если группа А находится в другой группе, сделайте это

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

Вам может понадобиться добавить атрибут id, если его не существует:

$element['your_field_group']['#attributes']['id'] = 'some-id';
$element['yout_field_group']['#id'] = 'some-id';
person bobylapointe    schedule 03.11.2012
comment
Вау, это гораздо элегантнее, чем мое решение! Спасибо! - person seane; 05.11.2012
comment
Это сработало для меня, но я столкнулся с серьезной проблемой. При создании узла с другим типом контента этот код все равно будет выполняться. И когда я попытался поставить в коде условие для проверки конкретного типа узла, оказалось, что элемент $переносит значения из другой формы в эту. Основная проблема: неправильный тип узла. Кто-нибудь еще испытывает это? Я на Д7. - person MTsrb; 18.10.2013
comment
@MTsrb Попробуйте условие на $element['#form_id'] - person yunzen; 30.07.2014

Вот самое простое решение, которое я придумал. По сути, это состоит из двух частей: (1.) программно изменить отображение формы и (2.) использовать графический интерфейс для изменения отображения содержимого.

(1.) Сначала я использовал hook_form_alter () для программного создания условного набора полей и добавления к нему существующих полей. Код показан ниже.

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.) Затем я использовал модуль Field group, чтобы изменить отображение содержимого. Я сделал это, перейдя к своему типу контента и используя вкладку «Управление отображением», чтобы создать группу полей и добавить в нее свои поля. Таким образом, поля будут отображаться отдельно от одной и той же группы как в форме, так и в сохраненном содержимом.

person seane    schedule 28.06.2012

Возможно, вы можете попробовать посмотреть код этого модуля, чтобы найти идею.

person Juuuuuu    schedule 28.06.2012
comment
Спасибо за совет. На самом деле я не стал смотреть на это, потому что у меня наконец-то появилось что-то, что заработало. Ознакомьтесь с опубликованным решением, если вам интересно. - person seane; 29.06.2012