2012-06-14 73 views
8

背景:在Drupal 7中,我创建了一个带有CCK(即字段UI)的表单。我使用Field group模块来创建一个fieldgroup,但我需要它是有条件的,这意味着它将只显示取决于以前的答案。Drupal 7中的条件字段组/字段集

以前的研究:要创建一个条件字段,您可以使用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'), 
    ), 
    ); 
    } 
} 

然而,似乎没有办法使用FIELDGROUPS的美国API。需要注意的一点是,虽然字段存储在$form中,但字段组存储在$form['#groups']以及$form['#fieldgroups']中。我不知道如何区分它们,考虑到这一点,我尝试以与上述相同的方式将#states属性应用于字段组。但是,它只会产生服务器错误。

问题:有没有办法使State API有条件地使用States API或其他方法来显示?

回答

2

这是我想出的最简单的解决方案。基本上有两部分内容:(1)以编程方式改变表单的显示,(2)使用GUI改变内容的显示。首先,我使用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模块来改变内容的显示。我通过转到我的内容类型并使用“管理显示”选项卡创建了一个字段组并添加了我的字段。这样,这些字段在窗体和保存的内容上将显示为相同的组。

0

也许你可以试试看this module的代码来帮助你找到想法。

+0

谢谢你的提示。我并没有真正结束,因为我终于找到了一些工作。如果您有兴趣,请查看发布的解决方案。 – seane

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

这工作perfecly。如果组A是另一个组中,这样做

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

您可能需要如果不存在添加一个id属性:

$element['your_field_group']['#attributes']['id'] = 'some-id'; 
$element['yout_field_group']['#id'] = 'some-id'; 
+0

哇,这比我的解决方案更优雅!谢谢! – seane

+0

这种为我工作,但我遇到了一个重大问题。当创建不同内容类型的节点时,该代码仍然会执行。当我试图在代码中添加一个条件来检查特定节点类型时,看起来$元素从另一个表单转移到了这个值。主要问题:节点类型不正确。任何人都会遇到这种情况我在D7上。 – MTsrb

+0

@MTsrb尝试'$ element ['#form_id']' – HerrSerker