diff --git a/conditional_fields.module b/conditional_fields.module
index 34503a6..fc69201 100644
--- a/conditional_fields.module
+++ b/conditional_fields.module
@@ -210,6 +210,60 @@ function conditional_fields_element_info_alter(&$types) {
}
/**
+ * Implements hook_field_group_build_pre_render_alter()
+ * 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) {
+ // Have to re-process conditional fields over again for newly created
+ // fieldgroup elements (and existing elements moved to fieldgroup children)
+
+ // $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['#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);
+ }
+ // Call form validation
+ conditional_fields_form_validate($form, $form_state);
+
+ $element = $form;
+}
+
+/**
* Processes form elements with dependencies.
*
* Just adds a #conditional_fields property to the form with the needed
@@ -217,7 +271,7 @@ function conditional_fields_element_info_alter(&$types) {
* - The fields #parents property.
* - Field dependencies data.
*/
-function conditional_fields_element_after_build($element, &$form_state) {
+function conditional_fields_element_after_build($element, &$form_state, $reprocess = FALSE) {
// Ensure that the element is a field.
if (isset($element['#field_name'])) {
$field = $element;
@@ -237,6 +291,10 @@ function conditional_fields_element_after_build($element, &$form_state) {
return $element;
}
+ // Get fieldgroup name if field belongs to one
+ $group_name = isset($form['#group_children']) && isset($form['#group_children'][$field['#field_name']]) ?
+ $form['#group_children'][$field['#field_name']] : NULL;
+
// Some fields do not have entity type and bundle properties. In this case we
// try to use the properties from the form. This is not an optimal solution,
// since in case of fields in entities within entities they might not correspond,
@@ -262,11 +320,24 @@ function conditional_fields_element_after_build($element, &$form_state) {
// Attach dependent.
if (isset($dependencies['dependents'][$field['#field_name']])) {
foreach ($dependencies['dependents'][$field['#field_name']] as $id => $dependency) {
- if (!isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) {
+ if ($reprocess || !isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) {
conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id);
}
}
}
+ // Also attach dependent if element is a (first) child in a dependent fieldgroup
+ // and the dependency state isn't 'visible' or 'hidden'
+ // (this is done on the fieldgroup element itself)
+ if ($group_name && isset($dependencies['dependents'][$group_name]) ) {
+ $group_dependent = $dependencies['dependents'][$group_name];
+ if (!in_array($group_dependent[key($group_dependent)]['options']['state'], array('visible', 'hidden'))) {
+ foreach ($group_dependent as $id => $dependency) {
+ if ($reprocess || !isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) {
+ conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id);
+ }
+ }
+ }
+ }
// Attach dependee.
// TODO: collect information about every element of the dependee widget, not
@@ -274,7 +345,7 @@ function conditional_fields_element_after_build($element, &$form_state) {
// define per-element sets of dependency values.
if (isset($dependencies['dependees'][$field['#field_name']])) {
foreach ($dependencies['dependees'][$field['#field_name']] as $id => $dependency) {
- if (!isset($form['#conditional_fields'][$field['#field_name']]['dependents'][$id])) {
+ if ($reprocess || !isset($form['#conditional_fields'][$field['#field_name']]['dependents'][$id])) {
conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $id);
}
}
@@ -400,6 +471,7 @@ function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $op
}
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,
@@ -424,6 +496,10 @@ function conditional_fields_form_after_build($form, &$form_state) {
return $form;
}
+ // 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();
@@ -435,7 +511,8 @@ function conditional_fields_form_after_build($form, &$form_state) {
continue;
}
- $dependent_location = 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.
@@ -445,9 +522,15 @@ function conditional_fields_form_after_build($form, &$form_state) {
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']);
+ $dependee_location = $dependee_info['parents'];
+ $dependee_form_field = drupal_array_get_nested_value($form, $dependee_location);
$options = $dependency['options'];
// Load field edit behaviors.
@@ -669,7 +752,12 @@ function conditional_fields_form_after_build($form, &$form_state) {
* @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)) {
@@ -691,7 +779,7 @@ function conditional_fields_dependent_validate($element, &$form_state, $form) {
// 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
@@ -720,7 +808,9 @@ function conditional_fields_dependent_validate($element, &$form_state, $form) {
*/
function conditional_fields_form_field_get_values($element, $form_state) {
// Fall back to #parents to support custom dependencies.
- $parents = !empty($element['#field_parents']) ? $element['#field_parents'] : $element['#parents'];
+ // $parents = !empty($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);
}
@@ -1269,21 +1359,34 @@ function conditional_fields_load_dependencies($entity_type = NULL, $bundle = NUL
$default_options = conditional_fields_dependency_default_options();
$select = db_select('conditional_fields', 'cf')
- ->fields('cf', array('id', 'options'))
- ->orderBy('cf.dependent');
+ ->fields('cf', array('id', 'options'));
$fci_depende = $select->join('field_config_instance', 'fci_dependee', 'cf.dependee = fci_dependee.id');
- $fci_dependent = $select->join('field_config_instance', 'fci_dependent', 'cf.dependent = fci_dependent.id');
$select->addField($fci_depende, 'field_name', 'dependee');
- $select->addField($fci_dependent, 'field_name', 'dependent');
$select->addField($fci_depende, 'entity_type');
$select->addField($fci_depende, 'bundle');
+ // Clone query now to allow a union with fieldgroup results
+ $select_group = clone $select;
+
+ // Join with field_config_instance
+ $fci_dependent = $select->join('field_config_instance', 'fci_dependent', 'cf.dependent = fci_dependent.id');
+ $select->addField($fci_dependent, 'field_name', 'dependent');
+
+ // Join with field_group
+ $group_dependent = $select_group->join('field_group', 'fg_dependent', 'cf.dependent = fg_dependent.id');
+ $select_group->addField($group_dependent, 'group_name', 'dependent');
+
if ($entity_type) {
$select->condition(
db_and()
->condition('fci_dependee.entity_type', $entity_type)
->condition('fci_dependent.entity_type', $entity_type)
);
+ $select_group->condition(
+ db_and()
+ ->condition('fci_dependee.entity_type', $entity_type)
+ ->condition('fg_dependent.entity_type', $entity_type)
+ );
}
if ($bundle) {
@@ -1292,7 +1395,15 @@ function conditional_fields_load_dependencies($entity_type = NULL, $bundle = NUL
->condition('fci_dependee.bundle', $bundle)
->condition('fci_dependent.bundle', $bundle)
);
+ $select_group->condition(
+ db_and()
+ ->condition('fci_dependee.bundle', $bundle)
+ ->condition('fg_dependent.bundle', $bundle)
+ );
}
+ // Union of results
+ //$select->orderBy('cf.dependent');
+ $select->union($select_group, 'UNION');
$result = $select->execute();
diff --git a/includes/conditional_fields.admin.inc b/includes/conditional_fields.admin.inc
index bf790f0..308b475 100644
--- a/includes/conditional_fields.admin.inc
+++ b/includes/conditional_fields.admin.inc
@@ -106,6 +106,15 @@ function conditional_fields_dependencies_overview_page($bundle_name = NULL, $ent
function conditional_fields_dependency_add_form($form, &$form_state, $entity_type, $bundle_name) {
$form = array();
$instances = field_info_instances($entity_type, $bundle_name);
+ // Get field groups on entity
+ $groups = field_group_info_groups($entity_type, $bundle_name);
+ $groups = isset($groups['form']) ? $groups['form'] : array();
+ foreach ($groups as $group_name => $group) {
+ $groups[$group_name] = (array)$group;
+ }
+ // New merged array of fields & groups for dependents
+ // Dependees should only be fields ($instances)
+ $instances_groups = $instances + $groups;
if (count($instances) < 2) {
$form['no_fields'] = array(
@@ -163,7 +172,7 @@ function conditional_fields_dependency_add_form($form, &$form_state, $entity_typ
// first row they will appear grouped.
if ($first_row == TRUE) {
$form['table']['dependencies'][$id]['dependent'] = array(
- '#markup' => check_plain($instances[$dependent]['label']) . ' (' . $dependent . ')',
+ '#markup' => check_plain($instances_groups[$dependent]['label']) . ' (' . $dependent . ')',
'#rowspan' => $dependee_count,
);
@@ -191,7 +200,7 @@ function conditional_fields_dependency_add_form($form, &$form_state, $entity_typ
$row['description']['#colspan'] = 2;
}
- $row['description']['#markup'] = conditional_fields_dependency_description($instances[$dependency['dependee']]['label'], $instances[$dependent]['label'], $dependency['options']);
+ $row['description']['#markup'] = conditional_fields_dependency_description($instances[$dependency['dependee']]['label'], $instances_groups[$dependent]['label'], $dependency['options']);
$row['edit'] = array(
'#type' => 'link',
@@ -221,6 +230,14 @@ function conditional_fields_dependency_add_form($form, &$form_state, $entity_typ
asort($fields);
+ // Build list of available groups.
+ $fieldgroups = array();
+ foreach ($groups as $group_name => $group) {
+ $fieldgroups[$group['id']] = check_plain($group['label'] . ' (' . $group['group_name'] . ')');
+ }
+
+ asort($fieldgroups);
+
// Build list of states.
$states = array_map('drupal_strtolower', conditional_fields_states());
@@ -236,7 +253,7 @@ function conditional_fields_dependency_add_form($form, &$form_state, $entity_typ
'#title' => t('Dependent'),
'#title_display' => 'invisible',
'#description' => t('Dependent'),
- '#options' => $fields,
+ '#options' => $fields + $fieldgroups,
'#prefix' => '' . t('Add new dependency') . '
',
),
'dependee' => array(
diff --git a/includes/conditional_fields.features.inc b/includes/conditional_fields.features.inc
index b998ce3..ec7f6fa 100644
--- a/includes/conditional_fields.features.inc
+++ b/includes/conditional_fields.features.inc
@@ -110,7 +110,21 @@ function conditional_fields_features_rebuild($module) {
}
$entity_instances = $instances[$field['entity']][$field['bundle']];
$dependee_id = $entity_instances[$field['dependee']]['id'];
- $dependent_id = $entity_instances[$field['dependent']]['id'];
+ $dependent_id = 0;
+ if (array_key_exists($field['dependent'], $entity_instances)) {
+ $dependent_id = $entity_instances[$field['dependent']]['id'];
+ }
+ elseif (module_exists('field_group')) {
+ $entity_groups = field_group_info_groups($field['entity'], $field['bundle'], 'form');
+ if (array_key_exists($field['dependent'], $entity_groups)) {
+ if (!$entity_groups[$field['dependent']]->id) {
+ field_group_group_save($entity_groups[$field['dependent']]);
+ $identifier = $entity_groups[$field['dependent']]->identifier;
+ $entity_groups[$field['dependent']] = field_group_load_field_group_by_identifier($identifier);
+ }
+ $dependent_id = $entity_groups[$field['dependent']]->id;
+ }
+ }
conditional_fields_dependency_insert($dependee_id, $dependent_id, $field['options']);
}
}