diff --git a/cck_select_other.install b/cck_select_other.install
index b234b14..6f7ee5c 100644
--- a/cck_select_other.install
+++ b/cck_select_other.install
@@ -1,12 +1,19 @@
array(
'label' => t('Select other list'),
'description' => t('Provides an "other" option, which allows the user to provide an alternate value.'),
- 'field types' => array('list', 'list_number', 'list_text'),
+ 'field types' => array('list_integer', 'list_float', 'list_text'),
'settings' => array(
'select_list_options' => '',
'select_list_options_fieldset' => array(
@@ -30,20 +30,6 @@ function cck_select_other_field_widget_info() {
}
/**
- * Implementation of hook_element_info().
- */
-function cck_select_other_element_info() {
- return array(
- 'cck_select_other' => array(
- '#input' => TRUE,
- '#process' => array('cck_select_other_process'),
- '#post_render' => array('cck_select_other_post_render'),
- '#pre_render' => array('cck_select_other_pre_render'),
- ),
- );
-}
-
-/**
* Implementation of hook_field_formatter_info().
*/
function cck_select_other_field_formatter_info() {
@@ -51,7 +37,7 @@ function cck_select_other_field_formatter_info() {
'cck_select_other' => array(
'label' => t('Select other'),
'description' => t('The default list module formatters do not take into account select other list widgets.'),
- 'field types' => array('list_integer', 'list_float', 'list_text', 'list_boolean'),
+ 'field types' => array('list_integer', 'list_float', 'list_text'),
),
);
}
@@ -65,9 +51,9 @@ function cck_select_other_field_formatter_view($entity_type, $entity, $field, $i
$settings = $instance['widget']['settings'];
$options = cck_select_other_options($instance);
+ $element = array();
foreach ($items as $delta => $item) {
-
$value = isset($options[$item['value']]) ? field_filter_xss($options[$item['value']]) : field_filter_xss($item['value']);
$element[$delta] = array(
@@ -122,63 +108,70 @@ 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 = $instance['required'] ? '' : '_none';
- $otherdef = '';
-
- if (empty($items)) {
- $items[] = array('value' => '');
- }
-
- if (!isset($items[$delta])) {
- $items[$delta] = array('value' => '');
- }
-
- // Set default value if we have instance data for delta, a default
- // value setting, or something basic if none at all.
- if (!empty($items[$delta]['value'])) {
- $def = (in_array($items[$delta]['value'], array_keys($options))) ? $items[$delta]['value'] : 'other';
- $otherdef = ($def == 'other') ? $items[$delta]['value'] : '';
- }
- else if (isset($instance['default_value'])) {
- $def = isset($instance['default_value'][0]['select_other_list']) ? $instance['default_value'][0]['select_other_list'] : 'other';
- $otherdef = ($def == 'other') ? $instance['default_value'][0]['value'] : '';
- }
-
- // This needs to be pulled out of our original element.
- $description = $element['#description'];
- $element = array(
- '#type' => $instance['widget']['type'],
- '#default_value' => '',
- '#prefix' => '
',
- '#suffix' => '
',
- '#field_name' => $field['field_name'], // Required fields for field_conditional_state.
- '#field_parents' => isset($form['#parents']) ? $form['#parents'] : array(),
+ // Setup select other wrapper.
+ $element += array(
'#bundle' => $instance['bundle'],
+ '#field_name' => $field['field_name'],
+ '#langcode' => $langcode,
+ '#element_validate' => array('cck_select_other_widget_validate'),
+ '#pre_render' => array('cck_select_other_widget_pre_render'),
+ '#attributes' => array(
+ 'class' => array('form-select-other-wrapper', 'cck-select-other-wrapper'),
+ ),
);
+ // Setup select list.
$element['select_other_list'] = array(
- '#title' => check_plain($instance['label']),
- '#description' => !empty($description) ? $description : t('You may specify your own option.'),
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
'#type' => 'select',
'#options' => $options,
- '#default_value' => $def,
+ '#required' => $instance['required'],
'#attributes' => array(
- 'class' => array('form-text form-select select_other_list'),
+ 'class' => array('form-text form-select form-select-other-list'),
),
- '#required' => $instance['required'],
);
- // @fixme - #states is REALLY slow here so I'm using my own shit again.
+ // Setup text input.
$element['select_other_text_input'] = array(
'#type' => 'textfield',
- '#default_value' => $otherdef,
+ '#title' => t('Provide other option'),
+ '#title_display' => 'invisible',
+ '#size' => 60,
'#attributes' => array(
- 'class' => array('form-text select_other_text_input'),
+ 'class' => array('form-text form-select-other-text-input'),
),
- '#element_validate' => array('cck_select_other_widget_validate'), // Always send through this validate function!
);
+ // Default empty values.
+ $list_default = $instance['required'] ? '' : '_none';
+ $text_default = '';
+ $value = '';
+
+ if (isset($items[$delta]['value'])) {
+ // Use the value provided in items.
+ $value = $items[$delta]['value'];
+ }
+ elseif (isset($instance['default_value'])) {
+ // Use the default value of the field if it is set.
+ $value = $instance['default_value'][0]['value'];
+ }
+
+ if ($value && in_array($value, array_keys($options))) {
+ // Value is not empty and value is in the list.
+ $list_default = $value;
+ }
+ elseif ($value) {
+ // Set the list default to other.
+ $list_default = 'other';
+ $text_default = $value;
+ }
+
+ // Set default values.
+ $element['select_other_list']['#default_value'] = $list_default;
+ $element['select_other_text_input']['#default_value'] = $text_default;
+
return $element;
}
@@ -209,43 +202,89 @@ function cck_select_other_form_alter(&$form, &$form_state, $form_id) {
* Validate empty text input for other selection.
*/
function cck_select_other_widget_validate($element, &$form_state) {
- // Reverse element parents because of element containers, notably profile2.
- $reversed = array_reverse($element['#parents']);
-
- $element_name = array_shift($reversed);
- $delta = array_shift($reversed);
- $langcode = array_shift($reversed);
- $field_name = array_shift($reversed);
-
- if (isset($form_state['field'][$field_name])) {
- // Retrieve stored field & instance info and form state values.
- $field = $form_state['field'][$field_name];
- $values = &$form_state['values'];
+ $values = drupal_array_get_nested_value($form_state['values'], $element['#array_parents']);
+
+ if (empty($values)) {
+ // Field UI does not behave in the same way as normal form operations, and
+ // values should be extracted from $element['#parents'] instead.
+ $values = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
}
- elseif (!empty($reversed) && isset($form_state['field']['#parents'])) {
- // Profile 2 exception.
- $container = array_shift($reversed);
- $field = $form_state['field']['#parents'][$container]['#fields'][$field_name];
- $values = &$form_state['values'][$container];
+
+ if (!$element['select_other_list']['#required'] && $values['select_other_list'] == '_none') {
+ // Empty select list option.
+ form_set_value($element, array('value' => NULL), $form_state);
+ }
+ elseif ($element['select_other_list']['#required'] && $values['select_other_list'] == '') {
+ // Empty select list option for required field.
+ form_set_value($element, array('value' => ''), $form_state);
+ form_error($element, t('You must select an option.'));
+ }
+ elseif ($element['select_other_list']['#required'] && $values['select_other_list'] == 'other' && !$values['select_other_text_input']) {
+ // Empty text input for required field.
+ form_set_value($element, array('value' => NULL), $form_state);
+ form_error($element['select_other_text_input'], t('You must provide a value for this option.'));
+ }
+ elseif ($values['select_other_list'] == 'other' && $values['select_other_text_input']) {
+ // Non-empty text input value.
+ form_set_value($element, array('value' => $values['select_other_text_input']), $form_state);
+ }
+ elseif ($values['select_other_list'] == 'other' && !$values['select_other_text_input']) {
+ // Empty text for non-required field.
+ form_set_value($element, array('value' => NULL), $form_state);
}
else {
- // Catastrophic error..?
- form_set_error($element['#name'], t('An error occurred trying to validate this field.'));
- watchdog('cck_select_other', 'Could not find field info in form state array for select other field, %name.', array('%name' => $field_name), WATCHDOG_ERROR);
+ // Non-empty select list value.
+ form_set_value($element, array('value' => $values['select_other_list']), $form_state);
}
- if ($field[$langcode]['instance']['required'] && $values[$field_name][$langcode][$delta]['select_other_list'] == 'other' && empty($values[$field_name][$langcode][$delta]['select_other_text_input'])) {
- // Empty other field.
- form_set_error($element['#name'], t('A non-empty value is required for this option.'));
- }
+ $field = field_info_field($element['#field_name']);
- if (!$field[$langcode]['instance']['required'] && $values[$field_name][$langcode][$delta]['select_other_list'] == '_none') {
- // Non-required field value.
- form_set_value($element, array(NULL), $form_state);
+ // Validate integer and float values for other options.
+ if ($field['type'] == 'list_integer' && $values['select_other_list'] == 'other') {
+ if (!preg_match('/^-?\d+$/', $values['select_other_text_input'])) {
+ form_error($element['select_other_text_input'], t('Only integers are allowed.'));
+ }
+ }
+ elseif ($field['type'] == 'list_float' && $values['select_other_list'] == 'other') {
+ if (!is_numeric($values['select_other_text_input'])) {
+ form_error($element['select_other_text_input'], t('Only valid numbers are allowed.'));
+ }
}
}
/**
+ * Attaches Javascript during pre build because this is when array parents
+ * should be defined to take advantage of modules that alter the element
+ * structure such as field_collection.
+ *
+ * @param $element
+ * The element array.
+ * @return array
+ * The element array.
+ */
+function cck_select_other_widget_pre_render($element) {
+ $key = $element['#field_name'] . '_' . $element['#delta'];
+ $settings = array(
+ $key => array(
+ 'list_element' => $element['select_other_list']['#id'],
+ 'input_element' => $element['select_other_text_input']['#id'],
+ ),
+ );
+
+ $element['#attached'] = array(
+ 'js' => array(
+ array(
+ 'data' => array('CCKSelectOther' => $settings),
+ 'type' => 'setting',
+ ),
+ drupal_get_path('module', 'cck_select_other') . '/cck_select_other.js',
+ ),
+ );
+
+ return $element;
+}
+
+/**
* Retrieve options for the select list
* @param $field the field instance we're working with
* @return an array of options to pass into the Form API.
@@ -299,157 +338,6 @@ function cck_select_other_options($field) {
}
/**
- * CCK Select Other widget process callback
- * @param $element
- * @param &$form_state
- * @return $element;
- */
-function cck_select_other_process($element, &$form_state) {
- if (!isset($element['#name'])) {
- return $element;
- }
-
- $keys = $element['#parents'];
-
- // field_values need to be a reference!
- $field_values = &$form_state['values'];
- foreach ($keys as $key) {
- $field_values = &$field_values[$key];
- }
-
- // Reverse array parents because of element containers, notably profile2.
- $reversed = array_reverse($keys);
-
- $delta = $reversed[0];
- $langcode = $reversed[1];
- $field_name = $reversed[2];
-
- if (isset($field_values) && !empty($field_values)) {
- 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'],
- );
- }
- else {
- // Use the select list otherwise
- $element['#value'] = $field_values['select_other_list'];
- $field_values = array(
- 'value' => $field_values['select_other_list'],
- );
- }
-
- return $element;
- }
- else {
- $element['#value'] = '';
- if (isset($element['select_other_list']['#default_value'])) {
- $element['select_other_list']['#value'] = $element['select_other_list']['#default_value'];
- }
- }
-
- return $element;
-}
-
-/**
- * Pre render callback for the form so we can recreate the fake form after it gets
- * blown away by the CCK process callback.
- * @param $element the element
- * @param $form_state
- * @return $form
- */
-function cck_select_other_pre_render($element, $form_state = NULL) {
- static $js;
-
- $errors = form_get_errors();
- if (!empty($errors)) {
- // Validation errors for the text input box get lost so need to be injected.
- $text_element = $element['#name'] . '[select_other_text_input]';
- if (in_array($text_element, array_keys($errors))) {
- $element['select_other_text_input']['#attributes']['class'][] = 'error';
- }
- }
-
- if (!isset($form_state)) {
- return $element;
- }
-
- if (!isset($element['#type']) || $element['#type'] <> 'cck_select_other') {
- return $element;
- }
-
- // No matches = not our field.
- $n = preg_match_all("/[A-Za-z0-9\-\_]+/", $element['#name'], $matches);
- if ($n == 0) {
- return $element;
- }
-
- // By any chance if we don't have any array keys, get out of here.
- $keys = isset($matches[0]) ? $matches[0]: NULL;
- if (!isset($keys)) {
- return $element;
- }
-
- foreach ($keys as $key => $val) {
- $keys[$key] = preg_replace("/_/", '-', $val);
- }
- $field_id = implode('-', $keys);
-
- if (!$js) {
- drupal_add_js(drupal_get_path('module', 'cck_select_other') . '/cck_select_other.js');
- $js = TRUE;
- }
- drupal_add_js(array('CCKSelectOther' => array(array('field_id' => $field_id))), array('type' => 'setting'));
-}
-
-/**
- * Post-render callback to add javascript functionality
- * @param $content
- * @param $element
- * @return $form
- */
-function cck_select_other_post_render($content, $element) {
- static $js;
-
- if ($element['#type'] <> 'cck_select_other') {
- return $content;
- }
-
- // No matches = not our field.
- $n = preg_match_all("/[A-Za-z0-9\-\_]+/", $element['#name'], $matches);
- if ($n == 0) {
- return $element;
- }
-
- // By any chance if we don't have any array keys, get out of here.
- $keys = isset($matches[0]) ? $matches[0]: NULL;
- if (!isset($keys)) {
- return $element;
- }
-
- foreach ($keys as $key => $val) {
- $keys[$key] = preg_replace("/_/", '-', $val);
- }
- $field_id = implode('-', $keys);
-
- if (!$js) {
- drupal_add_js(drupal_get_path('module', 'cck_select_other') . '/cck_select_other.js');
- $js = TRUE;
- }
- drupal_add_js(array('CCKSelectOther' => array(array('field_id' => $field_id))), array('type' => 'setting'));
-
- return $content;
-}
-
-/**
* Implementation of hook_content_migrate_field_alter().
*/
function cck_select_other_content_migrate_field_alter(&$field_value) {
diff --git a/tests/cck_select_other.test b/tests/cck_select_other.test
index 45d1663..f35ca8a 100644
--- a/tests/cck_select_other.test
+++ b/tests/cck_select_other.test
@@ -1,15 +1,13 @@
t('CCK Select Other Basic Test'),
'description' => t('Test saving values with the CCK Select Other widget.'),
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -207,7 +204,7 @@ class CCKSelectOtherBasicTest extends CCKSelectOtherTest {
$this->drupalLogin($this->web_user);
$this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
- $this->assertNoRaw(t('A non-empty value is required for this option.'), t('Did not fail validation for non-required field.'));
+ $this->assertNoRaw(t('You must provide a value for this option.'), t('Did not fail validation for non-required field.'));
$this->drupalLogout();
@@ -220,7 +217,7 @@ class CCKSelectOtherBasicTest extends CCKSelectOtherTest {
$field_str = str_replace('_', '-', $this->test_field['field_name']);
$this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
- $this->assertRaw(t('A non-empty value is required for this option.'), t('Failed validation for required field.'));
+ $this->assertRaw(t('You must provide a value for this option.'), t('Failed validation for required field.'));
$elements = $this->xpath('//input[@name="' . $text_field .'" and contains(@class, "error")]');
$this->assertEqual(count($elements), 1, t('Found error class on %field element.', array('%field' => $text_field)));
@@ -237,7 +234,7 @@ class CCKSelectOtherHTMLEntitiesTest extends CCKSelectOtherTest {
return array(
'name' => 'CCK Select Other HTML Entities',
'description' => 'Assert HTML entities are not double-encoded.',
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -264,8 +261,8 @@ class CCKSelectOtherHTMLEntitiesTest extends CCKSelectOtherTest {
}
/**
- * @class
- *
+ * Assert that allowed values restrict select other list options in the rare
+ * case that someone decides to use them.
*/
class CCKSelectOtherAllowedValuesTest extends CCKSelectOtherTest {
@@ -273,7 +270,7 @@ class CCKSelectOtherAllowedValuesTest extends CCKSelectOtherTest {
return array(
'name' => t('CCK Select Other Allowed Values Test'),
'description' => t('Confirm that allowed values set on a field restrict the widget.'),
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -322,15 +319,14 @@ class CCKSelectOtherAllowedValuesTest extends CCKSelectOtherTest {
}
/**
- * @class
- * CCK Select Other PHP Options Test
+ * Assert that PHP options work correctly in select other list.
*/
class CCKSelectOtherPHPOptionsTest extends CCKSelectOtherTest {
public static function getInfo() {
return array(
'name' => t('CCK Select Other PHP Options Test'),
'description' => t('Confirm that php options are generated in the select list.'),
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -375,15 +371,15 @@ class CCKSelectOtherPHPOptionsTest extends CCKSelectOtherTest {
}
/**
- * @class
- * CCK Select Other Multiple Fields Test
+ * Assert that select other list is functional when there are multiple select
+ * other fields on a page.
*/
class CCKSelectOtherMultipleFieldsTest extends CCKSelectOtherTest {
public static function getInfo() {
return array(
'name' => t('CCK Select Other Multiple Fields'),
'description' => t('Tests UI when a content type has multiple select other fields.'),
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -449,15 +445,14 @@ class CCKSelectOtherMultipleFieldsTest extends CCKSelectOtherTest {
}
/**
- * @class CCK Select Other Multiple Value List Field Case
- * Tests multiple value list fields where $delta > 1 or -1 (unlimited).
+ * Assert multiple value list fields where $delta > 1 or -1 (unlimited).
*/
class CCKSelectOtherMultipleValueListTest extends CCKSelectOtherTest {
static public function getInfo() {
return array(
'name' => t('CCK Select Other Multiple Values'),
'description' => t('Tests multiple value list field. Where delta is greater than one.'),
- 'group' => t('Field UI'),
+ 'group' => 'Field UI',
);
}
@@ -491,12 +486,12 @@ class CCKSelectOtherMultipleValueListTest extends CCKSelectOtherTest {
$name = substr($this->test_field['field_name'], 6);
$this->drupalGet('node/' . $this->test_node->nid . '/edit');
- $this->assertOptionSelected('edit-field-' . $name . '-und-0-select-other-list', $this->test_instance['default_value'][0]['value'], t('%b', array('%b' => json_encode($this->test_instance['default_value']))));
+ $this->assertOptionSelected('edit-field-' . $name . '-und-0-select-other-list', $this->test_instance['default_value'][0]['value']);
$this->assertOptionSelected('edit-field-' . $name . '-und-1-select-other-list', $this->test_instance['default_value'][0]['value']);
- // Try to post and make sure it saved both values correctly.
- // In unlimited situation, there are two elements by default.
- // We'll try add more later.
+ // Try to post and make sure it saved both values correctly. In unlimited
+ // situation, there are two elements by default. Test add more function
+ // later.
$options_arr = cck_select_other_options($this->test_instance);
do {
$firstoption = array_rand(cck_select_other_options($this->test_instance));
@@ -520,7 +515,7 @@ class CCKSelectOtherMultipleValueListTest extends CCKSelectOtherTest {
}
/**
- * @class CCKSelectOtherNotRequiredTest
+ * Assert that select other list is not saving any values if -none- is selected
*/
class CCKSelectOtherNotRequiredTest extends CCKSelectOtherTest {
@@ -528,7 +523,7 @@ class CCKSelectOtherNotRequiredTest extends CCKSelectOtherTest {
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'),
+ 'group' => 'Field UI',
);
}
@@ -595,3 +590,139 @@ class CCKSelectOtherNotRequiredTest extends CCKSelectOtherTest {
}
}
+
+/**
+ * Assert that select other field widget can be used with non-text fields.
+ *
+ * This is not based on CCKSelectOtherTest case because it's a different field.
+ */
+class CCKSelectOtherNumericFieldTest extends DrupalWebTestCase {
+
+ static public function getInfo() {
+ return array(
+ 'name' => 'CCK Select Other Numeric Field',
+ 'description' => 'Assert that select other widget behaves correctly for non-text fields.',
+ 'group' => 'Field UI',
+ );
+ }
+
+ public function setUp() {
+ parent::setUp(array('cck_select_other'));
+
+ $this->assertTrue(module_exists('cck_select_other'), t('CCK Select Other module is enabled.'));
+
+ $content_type = strtolower($this->randomName(5));
+
+ /* Setup an admin user */
+ $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer site configuration'));
+ $this->drupalLogin($this->admin_user);
+
+ /* Create a new content type */
+ $settings = array(
+ 'type' => $content_type,
+ );
+ $this->contentType = $this->drupalCreateContentType($settings);
+
+ /* Create some options for our select other list */
+ $this->options = "1\n2\n3\n4\n5\nother|Other";
+
+ /* Create a new field on our content type */
+ $field_label = $this->randomName(5);
+ $field_name = strtolower($this->randomName(5));
+ $bundle_path = 'admin/structure/types/manage/' . $this->contentType->type;
+ $edit = array(
+ 'fields[_add_new_field][label]' => $field_label,
+ 'fields[_add_new_field][field_name]' => $field_name,
+ 'fields[_add_new_field][type]' => 'list_integer',
+ 'fields[_add_new_field][widget_type]' => 'cck_select_other',
+ );
+ $this->drupalPost($bundle_path . '/fields', $edit, 'Save');
+ $edit = array(
+ 'instance[required]' => TRUE,
+ 'instance[widget][settings][select_list_options]' => $this->options,
+ 'field_' . $field_name . '[und][0][select_other_list]' => '_none',
+ );
+ $this->drupalPost($bundle_path . '/fields/field_' . $field_name, $edit, 'Save settings');
+ $this->drupalGet($bundle_path . '/fields/field_' . $field_name);
+
+ $this->test_field = field_info_field('field_' . $field_name);
+ $this->test_instance = field_info_instance('node', 'field_' . $field_name, $this->contentType->type);
+
+ /* Setup a web user that can create content */
+ // @todo bypass node access seems to be the only thing that does not return 403
+ $this->web_user = $this->drupalCreateUser(array('access content', 'create ' . $this->contentType->type . ' content', 'delete any ' . $this->contentType->type . ' content', 'bypass node access'));
+
+ $this->drupalLogout();
+
+ $this->drupalLogin($this->web_user);
+
+ $settings = array(
+ 'type' => $this->contentType->type,
+ );
+ $this->test_node = $this->drupalCreateNode($settings);
+
+ $this->drupalLogout();
+
+ $options_arr = cck_select_other_options($this->test_instance);
+ $this->assertEqual(7, count($options_arr), t('There are 6 = %count options set on the field.', array('%count' => count($options_arr))));
+ }
+
+ /**
+ * Implementation of tearDown() method
+ */
+ public function tearDown() {
+ $this->drupalLogin($this->web_user);
+ $this->drupalPost('node/' . $this->test_node->nid . '/delete', array('confirm' => 1), 'Delete');
+ $this->drupalLogout();
+
+ $this->drupalLogin($this->admin_user);
+ field_delete_field($this->test_field['field_name']);
+ $this->drupalLogout();
+
+ $this->test_node = NULL;
+ $this->test_field = NULL;
+ $this->test_instance = NULL;
+ $this->admin_user = NULL;
+ $this->web_user = NULL;
+ $this->options = NULL;
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test numeric field CRUD.
+ */
+ public function testSelectOtherList() {
+ $this->drupalLogin($this->web_user);
+
+ // Save a regular field value.
+ $value = rand(1, 5);
+
+ $select_field = $this->test_field['field_name'] . '[und][0][select_other_list]';
+ $text_field = $this->test_field['field_name'] . '[und][0][select_other_text_input]';
+ $edit = array(
+ $select_field => $value,
+ );
+
+ $this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
+ $this->test_node = node_load($this->test_node->nid, NULL, TRUE);
+ $this->assertRaw($this->test_node->{$this->test_field['field_name']}['und'][0]['value'], t('Select other field data %field matches %match on node.', array('%field' => $this->test_node->{$this->test_field['field_name']}['und'][0]['value'], '%match' => $value)));
+
+
+ // Save an other value as an integer.
+ $value = rand(50, 1000);
+ $edit[$select_field] = 'other';
+ $edit[$text_field] = $value;
+
+ $this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
+ $this->test_node = node_load($this->test_node->nid, NULL, TRUE);
+ $this->assertRaw($this->test_node->{$this->test_field['field_name']}['und'][0]['value'], t('Select other field data %field matches %match on node.', array('%field' => $this->test_node->{$this->test_field['field_name']}['und'][0]['value'], '%match' => $value)));
+
+ // Attempt to save an other value that is non-integer.
+ $value = $this->randomName(10);
+ $edit[$text_field] = $value;
+ $this->drupalPost('node/' . $this->test_node->nid . '/edit', $edit, t('Save'));
+ $this->assertText('Only integers are allowed', t('Select other field did not save an illegal value.'));
+ }
+
+}