See: http://drupal.org/node/650008 diff -Nurp ../conditional_fields.orig/conditional_fields.module ./conditional_fields.module --- ../conditional_fields.orig/conditional_fields.module 2010-07-16 10:24:42.000000000 -0500 +++ ./conditional_fields.module 2010-07-16 10:24:52.000000000 -0500 @@ -613,6 +613,29 @@ function conditional_fields_allowed_valu } /** + * Return an array of all fieldsets within the $form stored at the first depth of the array + * Each key in this array is a reference to the appropriate $form key + * Therefore all changes to $fieldsets will propogate to the appropriate $form key + * Due to recursion, the results are stored in the $fieldsets parameter + * This will produce a smaller array that can be searched through with less overhead + */ +function conditional_fields_node_editing_form_get_fieldgroups(&$form, &$fieldsets){ + foreach ($form as $form_key => $form_field){ + if (is_array($form[$form_key])){ + if (array_key_exists('#type', $form[$form_key])){ + if (strcasecmp($form[$form_key]['#type'], "fieldset") == 0){ + // The fieldset fields must map to the original form fields + // This allows for modifying the values without having to do a recursive search again + $fieldsets[$form_key] = & $form[$form_key]; + + conditional_fields_node_editing_form_get_fieldgroups($form[$form_key], $fieldsets); + } + } + } + } +} + +/** * Alter node form. We do it in after_build for compatibility * with non-core CCK widgets */ @@ -646,6 +669,11 @@ function conditional_fields_node_after_b $required_fields = array(); $js_settings = array(); + // Find all fieldsets in the form array via a recursive function + // Doing this is better than recursively walking the $form array foreach field in the $data array + $fieldsets = array(); + conditional_fields_node_editing_form_get_fieldgroups($form, $fieldsets); + foreach ($data as $row) { $controlling_fields[$row['control_field_name']][$row['field_name']] = $row['trigger_values']; $controlled_fields[$row['field_name']][$row['control_field_name']] = $row['trigger_values']; @@ -655,16 +683,17 @@ function conditional_fields_node_after_b foreach ($controlling_fields as $controlling_field_name => $controlling_field_descendants) { // Check if the controlling field is in the form, user has access to it, and is editable. $group_of_controlling_field = conditional_fields_get_group($type_name, $controlling_field_name); - $controlling_field = conditional_fields_item_in_form($form, $controlling_field_name, $group_of_controlling_field); + + $controlling_field = conditional_fields_item_in_form($form, $controlling_field_name, $group_of_controlling_field, $fieldsets); if (!$controlling_field || $controlling_field['#access'] === FALSE || $controlling_field['#type'] == 'markup') { $missing_controlling_fields[] = $controlling_field_name; continue; } // Set values on form for themeing. - if ($group_of_controlling_field) { - $form[$group_of_controlling_field][$controlling_field_name]['#controlling_fields'] = TRUE; - conditional_fields_item_apply_theme($form[$group_of_controlling_field][$controlling_field_name]); + if (!empty($group_of_controlling_field) && array_key_exists($group_of_controlling_field, $fieldsets)) { + $fieldsets[$group_of_controlling_field][$controlling_field_name]['#controlling_fields'] = TRUE; + conditional_fields_item_apply_theme($fieldsets[$group_of_controlling_field][$controlling_field_name]); } else { $form[$controlling_field_name]['#controlling_fields'] = TRUE; @@ -676,7 +705,7 @@ function conditional_fields_node_after_b foreach ($controlled_fields as $controlled_field_name => $controlled_field_parents) { // Check if the controlled field is in the form and user has access to it. $group_of_controlled_field = conditional_fields_get_group($type_name, $controlled_field_name); - $controlled_field = conditional_fields_item_in_form($form, $controlled_field_name, $group_of_controlled_field); + $controlled_field = conditional_fields_item_in_form($form, $controlled_field_name, $group_of_controlled_field, $fieldsets); if (!$controlled_field || $controlled_field['#access'] === FALSE) { continue; } @@ -706,8 +735,8 @@ function conditional_fields_node_after_b } case C_FIELDS_ORPHANED_HIDE: // Unset controlled field. - if ($group_of_controlled_field) { - unset($form[$group_of_controlled_field][$controlled_field_name]); + if ($group_of_controlled_field && !empty($group_of_controlling_field) && array_key_exists($group_of_controlling_field, $fieldsets)) { + unset($fieldsets[$group_of_controlled_field][$controlled_field_name]); } else { unset($form[$controlled_field_name]); @@ -735,9 +764,9 @@ function conditional_fields_node_after_b } // Set values on form for themeing. - if ($group_of_controlled_field) { - $form[$group_of_controlled_field][$controlled_field_name]['#controlled_fields'] = TRUE; - conditional_fields_item_apply_theme($form[$group_of_controlled_field][$controlled_field_name]); + if ($group_of_controlled_field && !empty($group_of_controlling_field) && array_key_exists($group_of_controlling_field, $fieldsets)) { + $fieldsets[$group_of_controlled_field][$controlled_field_name]['#controlled_fields'] = TRUE; + conditional_fields_item_apply_theme($fieldsets[$group_of_controlled_field][$controlled_field_name]); } else { $form[$controlled_field_name]['#controlled_fields'] = TRUE; @@ -757,9 +786,9 @@ function conditional_fields_node_after_b // Since required fields validation is hardcoded in _form_validate, // we need to unset the #required property and perform a custom validation. foreach ($required_fields as $field) { - if ($field['in_group']) { - conditional_fields_custom_required_field($form[$field['in_group']][$field['field']]); - conditional_fields_item_apply_theme($form[$field['in_group']][$field['field']]); + if ($field['in_group'] && !empty($group_of_controlling_field) && array_key_exists($group_of_controlling_field, $fieldsets)) { + conditional_fields_custom_required_field($fieldsets[$field['in_group']][$field['field']]); + conditional_fields_item_apply_theme($fieldsets[$field['in_group']][$field['field']]); } else { conditional_fields_custom_required_field($form[$field['field']]); @@ -816,26 +845,32 @@ function conditional_fields_item_apply_t * Find an item in a form by key. If it's a CCK field, the function * will find it using field_info. */ -function conditional_fields_item_in_form($form, $item_name, $group = FALSE) { +function conditional_fields_item_in_form($form, $item_name, $group = FALSE, $fieldsets = NULL) { static $items; if ($items[$item_name]) { return $items[$item_name]; } + $haystack = $form; + + if (is_array($fieldsets)){ + $haystack = $fieldsets; + } + if ($group) { - if ($form[$group][$item_name]) { - $items[$item_name] = $form[$group][$item_name]; + if ($haystack[$group][$item_name]) { + $items[$item_name] = $haystack[$group][$item_name]; } - elseif ($form[$group][$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]) { - $items[$item_name] = $form[$group][$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]; + elseif ($haystack[$group][$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]) { + $items[$item_name] = $haystack[$group][$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]; } } else { - if ($form[$item_name]) { - $items[$item_name] = $form[$item_name]; + if ($haystack[$item_name]) { + $items[$item_name] = $haystack[$item_name]; } - elseif ($form[$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]) { - $items[$item_name] = $form[$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]; + elseif ($haystack[$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]) { + $items[$item_name] = $haystack[$form['#field_info'][$item_name]['display_settings']['parent']][$item_name]; } }