diff -u w/conditional_fields.module w/conditional_fields.module --- w/conditional_fields.module +++ w/conditional_fields.module @@ -214,27 +214,53 @@ * Have to wait for the group elements to be created - unfortunately this is after after_build */ function conditional_fields_field_group_build_pre_render_alter(&$element) { - $form = &$element; + // Have to re-process conditional fields over again for newly created + // fieldgroup elements (and existing elements moved to fieldgroup children) - // Have to re-process conditional fields over again for fieldgroup elements - $form_state = &$form['#form_state']; - $form_state['complete form'] = $form; - $process = array(); - $groups = $form['#fieldgroups']; - foreach ($groups as $group_name => $group) { + // $form_state is added to $form['#form_state'] via conditional_fields_form_after_build() + $form_state = $element['#form_state']; + $form_state['complete form'] = $element; + $form = &$form_state['complete form']; + // Loop through fieldgroups and fieldgroup children + $new_dependents = array(); + foreach ($form['#fieldgroups'] as $group_name => $group) { + // Call element_after_build for fieldgroup children foreach($group->children as $field_name) { $parents = array_merge($group->array_parents, array($field_name)); $field_element = &drupal_array_get_nested_value($form, $parents); conditional_fields_element_after_build($field_element, $form_state, TRUE); } + // Call element_after_build for fieldgroup element $group_element = &drupal_array_get_nested_value($form, $group->array_parents); - $group_element['#group_name'] = $group_name; + $group_element['#field_name'] = $group_name; + // Make sure group element has an ID to select in drupal_process_states + $group_element['#id'] = isset($group_element['#id']) ? $group_element['#id'] : $group_name; + // Need to wrap markup type with a div with the ID, unless ID already present in prefix or markup + if (isset($group_element['#type']) && $group_element['#type'] == 'markup') { + if ((!isset($group_element['#prefix']) || !strstr($group_element['#prefix'], '#' . $group_element['#id'])) + && (!isset($group_element['#markup']) || !strstr($group_element['#markup'], '#' . $group_element['#id'])) + ) { + $group_element['#prefix'] = '
' . (isset($group_element['#prefix']) ? $group_element['#prefix'] : ''); + $group_element['#suffix'] = (isset($group_element['#suffix']) ? $group_element['#suffix'] : '') . '
'; + } + } conditional_fields_element_after_build($group_element, $form_state, TRUE); + if (isset($form['#conditional_fields'][$group_name], $form['#conditional_fields'][$group_name]['dependees'])) { + $new_dependents[$group_name] = &$group_element; + } + } + + // Call form_after_build + $form = conditional_fields_form_after_build($form, $form_state, TRUE); + + // Call validation for group dependents + foreach ($new_dependents as $dependent_name => &$dependent) { + conditional_fields_dependent_validate($dependent, $form_state, $form); } - $form = $form_state['complete form']; + // Call form validation + conditional_fields_form_validate($form, $form_state); - // Manually call form after_build - $form = conditional_fields_form_after_build($form, $form_state); + $element = $form; } /** @@ -250,10 +276,6 @@ if (isset($element['#field_name'])) { $field = $element; } - elseif (isset($element['#group_name'])) { - $field = $element; - $field['#field_name'] = $field['#group_name']; - } elseif (isset($element['#language'], $element[$element['#language']], $element[$element['#language']]['#field_name'])) { // Some fields are wrapped in containers before processing. $field = $element[$element['#language']]; @@ -261,6 +283,7 @@ else { return $element; } + $form = &$form_state['complete form']; // Avoid processing fields in fields_ui administration pages. @@ -287,6 +310,7 @@ else { return $element; } + $dependencies = conditional_fields_load_dependencies($entity_type, $bundle); if (!$dependencies) { @@ -402,7 +426,7 @@ */ function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $options, $id = 0) { $options += conditional_fields_dependency_default_options(); - + // The absence of the $id parameter identifies a custom dependency. if (!$id) { // String values are accepted to simplify usage of this function with custom @@ -430,14 +454,10 @@ // Attach dependee. // Use the #parents property of the dependee instead of #field_parents since // we will need access to the full structure of the widget. - if (isset($dependee['#array_parents'])) { - $dependee_parents = $dependee['#array_parents']; - } - elseif (isset($dependee['#parents'])) { - $dependee_parents = $dependee['#parents']; - } - if (isset($dependee_parents)) { - $form['#conditional_fields'][$dependee['#field_name']]['parents'] = $dependee_parents; + // We also need #field_parents to get the field from $form + if (isset($dependee['#parents'])) { + $form['#conditional_fields'][$dependee['#field_name']]['parents'] = $dependee['#parents']; + $form['#conditional_fields'][$dependee['#field_name']]['array_parents'] = $dependee['#array_parents']; $form['#conditional_fields'][$dependee['#field_name']]['dependents'][$id] = array( 'dependent' => $dependent['#field_name'], 'options' => $options, @@ -445,10 +465,7 @@ } // Attach dependent. - if (isset($dependent['#array_parents'])) { - $dependent_parents = $dependent['#array_parents']; - } - elseif (isset($dependent['#field_parents'])) { + if (isset($dependent['#field_parents'])) { $dependent_parents = $dependent['#field_parents']; } elseif (isset($dependent['#parents'])) { @@ -456,6 +473,7 @@ } if (isset($dependent_parents)) { $form['#conditional_fields'][$dependent['#field_name']]['field_parents'] = $dependent_parents; + $form['#conditional_fields'][$dependent['#field_name']]['array_parents'] = $dependent['#array_parents']; $form['#conditional_fields'][$dependent['#field_name']]['dependees'][$id] = array( 'dependee' => $dependee['#field_name'], 'options' => $options, @@ -483,18 +501,22 @@ // Set $form_state in $form so hook_field_group_build_pre_render_alter has access to it // when it is invoked after after_build (when fieldgroup elements are attached to form) $form['#form_state'] =& $form_state; - + $effects = array(); $state_handlers = conditional_fields_states_handlers(); // Cycle all dependents. foreach ($form['#conditional_fields'] as $dependent => $dependent_info) { $states = array(); + if (empty($dependent_info['dependees'])) { continue; } - $dependent_location = array_unique(array_merge($dependent_info['field_parents'], array($dependent))); + + // Here we use #array_parents to get field from $form + $dependent_location = $dependent_info['array_parents']; $dependent_form_field = drupal_array_get_nested_value($form, $dependent_location); + // Cycle the dependant's dependees. foreach ($dependent_info['dependees'] as $dependency) { $dependee = $dependency['dependee']; @@ -502,9 +524,16 @@ if (empty($form['#conditional_fields'][$dependee])) { continue; } + // Skip this dependency if it's a group element and state is not visible/hidden + // (dependencies for other states are attached to fieldgroup children elements) + if (in_array($dependent_form_field['#field_name'], array_keys($form['#fieldgroups'])) && !in_array($dependency['options']['state'], array('visible', 'hidden'))) { + continue; + } $dependee_info = $form['#conditional_fields'][$dependee]; - $dependee_form_field = drupal_array_get_nested_value($form, $dependee_info['parents']); + // Here we use #array_parents to get field from $form + $dependee_location = $dependee_info['array_parents']; + $dependee_form_field = drupal_array_get_nested_value($form, $dependee_location); $options = $dependency['options']; // Load field edit behaviors. @@ -639,6 +668,7 @@ $behavior($form, $form_state, $dependent, $dependent_info); } } + unset($behaviors); if (empty($states)) { @@ -725,7 +755,12 @@ * @see conditional_fields_form_validate() */ function conditional_fields_dependent_validate($element, &$form_state, $form) { - $dependent = $element[$element['#language']]; + if (isset($element['#language'], $element[$element['#language']])) { + $dependent = $element[$element['#language']]; + } + else { + $dependent = $element; + } // Check if this field's dependencies were triggered. if (conditional_fields_evaluate_dependencies($dependent, $form, $form_state)) { @@ -747,7 +782,7 @@ // conditional_fields_form_validate(). $errors = form_get_errors(); - if ($errors) { + if ($errors && isset($dependent['#parents'])) { // group elements have no #parents key $error_key = implode('][', $dependent['#parents']); foreach ($errors as $name => $error) { // An error triggered by this field might have been set on a descendant @@ -776,7 +811,9 @@ */ function conditional_fields_form_field_get_values($element, $form_state) { // Fall back to #parents to support custom dependencies. - $parents = isset($element['#field_parents']) ? $element['#field_parents'] : $element['#parents']; + // $parents = isset($element['#field_parents']) ? $element['#field_parents'] : $element['#parents']; + // Should this be the other way around? Isn't #parents the parent keys in $form_state['values']? + $parents = isset($element['#parents']) ? $element['#parents'] : $element['#field_parents']; return drupal_array_get_nested_value($form_state['values'], $parents); } @@ -1057,7 +1094,7 @@ foreach ($dependencies as $dependency_id => $dependency) { // Extract field values from submitted values. $dependee = $dependency['dependee']; - $dependee_parents = $form['#conditional_fields'][$dependee]['parents']; + $dependee_parents = $form['#conditional_fields'][$dependee]['array_parents']; // We have the parents of the field, but depending on the entity type and // the widget type, they may include additional elements that are actually diff -u w/includes/conditional_fields.admin.inc w/includes/conditional_fields.admin.inc --- w/includes/conditional_fields.admin.inc +++ w/includes/conditional_fields.admin.inc @@ -319,6 +319,7 @@ 'state' => $form_state['values']['state'], 'condition' => $form_state['values']['condition'] ); + if (!$id = conditional_fields_dependency_insert($form_state['values']['dependee'], $form_state['values']['dependent'], $options)) { drupal_set_message(t('There was an error while trying to create the dependency.'), 'error'); return;