? conditional_fields_boolean_or.patch Index: conditional_fields.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/conditional_fields/conditional_fields.install,v retrieving revision 1.5.2.1 diff -u -p -r1.5.2.1 conditional_fields.install --- conditional_fields.install 17 Jan 2010 00:26:08 -0000 1.5.2.1 +++ conditional_fields.install 13 Jun 2010 03:09:14 -0000 @@ -31,6 +31,11 @@ function conditional_fields_schema() { 'length' => '32', 'not null' => TRUE, 'default' => ''), + 'boolean_operator' => array( + 'type' => 'varchar', + 'length' => '3', + 'not null' => TRUE, + 'default' => ''), 'type' => array( 'type' => 'varchar', 'length' => '127', @@ -58,3 +63,9 @@ function conditional_fields_uninstall() cache_clear_all('variables', 'cache'); } + +function conditional_fields_update_6200() { + $ret = array(); + db_add_field($ret, 'conditional_fields', 'boolean_operator', array('type' => 'varchar', 'length' => '3', 'not null' => TRUE, 'default' => '')); + return $ret; +} Index: conditional_fields.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/conditional_fields/conditional_fields.js,v retrieving revision 1.7.2.4 diff -u -p -r1.7.2.4 conditional_fields.js --- conditional_fields.js 15 Mar 2010 22:50:06 -0000 1.7.2.4 +++ conditional_fields.js 13 Jun 2010 03:09:14 -0000 @@ -10,32 +10,63 @@ Drupal.ConditionalFields.switchField = f return; } $.each(Drupal.settings.ConditionalFields.controlling_fields[id], function(i, controlledField) { + var boolean_operator = Drupal.settings.ConditionalFields.boolean_operators[controlledField.field_id]; var triggers = Drupal.ConditionalFields.checkTriggered(controlledField, values); // If the field was not triggered, hide it - if (!triggers) { - Drupal.ConditionalFields.doAnimation(controlledField, 'hide', onPageReady); - } - // Else check other controlling fields: if any one doesn't trigger, hide the field and stop checking - else { - var otherTriggers = true; - $.each(Drupal.settings.ConditionalFields.controlling_fields, function(ii, maybeControllingField) { - if (ii != id) { - $.each(maybeControllingField, function(iii, maybeControlledField) { - if (maybeControlledField.field_id == controlledField.field_id) { - otherTriggers = Drupal.ConditionalFields.checkTriggered(maybeControlledField, Drupal.ConditionalFields.findValues($(ii))); - if (!otherTriggers) { - return false; + if (boolean_operator == 'AND') { + if (!triggers) { + Drupal.ConditionalFields.doAnimation(controlledField, 'hide', onPageReady); + } + // Else check other controlling fields: if any one doesn't trigger, hide the field and stop checking + else { + var otherTriggers = true; + $.each(Drupal.settings.ConditionalFields.controlling_fields, function(ii, maybeControllingField) { + if (ii != id) { + $.each(maybeControllingField, function(iii, maybeControlledField) { + if (maybeControlledField.field_id == controlledField.field_id) { + otherTriggers = Drupal.ConditionalFields.checkTriggered(maybeControlledField, Drupal.ConditionalFields.findValues($(ii))); + if (!otherTriggers) { + return false; + } } - } - }); + }); + } + if (!otherTriggers) { + Drupal.ConditionalFields.doAnimation(controlledField, 'hide', onPageReady); + return false; + } + }); + if (otherTriggers) { + Drupal.ConditionalFields.doAnimation(controlledField, 'show', onPageReady); } + } + } + if (boolean_operator == 'OR') { + if (triggers) { + Drupal.ConditionalFields.doAnimation(controlledField, 'show', onPageReady); + } + // Else check other controlling fields: if any one doesn't trigger, hide the field and stop checking + else { + var otherTriggers = false; + $.each(Drupal.settings.ConditionalFields.controlling_fields, function(ii, maybeControllingField) { + if (ii != id) { + $.each(maybeControllingField, function(iii, maybeControlledField) { + if (maybeControlledField.field_id == controlledField.field_id) { + otherTriggers = Drupal.ConditionalFields.checkTriggered(maybeControlledField, Drupal.ConditionalFields.findValues($(ii))); + if (otherTriggers) { + return true; + } + } + }); + } + if (otherTriggers) { + Drupal.ConditionalFields.doAnimation(controlledField, 'show', onPageReady); + return true; + } + }); if (!otherTriggers) { Drupal.ConditionalFields.doAnimation(controlledField, 'hide', onPageReady); - return false; } - }); - if (otherTriggers) { - Drupal.ConditionalFields.doAnimation(controlledField, 'show', onPageReady); } } }); Index: conditional_fields.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/conditional_fields/conditional_fields.module,v retrieving revision 1.8.2.17 diff -u -p -r1.8.2.17 conditional_fields.module --- conditional_fields.module 10 Apr 2010 01:57:48 -0000 1.8.2.17 +++ conditional_fields.module 13 Jun 2010 03:09:14 -0000 @@ -202,6 +202,29 @@ function conditional_fields_nodeapi(&$no return; } + // Set fields using boolean OR to hidden by default. + // To-do: Remove duplicated code. + foreach ($data as $field) { + // The controlled field is not in a group and is not in the form for other reasons. Skip. + if (!$controlled_group && !$node->content[$field['field_name']]) { + continue; + } + + // 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']]) { + continue; + } + + if ($field['boolean_operator'] == 'OR') { + if ($controlled_group) { + $node->content[$controlled_group]['group'][$field['field_name']]['#access'] = FALSE; + } + else { + $node->content[$field['field_name']]['#access'] = FALSE; + } + } + } + foreach ($data as $field) { // We might have to look for the field in a group @@ -235,15 +258,31 @@ function conditional_fields_nodeapi(&$no } if ($viewed) { - // 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; + if ($field['boolean_operator'] == 'AND') { + // 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; + } + else { + $node->content[$field['field_name']]['#access'] = FALSE; + } } - else { - $node->content[$field['field_name']]['#access'] = FALSE; + } + elseif ($field['boolean_operator'] == 'OR') { + // Show the controlled field if it is 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'] = TRUE; + } + else { + $node->content[$field['field_name']]['#access'] = TRUE; + } } } + else { + return; + } } else { // Apply orphaned fields settings @@ -251,8 +290,19 @@ function conditional_fields_nodeapi(&$no switch ($orphaned_settings) { case C_FIELDS_ORPHANED_SHOW_TRIGGERED: - // If the field was triggered, don't hide it + // If the field was triggered, either: + // 1. Don't hide it (AND) + // 2. Show it (OR) if (conditional_fields_is_triggered($current_values[$field['control_field_name']], $field['trigger_values'])) { + if ($field['boolean_operator'] == 'OR') { + if ($controlled_group) { + $node->content[$controlled_group]['group'][$field['field_name']]['#access'] = TRUE; + } + else { + $node->content[$field['field_name']]['#access'] = TRUE; + } + } + break; } case C_FIELDS_ORPHANED_HIDE: @@ -263,8 +313,17 @@ function conditional_fields_nodeapi(&$no else { $node->content[$field['field_name']]['#access'] = FALSE; } + + break; case C_FIELDS_ORPHANED_SHOW_ALL: - // Nothing to do... + if ($field['boolean_operator'] == 'OR') { + if ($controlled_group) { + $node->content[$controlled_group]['group'][$field['field_name']]['#access'] = TRUE; + } + else { + $node->content[$field['field_name']]['#access'] = TRUE; + } + } break; } } @@ -412,8 +471,9 @@ function conditional_fields_content_admi if (isset($available_fields)) { $default_values = conditional_fields_available_fields_default_values($form['field_name']['#value'], $available_fields); + $boolean_operator_fieldset = conditional_fields_content_admin_field_boolean_operator(); $available_fieldset = conditional_fields_content_admin_field_controllable($type, $default_values, $available_fields, $allowed_values, 'field'); - + // Add validation function $form['#validate'] = array_merge(array('conditional_fields_content_admin_field_validate'), $form['#validate']); @@ -441,6 +501,7 @@ function conditional_fields_content_admi } $form['widget']['conditional_fields']['available_fields'] = $available_fieldset; } + $form['widget']['conditional_fields']['boolean_operator'] = $boolean_operator_fieldset; } return; } @@ -515,6 +576,31 @@ function conditional_fields_content_admi } /** + * Boolean operator settings form + */ +function conditional_fields_content_admin_field_boolean_operator() { + $output = array( + '#type' => 'fieldset', + '#title' => t('Boolean operator'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + ); + // Add radio buttons to choose boolean operator + $output['boolean_operator'] = array( + '#type' => 'radios', + '#title' => t('Boolean operator'), + '#description' => t('The boolean operator used when there are multiple controlling fields. Choose AND to show the field only if all controlling fields have triggered values selected. Choose OR to show the field when any controlling field has a triggered value selected.'), + '#default_value' => 'AND', + '#options' => array( + 'AND' => 'AND', + 'OR' => 'OR' + ), + ); + + return $output; +} + +/** * Alteration of the fieldgroup editing form */ function conditional_fields_fieldgroup_group_edit_form(&$form) { @@ -557,6 +643,7 @@ function conditional_fields_fieldgroup_g '#attributes' => array('id' => 'conditional-fields-settings'), ); $form['widget']['conditional_fields']['available_fields'] = conditional_fields_content_admin_field_controllable($form['#content_type'], $default_values, $available_fields, $allowed_values, 'group'); + $form['widget']['conditional_fields']['boolean_operator'] = conditional_fields_content_admin_field_boolean_operator(); // Add validation function $form['#validate'][] = 'conditional_fields_content_admin_field_validate'; @@ -594,12 +681,13 @@ function conditional_fields_content_admi function conditional_fields_forms_submit($form, &$form_state) { $controlled_field = (isset($form_state['values']['field_name']) ? $form_state['values']['field_name'] : $form_state['values']['group_name']); $type = (isset($form['#field']['type_name']) ? $form['#field']['type_name'] : $form['#content_type']['type']); - conditional_fields_save_field($type, $controlled_field, $form_state['values']['conditional_fields']['available_fields']); + $boolean_operator = $form_state['values']['conditional_fields']['boolean_operator']['boolean_operator']; + conditional_fields_save_field($type, $controlled_field, $form_state['values']['conditional_fields']['available_fields'], $boolean_operator); // Fields already controlled should share the same settings of their controlling fields if ($form_state['values']['controlled_fields']) { foreach ($form_state['values']['controlled_fields'] as $field_name => $trigger_values) { - conditional_fields_save_field($type, $field_name, $form_state['values']['conditional_fields']['available_fields']); + conditional_fields_save_field($type, $field_name, $form_state['values']['conditional_fields']['available_fields'], $boolean_operator); } } } @@ -661,6 +749,7 @@ function conditional_fields_node_after_b 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']; + $boolean_operators[$row['field_name']] = $row['boolean_operator']; } /* Handle controlling fields */ @@ -700,6 +789,7 @@ function conditional_fields_node_after_b if (count($controlled_field_parents) == 0) { $orphaned_settings = variable_get('c_fields_edit_' . $type_name, C_FIELDS_ORPHANED_SHOW_TRIGGERED); switch ($orphaned_settings) { + // To-do: Add code here. 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 @@ -763,6 +853,8 @@ function conditional_fields_node_after_b $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); } + $boolean_operator = $boolean_operators[$controlled_field_name]; + $js_settings['boolean_operators'][$js_controlled_field_id] = $boolean_operator; } // Controlled fields should only be required when triggered. @@ -882,15 +974,29 @@ function conditional_fields_node_editing $controlled_fields = array(); foreach ($form['#conditional_fields']['data'] as $row) { $controlled_fields[$row['field_name']][$row['control_field_name']] = $row['trigger_values']; + $boolean_operators[$row['field_name']] = $row['boolean_operator']; } foreach ($controlled_fields as $controlled_field_name => $controlling_fields) { - // Check if all controlling field were triggered - $triggered = FALSE; - foreach ($controlling_fields as $controlling_field_name => $trigger_values) { - $triggered = conditional_fields_is_triggered($form_state['values'][$controlling_field_name], $trigger_values); - if ($triggered == FALSE) { - break; + $boolean_operator = $boolean_operators[$controlled_field_name]; + if ($boolean_operator == 'AND') { + // Check if all controlling field were triggered + $triggered = FALSE; + foreach ($controlling_fields as $controlling_field_name => $trigger_values) { + $triggered = conditional_fields_is_triggered($form_state['values'][$controlling_field_name], $trigger_values); + if ($triggered == FALSE) { + break; + } + } + } + elseif ($boolean_operator == 'OR') { + // Check if any controlling field was triggered + $triggered = FALSE; + foreach ($controlling_fields as $controlling_field_name => $trigger_values) { + $triggered = conditional_fields_is_triggered($form_state['values'][$controlling_field_name], $trigger_values); + if ($triggered == TRUE) { + break; + } } } @@ -917,15 +1023,29 @@ function conditional_fields_node_editing } else { // Set error only if the containing group is not controlled or is controlled and triggered - $set_error = TRUE; - foreach ($form['#conditional_fields']['data'] as $row_check_containing_group) { - if ($row_check_containing_group['field_name'] == $in_group) { - if (!conditional_fields_is_triggered($form_state['values'][$row_check_containing_group['control_field_name']], $row_check_containing_group['trigger_values'])) { - $set_error = FALSE; + if ($boolean_operator == 'AND') { + $set_error = TRUE; + foreach ($form['#conditional_fields']['data'] as $row_check_containing_group) { + if ($row_check_containing_group['field_name'] == $in_group) { + if (!conditional_fields_is_triggered($form_state['values'][$row_check_containing_group['control_field_name']], $row_check_containing_group['trigger_values'])) { + $set_error = FALSE; + } + break; } - break; } } + elseif ($boolean_operator == 'OR') { + $set_error = FALSE; + foreach ($form['#conditional_fields']['data'] as $row_check_containing_group) { + if ($row_check_containing_group['field_name'] == $in_group) { + if (conditional_fields_is_triggered($form_state['values'][$row_check_containing_group['control_field_name']], $row_check_containing_group['trigger_values'])) { + $set_error = TRUE; + } + break; + } + } + } + if ($set_error) { form_error($controlled_field, t('!name field is required.', array('!name' => $controlled_field['#title']))); } @@ -1033,7 +1153,7 @@ function conditional_fields_load_data($t if (!$data[$structure][$type]) { $data[$structure][$type] = array(); if ($structure == 'row') { - $query = db_query("SELECT control_field_name, field_name, trigger_values FROM {conditional_fields} WHERE type = '%s'", $type); + $query = db_query("SELECT control_field_name, field_name, trigger_values, boolean_operator FROM {conditional_fields} WHERE type = '%s'", $type); while ($result = db_fetch_array($query)) { $result['trigger_values'] = unserialize($result['trigger_values']); $data['row'][$type][] = $result; @@ -1215,7 +1335,7 @@ function conditional_fields_content_fiel // Import conditional fields definitions with content_copy module elseif ($ops == 'create instance') { if ($field['conditional_fields']['available_fields']) { - conditional_fields_save_field($field['type_name'], $field['field_name'], $field['conditional_fields']['available_fields']); + conditional_fields_save_field($field['type_name'], $field['field_name'], $field['conditional_fields']['available_fields'], $field['boolean_operator']); } } } @@ -1226,7 +1346,7 @@ function conditional_fields_content_fiel * * Use this function with caution, as it doesn't check if the content type and the fields actually exist. */ -function conditional_fields_save_field($type_name, $controlled_field, $controlling_fields) { +function conditional_fields_save_field($type_name, $controlled_field, $controlling_fields, $boolean_operator) { foreach ($controlling_fields as $controlling_field => $trigger_values) { // If the row already exists if (db_result(db_query("SELECT COUNT(*) FROM {conditional_fields} WHERE control_field_name = '%s' AND field_name = '%s' AND type = '%s'", $controlling_field, $controlled_field, $type_name))) { @@ -1235,13 +1355,13 @@ function conditional_fields_save_field($ conditional_fields_delete_field($type_name, $controlled_field, $controlling_field); } else { - conditional_fields_update_field($type_name, $controlled_field, $controlling_field, $trigger_values); + conditional_fields_update_field($type_name, $controlled_field, $controlling_field, $trigger_values, $boolean_operator); } } else { // If values are set, create new entry if (!empty($trigger_values) && !$trigger_values['conditional_field_no_value']) { - conditional_fields_insert_field($type_name, $controlled_field, $controlling_field, $trigger_values); + conditional_fields_insert_field($type_name, $controlled_field, $controlling_field, $trigger_values, $boolean_operator); } } } @@ -1250,15 +1370,15 @@ function conditional_fields_save_field($ /** * Insert into database the data of a new conditional field */ -function conditional_fields_insert_field($type_name, $controlled_field, $controlling_field, $trigger_values) { - db_query("INSERT INTO {conditional_fields} (control_field_name, field_name, type, trigger_values) VALUES ('%s', '%s', '%s', '%s')", $controlling_field, $controlled_field, $type_name, serialize($trigger_values)); +function conditional_fields_insert_field($type_name, $controlled_field, $controlling_field, $trigger_values, $boolean_operator) { + db_query("INSERT INTO {conditional_fields} (control_field_name, field_name, type, trigger_values, boolean_operator) VALUES ('%s', '%s', '%s', '%s', '%s')", $controlling_field, $controlled_field, $type_name, serialize($trigger_values), $boolean_operator); } /** * Update an existing conditonal field's database data */ -function conditional_fields_update_field($type_name, $controlled_field, $controlling_field, $trigger_values) { - db_query("UPDATE {conditional_fields} SET trigger_values = '%s' WHERE control_field_name = '%s' AND field_name = '%s' AND type = '%s'", serialize($trigger_values), $controlling_field, $controlled_field, $type_name); +function conditional_fields_update_field($type_name, $controlled_field, $controlling_field, $trigger_values, $boolean_operator) { + db_query("UPDATE {conditional_fields} SET trigger_values = '%s', boolean_operator = '%s' WHERE control_field_name = '%s' AND field_name = '%s' AND type = '%s'", serialize($trigger_values), $boolean_operator, $controlling_field, $controlled_field, $type_name); } /**