You are here

function conditional_fields_node_after_build in Conditional Fields 6.2

Main tasks:

  • Create javascript settings
  • Prepare custom validation for required controlled fields
  • Assign a theme function to conditional fields
  • Apply orphaned fields settings if applicable
1 string reference to 'conditional_fields_node_after_build'
conditional_fields_node_form in ./conditional_fields.module
Alter node form. We do it in after_build for compatibility with non-core CCK widgets

File

./conditional_fields.module, line 658
Content fields and groups visibility based on the values of user defined 'trigger' fields.

Code

function conditional_fields_node_after_build($form, &$form_state) {

  // Avoid running twice when the form is rebuilt with AHAH
  if (!empty($form_state['clicked_button']['#ahah'])) {
    return $form;
  }
  $type_name = $form['type']['#value'];

  // Do nothing if there are no conditional fields
  if (!($data = conditional_fields_load_data($type_name))) {
    return $form;
  }
  $controlling_fields = array();
  $missing_controlling_fields = array();
  $controlled_fields = array();
  $required_fields = array();
  $js_settings = array();
  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'];
  }

  /* Handle controlling fields */
  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);
    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]);
    }
    else {
      $form[$controlling_field_name]['#controlling_fields'] = TRUE;
      conditional_fields_item_apply_theme($form[$controlling_field_name]);
    }
  }

  /* Handle controlled fields */
  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);
    if (!$controlled_field || isset($controlled_field['#access']) && $controlled_field['#access'] === FALSE) {
      continue;
    }

    // Handle orphaned fields.
    foreach ($missing_controlling_fields as $missing_controlling_field) {
      unset($controlled_field_parents[$missing_controlling_field]);
    }
    if (count($controlled_field_parents) == 0) {
      $orphaned_settings = variable_get('c_fields_edit_' . $type_name, C_FIELDS_ORPHANED_SHOW_TRIGGERED);
      switch ($orphaned_settings) {
        case C_FIELDS_ORPHANED_SHOW_TRIGGERED:

          // Show only triggered fields. E.g.: fields whose controlling
          // fields have triggering values set by default, or set by
          // another user with permissions.
          $triggered = TRUE;
          foreach ($controlling_fields as $controlling_field_name => $controlling_field_descendants) {
            if ($controlling_field_descendants[$controlled_field_name]) {
              if (!conditional_fields_is_triggered($form_state['values'][$controlling_field_name], $controlling_field_descendants[$controlled_field_name])) {
                $triggered = FALSE;
                break;
              }
            }
          }
          if ($triggered) {
            break;
          }
        case C_FIELDS_ORPHANED_HIDE:

          // Unset controlled field.
          if ($group_of_controlled_field) {
            unset($form[$group_of_controlled_field][$controlled_field_name]);
          }
          else {
            unset($form[$controlled_field_name]);
          }
          break;
        case C_FIELDS_ORPHANED_SHOW_ALL:
      }
      continue;
    }
    if ($controlled_field['#required']) {
      $required_fields[$controlled_field_name] = array(
        'field' => $controlled_field_name,
        'in_group' => $group_of_controlled_field,
      );
    }
    $is_group = strpos($controlled_field_name, 'group_') === 0 ? TRUE : FALSE;

    // Required fields inside a controlled fieldgroup
    // must be handled by conditional fields.
    if ($is_group) {
      foreach (element_children($controlled_field) as $group_element) {
        if ($controlled_field[$group_element]['#required'] && !$controlled_fields[$group_element]) {
          $required_fields[$group_element] = array(
            'field' => $group_element,
            'in_group' => $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]);
    }
    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]);
    }

    // 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);
    foreach ($controlled_field_parents as $controlling_field_name => $trigger_values) {
      $js_controlling_field_id = '#conditional-' . conditional_fields_form_clean_id($controlling_field_name);
      $js_settings['controlling_fields'][$js_controlling_field_id][$js_controlled_field_id] = array(
        'field_id' => $js_controlled_field_id,
        'trigger_values' => $trigger_values,
      );
    }
  }

  // Controlled fields should only be required when triggered.
  // 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']], $form['#field_info'][$field['field']]);
      conditional_fields_item_apply_theme($form[$field['in_group']][$field['field']]);
    }
    else {
      conditional_fields_custom_required_field($form[$field['field']], $form['#field_info'][$field['field']]);
      conditional_fields_item_apply_theme($form[$field['field']]);
    }
  }

  // Apply user interface settings
  $ui_settings = variable_get('c_fields_js_' . $type_name, C_FIELDS_JS_HIDE);
  switch ($ui_settings) {
    case C_FIELDS_JS_DISABLE:
      $js_settings['ui_settings'] = 'disable';
      break;
    case C_FIELDS_JS_HIDE:
      $js_settings['ui_settings']['animation'] = (int) variable_get('c_fields_animation_' . $type_name, C_FIELDS_ANIMATION_NO);
      $js_settings['ui_settings']['anim_speed'] = variable_get('c_fields_anim_speed_' . $type_name, "normal");
      break;
  }

  // Key settings by an unique identifier so we can have multiple node forms
  // with conditional fields in the same page. We use the form build id since
  // the form's id might not be unique.
  $js_id = $form['#build_id'];
  $js_settings = array(
    $js_id => $js_settings,
  );
  if ($ui_settings != C_FIELDS_JS_NO) {
    conditional_fields_add_js($js_settings);
  }

  // Pass variables for validation
  $form['#conditional_fields']['data'] = $data;
  $form['#conditional_fields']['required_fields'] = $required_fields;
  $form['#conditional_fields']['settings'] = $js_settings;

  // Add validation function
  $form['#validate'] = array_merge(array(
    'conditional_fields_node_form_validate',
  ), (array) $form['#validate']);
  return $form;
}