From 1de1a6c01f06adfa3241595a63d13d35afc39547 Mon Sep 17 00:00:00 2001
From: Matthew Radcliffe <mradcliffe@kosada.com>
Date: Sat, 1 Oct 2011 15:33:32 -0400
Subject: [PATCH] [#1215884] by mradcliffe. Non-required fields should provide
 a -none- option that does not save a value. This commit may
 not cover all cases such as saving a value, then switching
 back to -none-. I will need to write another test for that,
 but later...

---
 cck_select_other.module     |   21 +++++++++++++---
 tests/cck_select_other.test |   55 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/cck_select_other.module b/cck_select_other.module
index db232da..e84b8be 100644
--- a/cck_select_other.module
+++ b/cck_select_other.module
@@ -85,7 +85,7 @@ function cck_select_other_field_widget_settings_form($field, $instance) {
  */
 function cck_select_other_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
   $options = cck_select_other_options($instance);
-  $def = '';
+  $def = $instance['required'] ? '' : '-none-';
 
   if (empty($items)) {
     $items[] = array('value' => '');
@@ -106,7 +106,7 @@ function cck_select_other_field_widget_form(&$form, &$form_state, $field, $insta
     $otherdef = ($def == 'other') ? $instance['default_value'][0]['value'] : '';
   }
   else {
-    $def = 'other';
+    $def = $instance['required'] ? array_shift(array_values($options)) : '-none-';
     $otherdef = '';
   }
 
@@ -208,9 +208,14 @@ function cck_select_other_options($field) {
       $options[$key] = t('@option', array('@option' => $option));
     }
   }
+  
   if (!isset($options['other'])) {
     $options['other'] = t('Other');
   }
+  
+  if (!$field['required']) {
+    $options = array_merge(array('-none-' => t('-None-')), $options);
+  }
 
   return $options;
 }
@@ -252,14 +257,22 @@ function cck_select_other_process($element, &$form_state) {
   $field_name = $reversed[2];
 
   if (isset($field_values) && !empty($field_values)) {
-    if ($field_values['select_other_list'] == 'other') {
+    if ($field_values['select_other_list'] == '-none-') {
+      // If we are not a required field, then we do not set a value.
+      $element['#value'] = '';
+      $field_values = array(
+        'value' => '',                    
+      );
+    }
+    else if ($field_values['select_other_list'] == 'other') {
+      // Use text input if we have 'other' selected
       $element['#value'] = $field_values['select_other_text_input'];
       $field_values = array(
         'value' => $field_values['select_other_text_input'],
       );
-      // Validate empty? This seems to be done in list.module in Drupal 7 now.
     }
     else {
+      // Use the select list otherwise
       $element['#value'] = $field_values['select_other_list'];
       $field_values = array(
         'value' => $field_values['select_other_list'],
diff --git a/tests/cck_select_other.test b/tests/cck_select_other.test
index ba09634..d763c98 100644
--- a/tests/cck_select_other.test
+++ b/tests/cck_select_other.test
@@ -24,7 +24,6 @@ class CCKSelectOtherTest extends DrupalWebTestCase {
    */
   public function setUp() {
     parent::setUp(array('cck_select_other', 'php'));
-//    parent::setUp('field', 'field_ui', 'list', 'options', 'cck_select_other'); //enable field api modules
 
     $this->assertTrue(module_exists('cck_select_other'), t('CCK Select Other module is enabled.'));
 
@@ -61,6 +60,7 @@ class CCKSelectOtherTest extends DrupalWebTestCase {
     );
     $this->drupalPost($bundle_path . '/fields', $edit, 'Save');
     $edit = array(
+      'instance[required]' => TRUE, 
       'instance[widget][settings][select_list_options]' => $this->options,
       'instance[widget][settings][select_list_options_fieldset][advanced_options][select_list_options_php]' => '',
       'field_' . $field_name . '[und][0][select_other_list]' => 'other',
@@ -87,7 +87,8 @@ class CCKSelectOtherTest extends DrupalWebTestCase {
     $this->drupalLogout();
 
     $options_arr = cck_select_other_options($this->test_instance);
-    $this->assertEqual(5, count($options_arr), t('There are 5 = %count options set on the field.', array('%count' => count($options_arr))));
+    $options_arr_count = $this->test_instance['required'] ? 5 : 6;
+    $this->assertEqual($options_arr_count, count($options_arr), t('There are 5 = %count options set on the field.', array('%count' => count($options_arr))));
   }
 
   /**
@@ -466,3 +467,53 @@ class CCKSelectOtherMultipleValueListTest extends CCKSelectOtherTest {
   }
 
 }
+
+/**
+ * @class CCKSelectOtherNotRequiredTest
+ */
+class CCKSelectOtherNotRequiredTest extends CCKSelectOtherTest {
+  
+  public static function getInfo() {
+    return array(
+      'name' => t('CCK Select Other Not Required'),
+      'description' => t('Asserts that CCK Select Other is not saving any values if -none- is selected.'),
+      'group' => t('Field UI'),
+    );
+  }
+  
+  function setUp() {
+    parent::setUp();
+    
+    $this->test_instance['required'] = FALSE;
+    field_update_instance($this->test_instance);
+    $this->test_instance = field_info_instance('node', $this->test_field['field_name'], $this->test_node->type);
+  }
+
+  /**
+   * Test that there is a -none- option in a non-required field and that it does
+   * not save a field value.
+   */
+  function testNoRequired() {
+    $this->drupalLogin($this->web_user);
+
+    $name = substr($this->test_field['field_name'], 6);
+    
+    // Assert that we have -none- as the option in our select list.
+    $this->drupalGet('node/' . $this->test_node->nid . '/edit');
+    $this->assertOptionSelected('edit-field-' . $name . '-und-0-select-other-list', '-none-', t('-None- option selected in select list.'));
+
+    // Post to the node, and make sure that -none- is the value and that value ends up as empty.
+    $edit = array(
+      $this->test_instance['field_name'] . '[und][0][select_other_list]' => '-none-',            
+    );
+    $this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
+    $this->assertNoRaw($this->test_instance['label']);
+    
+    // Assert the node object as well.
+    $node = node_load($this->test_node->nid);    
+    $this->assertNull($node->{$this->test_instance['field_name']}['und'], t('Select other did not save any value for non-required field.'));
+    
+    $this->drupalLogout();
+  }
+  
+}
-- 
1.7.4.4

