2012-06-14 14 views
8

Sfondo: In Drupal 7, ho creato un modulo con CCK (ovvero l'interfaccia utente di campo). Ho usato il modulo Field group per creare un fieldgroup, ma ho bisogno che sia condizionale, il che significa che verrà visualizzato solo in base a una risposta precedente.Gruppi di campi condizionali/campi in Drupal 7

Precedenti ricerche: Per creare un campo condizionale, è possibile utilizzare hook_form_alter() per modificare l'attributo #states in questo modo:

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

Tuttavia, sembra che ci sia alcun modo per utilizzare l'API Uniti per fieldgroups. Una cosa da notare è che, mentre i campi sono memorizzati in $form, i gruppi di campi sono memorizzati in $form['#groups'] e nello $form['#fieldgroups']. Non so come distinguere tra questi, e con questo in mente, ho provato ad applicare un attributo #states ad un fieldgroup nello stesso modo come sopra. Tuttavia, produce solo errori del server.

Domanda: C'è un modo per rendere condizionale un fieldgroup utilizzando l'API Stati o un approccio alternativo?

risposta

2

Ecco la soluzione più semplice mi è venuta. Esistono essenzialmente due parti: (1.) alterano la visualizzazione del modulo a livello di programmazione e (2.) utilizzano la GUI per modificare la visualizzazione del contenuto.

(1.) Innanzitutto, ho utilizzato hook_form_alter() per creare a livello di codice il set di campi condizionale e aggiungere campi esistenti. Il codice è mostrato sotto.

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.) Poi ho usato il modulo Field group di modificare la visualizzazione del contenuto. L'ho fatto andando al mio tipo di contenuto e utilizzando la scheda "Gestisci display" per creare un gruppo di campi e aggiungervi i miei campi. In questo modo, i campi sembreranno appartenere allo stesso gruppo sia sul modulo che sul contenuto salvato.

0

Forse si può provare a guardare il codice di this module per aiutarvi a trovare un'idea.

+0

Grazie per la punta. In realtà non ho finito per guardarlo perché ho finalmente qualcosa su cui lavorare. Controlla la soluzione pubblicata se sei interessato. – seane

3

è necessario utilizzare il hook_field_group_build_pre_render_alter()

Semplicemente:

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

Questo funziona in ottima posizione. Se il gruppo A è in un altro gruppo, fare questo

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

potrebbe essere necessario aggiungere un attributo id se non esiste:

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

Wow, questo è molto più elegante della mia soluzione! Grazie! – seane

+0

Questo tipo di ha funzionato per me ma ho riscontrato un grosso problema. Quando si crea un nodo di un diverso tipo di contenuto, questo codice dovrebbe ancora essere eseguito. E quando ho provato a inserire una condizione nel codice per verificare lo specifico tipo di nodo, è emerso che l'elemento $ riportava i valori dall'altra forma a questa. Problema principale: il tipo di nodo non era corretto. Qualcun altro lo sperimenta? Sono su D7. – MTsrb

+0

@MTsrb Prova una condizione su '$ element ['# form_id']' – HerrSerker