See: http://drupal.org/node/650008

This version works with the latest nested fieldgroup cck code added upstream that replaces the old nested fieldgroups cck patch, see: http://drupal.org/node/849420#comment-4011484
This version hasthe suggested change from http://drupal.org/node/650008#comment-4823534 applied.

diff -Nurp ../conditional_fields.orig/conditional_fields.module ./conditional_fields.module
--- ../conditional_fields.orig/conditional_fields.module	2011-09-14 07:56:10.000000000 -0500
+++ ./conditional_fields.module	2011-09-14 08:04:39.000000000 -0500
@@ -201,6 +201,9 @@ function conditional_fields_nodeapi(&$no
       return;
     }
 
+    // Get all groups from form
+    $groups = fieldgroup_groups($node->type);
+
     foreach ($data as $field) {
 
       // We might have to look for the field in a group
@@ -212,8 +215,12 @@ function conditional_fields_nodeapi(&$no
         continue;
       }
 
+      // Get group array of the form
+      $controlled_group_ref = conditional_fields_get_item_group($groups, $controlled_group, $node->content);
+      $controlling_group_ref = conditional_fields_get_item_group($groups, $controlling_group, $node->content);
+
       // The controlled field is in a group and is not the form for other reasons. Skip.
-      if ($controlled_group && !$node->content[$controlled_group]['group'][$field['field_name']]) {
+      if ($controlled_group && !$controlled_group_ref[$field['field_name']]) {
         continue;
       }
 
@@ -225,9 +232,9 @@ function conditional_fields_nodeapi(&$no
       $field_key = array_keys($type['fields'][$field['control_field_name']]['columns']);
       foreach ((array)$node->$field['control_field_name'] as $value) {
         $current_values[$field['control_field_name']][] = $value[$field_key[0]];
-        if (!empty($value[$field_key[0]])) {
+        if ($value[$field_key[0]] != "") {
           if ($node->content[$field['control_field_name']]['field']['#access'] == TRUE ||
-              ($controlling_group && $node->content[$controlling_group]['group'][$field['control_field_name']]['field']['#access'] == TRUE)) {
+             ($controlling_group && $controlling_group_ref[$field['control_field_name']]['field']['#access'] == TRUE)) {
             $viewed = TRUE;
           }
         }
@@ -237,10 +244,10 @@ function conditional_fields_nodeapi(&$no
         // Hide the controlled field if it is not triggered
         if (!conditional_fields_is_triggered($current_values[$field['control_field_name']], $field['trigger_values'])) {
           if ($controlled_group) {
-            $node->content[$controlled_group]['group'][$field['field_name']]['#access'] = FALSE;
+            conditional_fields_hide_field_node_viewing($groups, $controlled_group, $node->content, $field['field_name']);
           }
           else {
-            $node->content[$field['field_name']]['#access'] = FALSE;
+            $node->content[$field['field_name']]['field']['#access'] = FALSE;
           }
         }
       }
@@ -296,14 +303,30 @@ function conditional_fields_form_alter(&
       break;
     case 'content_add_more_js':
       // Handle ahah multiple fields
-      foreach ($form as $item_name => $item) {
-        if (db_result(db_query("SELECT COUNT(*) FROM {conditional_fields} WHERE field_name = '%s'", $item_name))) {
-          $form[$item_name]['#post_render'] = array_merge(array('conditional_fields_add_more_post_render'), (array)$form[$item_name]['#post_render']);
-          foreach (element_children($form[$item_name]) as $element) {
-            conditional_fields_custom_required_field($form[$item_name][$element]);
+
+      // 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);
+
+      $data = conditional_fields_load_data($form['#field']['type']);
+
+      foreach ($data as $row) {
+        if (in_array($row['field_name'], $fieldsets)){
+          $group_name = array_search($row['field_name'], $fieldsets);
+          $fieldsets[$group_name][$row['field_name']]['#post_render'] = array_merge(array('conditional_fields_add_more_post_render'), (array)$fieldsets[$group_name][$row['field_name']]['#post_render']);
+          foreach (element_children($fieldsets[$group_name][$row['field_name']]) as $element) {
+            conditional_fields_custom_required_field($fieldsets[$group_name][$row['field_name']][$element]);
+          }
+        }
+        else {
+          $form[$row['field_name']]['#post_render'] = array_merge(array('conditional_fields_add_more_post_render'), (array)$form[$row['field_name']]['#post_render']);
+          foreach (element_children($form[$row['field_name']]) as $element) {
+            conditional_fields_custom_required_field($form[$row['field_name']][$element]);
           }
         }
       }
+
       break;
     case 'content_copy_import_form':
       $form['#submit'][] = 'conditional_fields_import';
@@ -535,7 +558,7 @@ function conditional_fields_fieldgroup_g
   // Find fields with allowed values which are not inside a group
   foreach ($form['#content_type']['fields'] as $field) {
     $in_group = fieldgroup_get_group($form['#content_type']['type'], $field['field_name']);
-    if (!$in_group) {
+    if (!$in_group || $in_group == $form['parent']['#default_value']) {
       if ($allowed_values[$field['field_name']] = conditional_fields_allowed_values($field)) {
         $available_fields[$field['field_name']] = $field;
       }
@@ -622,6 +645,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
  */
@@ -655,6 +701,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'];
@@ -664,16 +715,23 @@ 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 ($group_of_controlling_field != '' && array_key_exists($group_of_controlling_field, $fieldsets)) {
+      if (is_array($fieldsets[$group_of_controlling_field]['#group_fields'])){
+        $fieldsets[$group_of_controlling_field]['#group_fields'][$controlling_field_name]['#controlling_fields'] = TRUE;
+        conditional_fields_item_apply_theme($fieldsets[$group_of_controlling_field]['#group_fields'][$controlling_field_name]);
+      }
+      else {
+        $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;
@@ -685,7 +743,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 || (isset($controlled_field['#access']) && $controlled_field['#access'] === FALSE)) {
       continue;
     }
@@ -715,8 +773,13 @@ 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 && $group_of_controlled_field != '' && array_key_exists($group_of_controlled_field, $fieldsets)) {
+            if (is_array($fieldsets[$group_of_controlled_field]['#group_fields'])){
+              unset($fieldsets[$group_of_controlled_field]['#group_fields'][$controlled_field_name]);
+            }
+            else {
+              unset($fieldsets[$group_of_controlled_field][$controlled_field_name]);
+            }
           }
           else {
             unset($form[$controlled_field_name]);
@@ -741,18 +804,28 @@ function conditional_fields_node_after_b
           $required_fields[$group_element] = array('field' => $group_element, 'in_group' => $controlled_field_name);
         }
       }
+
+      // wrap groups in controlled field theming
+      conditional_fields_item_apply_theme($fieldsets[$controlled_field_name], $controlled_field_name);
     }
 
     // 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 && $group_of_controlled_field != '' && array_key_exists($group_of_controlled_field, $fieldsets)) {
+      if (is_array($fieldsets[$group_of_controlled_field]['#group_fields'])){
+        $fieldsets[$group_of_controlled_field]['#group_fields'][$controlled_field_name]['#controlled_fields'] = TRUE;
+        conditional_fields_item_apply_theme($fieldsets[$group_of_controlled_field]['#group_fields'][$controlled_field_name], ($is_group ? $controlled_field_name : ''));
+      }
+      else {
+        $fieldsets[$group_of_controlled_field][$controlled_field_name]['#controlled_fields'] = TRUE;
+        conditional_fields_item_apply_theme($fieldsets[$group_of_controlled_field][$controlled_field_name], ($is_group ? $controlled_field_name : ''));
+      }
     }
     else {
       $form[$controlled_field_name]['#controlled_fields'] = TRUE;
-      $is_group ? conditional_fields_item_apply_theme($form[$controlled_field_name], $controlled_field_name) : conditional_fields_item_apply_theme($form[$controlled_field_name]);
+      conditional_fields_item_apply_theme($form[$controlled_field_name], ($is_group ? $controlled_field_name : ''));
     }
 
+
     // Add fields to javascript settings
     // TODO: Use unique ids (requires per-widget settings)
     $js_controlled_field_id = '#conditional-' . conditional_fields_form_clean_id($controlled_field_name);
@@ -766,9 +839,15 @@ 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 (array_key_exists($field['in_group'], $fieldsets) && is_array($fieldsets[$field['in_group']]) && array_key_exists($field['field'], $fieldsets[$field['in_group']])){
+      if (is_array($fieldsets[$field['in_group']]['#group_fields'])){
+        conditional_fields_custom_required_field($fieldsets[$field['in_group']]['#group_fields'][$field['field']]);
+        conditional_fields_item_apply_theme($fieldsets[$field['in_group']]['#group_fields'][$field['field']]);
+      }
+      else {
+        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']]);
@@ -826,26 +905,35 @@ 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 (!empty($items[$item_name])) {
     return $items[$item_name];
   }
 
+  $haystack = $form;
+
+  if (is_array($fieldsets) && !array_key_exists($item_name, $haystack)){
+    $haystack = $fieldsets;
+  }
+
   if ($group) {
-    if (!empty($form[$group][$item_name])) {
-      $items[$item_name] = $form[$group][$item_name];
+    if ($haystack[$group][$item_name]) {
+      $items[$item_name] = $haystack[$group][$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];
     }
-    elseif (!empty($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];
+    else if (is_array($haystack[$group]['#group_fields']) && array_key_exists($item_name, $haystack[$group]['#group_fields'])) {
+      $items[$item_name] = $haystack[$group]['#group_fields'][$item_name];
     }
   }
   else {
-    if (!empty($form[$item_name])) {
-      $items[$item_name] = $form[$item_name];
+    if ($haystack[$item_name]) {
+      $items[$item_name] = $haystack[$item_name];
     }
-    elseif (!empty($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];
     }
   }
 
@@ -875,6 +963,11 @@ function conditional_fields_node_editing
     conditional_fields_add_js($form['#conditional_fields']['settings']);
   }
 
+  // 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);
+
   // Rebuild the array grouping the data by controlled fields
   // Needed to handle multiple controlling field per controlled field
   $controlled_fields = array();
@@ -882,6 +975,8 @@ function conditional_fields_node_editing
     $controlled_fields[$row['field_name']][$row['control_field_name']] = $row['trigger_values'];
   }
 
+  $required_fields = $form['#conditional_fields']['required_fields'];
+
   foreach ($controlled_fields as $controlled_field_name => $controlling_fields) {
     // Check if all controlling field were triggered
     $triggered = FALSE;
@@ -895,10 +990,10 @@ function conditional_fields_node_editing
     $required_fields = $form['#conditional_fields']['required_fields'];
 
     if (!empty($required_fields[$controlled_field_name]['in_group'])) {
-      $controlled_field = &$form[$required_fields[$controlled_field_name]['in_group']][$controlled_field_name];
+      $controlled_field = &$fieldsets[$required_fields[$controlled_field_name]['in_group']][$controlled_field_name];
     }
     else {
-      $controlled_field = &$form[$controlled_field_name];
+      $controlled_field = &$fieldsets[$controlled_field_name];
     }
 
     // Controlled field
@@ -1291,12 +1386,12 @@ function conditional_fields_set_required
  * Unset the #required property and set a #conditional_fields_required property for custom validation.
  */
 function conditional_fields_custom_required_field(&$field) {
-  if ($field['#required']) {
+  if (isset($field['#required'])) {
     unset($field['#required']);
     $field['#conditional_fields_required'] = TRUE;
   }
   foreach (element_children($field) as $child) {
-    conditional_fields_custom_required_field($field[$child]);
+    if (is_array($field[$child])) conditional_fields_custom_required_field($field[$child]);
   }
 }
 
@@ -1399,3 +1494,47 @@ function conditional_fields_form_clean_i
   $id = str_replace(array('][', '_', ' '), '-', $id);
   return $id;
 }
+
+/**
+* Retuns group array from a name
+*/
+function conditional_fields_get_item_group($groups, $group_name, $content) {
+  $group = $group_name;
+  $group_chain = array();
+
+  while ($group != "") {
+    array_unshift($group_chain, $group);
+    $group = $groups[$group]["parent"];
+  }
+
+  $groupref = &$content;
+
+  foreach ($group_chain as $group) {
+    $groupref = &$groupref[$group]['group'];
+  }
+
+  return $groupref;
+}
+
+/**
+* Hides field within a group or nested group
+*/
+
+function conditional_fields_hide_field_node_viewing($groups, $group_name, &$content, $field_name) {
+  $group = $group_name;
+  $group_chain = array();
+
+  while ($group != "") {
+    array_unshift($group_chain, $group);
+    $group = $groups[$group]["parent"];
+  }
+
+  $groupref = &$content;
+
+  foreach ($group_chain as $group) {
+    $groupref = &$groupref[$group]['group'];
+  }
+
+  $groupref[$field_name]['field']['#access'] = FALSE;
+}
+
