diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/field/modules/options/options.module | 32 | ||||
-rw-r--r-- | modules/field/modules/options/options.test | 11 | ||||
-rw-r--r-- | modules/simpletest/tests/form.test | 81 | ||||
-rw-r--r-- | modules/simpletest/tests/form_test.module | 48 | ||||
-rw-r--r-- | modules/system/system.module | 2 |
5 files changed, 134 insertions, 40 deletions
diff --git a/modules/field/modules/options/options.module b/modules/field/modules/options/options.module index 75683a9fb..e536c08c6 100644 --- a/modules/field/modules/options/options.module +++ b/modules/field/modules/options/options.module @@ -152,7 +152,6 @@ function options_field_widget_validate($element, &$form_state) { */ function _options_properties($type, $multiple, $required, $has_value) { $base = array( - 'zero_placeholder' => FALSE, 'filter_xss' => FALSE, 'strip_tags' => FALSE, 'empty_option' => FALSE, @@ -190,9 +189,6 @@ function _options_properties($type, $multiple, $required, $has_value) { case 'buttons': $properties = array( 'filter_xss' => TRUE, - // Form API 'checkboxes' do not suport 0 as an option, so we replace it with - // a placeholder within the form workflow. - 'zero_placeholder' => $multiple, ); // Add a 'none' option for non-required radio buttons. if (!$required && !$multiple) { @@ -238,18 +234,6 @@ function _options_get_options($field, $instance, $properties) { * The function is recursive to support optgroups. */ function _options_prepare_options(&$options, $properties) { - // Substitute the '_0' placeholder. - if ($properties['zero_placeholder']) { - $values = array_keys($options); - $labels = array_values($options); - // Use a strict comparison, because 0 == 'any string'. - $index = array_search(0, $values, TRUE); - if ($index !== FALSE && !is_array($options[$index])) { - $values[$index] = '_0'; - $options = array_combine($values, $labels); - } - } - foreach ($options as $value => $label) { // Recurse for optgroups. if (is_array($label)) { @@ -273,14 +257,6 @@ function _options_storage_to_form($items, $options, $column, $properties) { $items_transposed = options_array_transpose($items); $values = (isset($items_transposed[$column]) && is_array($items_transposed[$column])) ? $items_transposed[$column] : array(); - // Substitute the '_0' placeholder. - if ($properties['zero_placeholder']) { - $index = array_search('0', $values); - if ($index !== FALSE) { - $values[$index] = '_0'; - } - } - // Discard values that are not in the current list of options. Flatten the // array if needed. if ($properties['optgroups']) { @@ -302,14 +278,6 @@ function _options_form_to_storage($element) { $values = array($values[0] ? $element['#on_value'] : $element['#off_value']); } - // Substitute the '_0' placeholder. - if ($properties['zero_placeholder']) { - $index = array_search('_0', $values); - if ($index !== FALSE) { - $values[$index] = 0; - } - } - // Filter out the 'none' option. Use a strict comparison, because // 0 == 'any string'. if ($properties['empty_option']) { diff --git a/modules/field/modules/options/options.test b/modules/field/modules/options/options.test index cd85e6579..110ab5767 100644 --- a/modules/field/modules/options/options.test +++ b/modules/field/modules/options/options.test @@ -112,9 +112,6 @@ class OptionsWidgetsTestCase extends FieldTestCase { * Tests the 'options_buttons' widget (multiple select). */ function testCheckBoxes() { - // Checkboxes do not support '0' as an option, the widget internally - // replaces it with '_0'. - // Create an instance of the 'multiple values' field. $instance = array( 'field_name' => $this->card_2['field_name'], @@ -142,7 +139,7 @@ class OptionsWidgetsTestCase extends FieldTestCase { // Submit form: select first and third options. $edit = array( - "card_2[$langcode][_0]" => TRUE, + "card_2[$langcode][0]" => TRUE, "card_2[$langcode][1]" => FALSE, "card_2[$langcode][2]" => TRUE, ); @@ -157,7 +154,7 @@ class OptionsWidgetsTestCase extends FieldTestCase { // Submit form: select only first option. $edit = array( - "card_2[$langcode][_0]" => TRUE, + "card_2[$langcode][0]" => TRUE, "card_2[$langcode][1]" => FALSE, "card_2[$langcode][2]" => FALSE, ); @@ -172,7 +169,7 @@ class OptionsWidgetsTestCase extends FieldTestCase { // Submit form: select the three options while the field accepts only 2. $edit = array( - "card_2[$langcode][_0]" => TRUE, + "card_2[$langcode][0]" => TRUE, "card_2[$langcode][1]" => TRUE, "card_2[$langcode][2]" => TRUE, ); @@ -181,7 +178,7 @@ class OptionsWidgetsTestCase extends FieldTestCase { // Submit form: uncheck all options. $edit = array( - "card_2[$langcode][_0]" => FALSE, + "card_2[$langcode][0]" => FALSE, "card_2[$langcode][1]" => FALSE, "card_2[$langcode][2]" => FALSE, ); diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index 4661ad25f..1f76318f5 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -1352,3 +1352,84 @@ class FormsFileInclusionTestCase extends DrupalWebTestCase { $this->assertText('Submit callback called.'); } } + +/** + * Tests checkbox element. + */ +class FormCheckboxTestCase extends DrupalWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Form API checkbox', + 'description' => 'Tests form API checkbox handling of various combinations of #default_value and #return_value.', + 'group' => 'Form API', + ); + } + + function setUp() { + parent::setUp('form_test'); + } + + function testFormCheckbox() { + // Ensure that the checked state is determined and rendered correctly for + // tricky combinations of default and return values. + foreach (array(FALSE, NULL, TRUE, 0, '0', '', 1, '1', 'foobar', '1foobar') as $default_value) { + // Only values that can be used for array indeces are supported for + // #return_value, with the exception of integer 0, which is not supported. + // @see form_process_checkbox(). + foreach (array('0', '', 1, '1', 'foobar', '1foobar') as $return_value) { + $form_array = drupal_get_form('form_test_checkbox_type_juggling', $default_value, $return_value); + $form = drupal_render($form_array); + if ($default_value === TRUE) { + $checked = TRUE; + } + elseif ($return_value === '0') { + $checked = ($default_value === '0'); + } + elseif ($return_value === '') { + $checked = ($default_value === ''); + } + elseif ($return_value === 1 || $return_value === '1') { + $checked = ($default_value === 1 || $default_value === '1'); + } + elseif ($return_value === 'foobar') { + $checked = ($default_value === 'foobar'); + } + elseif ($return_value === '1foobar') { + $checked = ($default_value === '1foobar'); + } + $checked_in_html = strpos($form, 'checked') !== FALSE; + $message = t('#default_value is %default_value #return_value is %return_value.', array('%default_value' => var_export($default_value, TRUE), '%return_value' => var_export($return_value, TRUE))); + $this->assertIdentical($checked, $checked_in_html, $message); + } + } + + // Ensure that $form_state['values'] is populated correctly for a checkboxes + // group that includes a 0-indexed array of options. + $results = json_decode($this->drupalPost('form-test/checkboxes-zero', array(), 'Save')); + $this->assertIdentical($results->checkbox_off, array(0, 0, 0), t('All three in checkbox_off are zeroes: off.')); + $this->assertIdentical($results->checkbox_zero_default, array('0', 0, 0), t('The first choice is on in checkbox_zero_default')); + $this->assertIdentical($results->checkbox_string_zero_default, array('0', 0, 0), t('The first choice is on in checkbox_string_zero_default')); + $edit = array('checkbox_off[0]' => '0'); + $results = json_decode($this->drupalPost('form-test/checkboxes-zero', $edit, 'Save')); + $this->assertIdentical($results->checkbox_off, array('0', 0, 0), t('The first choice is on in checkbox_off but the rest is not')); + + // Ensure that each checkbox is rendered correctly for a checkboxes group + // that includes a 0-indexed array of options. + $this->drupalPost('form-test/checkboxes-zero/0', array(), 'Save'); + $checkboxes = $this->xpath('//input[@type="checkbox"]'); + foreach ($checkboxes as $checkbox) { + $checked = isset($checkbox['checked']); + $name = (string) $checkbox['name']; + $this->assertIdentical($checked, $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', t('Checkbox %name correctly checked', array('%name' => $name))); + } + $edit = array('checkbox_off[0]' => '0'); + $this->drupalPost('form-test/checkboxes-zero/0', $edit, 'Save'); + $checkboxes = $this->xpath('//input[@type="checkbox"]'); + foreach ($checkboxes as $checkbox) { + $checked = isset($checkbox['checked']); + $name = (string) $checkbox['name']; + $this->assertIdentical($checked, $name == 'checkbox_off[0]' || $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', t('Checkbox %name correctly checked', array('%name' => $name))); + } + } +} diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index fbeb6de45..4d717c04b 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -175,6 +175,13 @@ function form_test_menu() { 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); + $items['form-test/checkboxes-zero'] = array( + 'title' => 'FAPI test involving checkboxes and zero', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_checkboxes_zero'), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); return $items; } @@ -1395,3 +1402,44 @@ function form_test_load_include_custom($form, &$form_state) { $form_state['cache'] = TRUE; return $form; } + +function form_test_checkbox_type_juggling($form, $form_state, $default_value, $return_value) { + $form['checkbox'] = array( + '#type' => 'checkbox', + '#return_value' => $return_value, + '#default_value' => $default_value, + ); + return $form; +} + +function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) { + $form['checkbox_off'] = array( + '#type' => 'checkboxes', + '#options' => array('foo', 'bar', 'baz'), + ); + $form['checkbox_zero_default'] = array( + '#type' => 'checkboxes', + '#options' => array('foo', 'bar', 'baz'), + '#default_value' => array(0), + ); + $form['checkbox_string_zero_default'] = array( + '#type' => 'checkboxes', + '#options' => array('foo', 'bar', 'baz'), + '#default_value' => array('0'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + if ($json) { + $form['#submit'][] = '_form_test_checkbox_submit'; + } + else { + $form['#submit'][] = '_form_test_checkboxes_zero_no_redirect'; + } + return $form; +} + +function _form_test_checkboxes_zero_no_redirect($form, &$form_state) { + $form_state['redirect'] = FALSE; +} diff --git a/modules/system/system.module b/modules/system/system.module index d450eadc5..296c06714 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -408,8 +408,8 @@ function system_element_info() { $types['checkbox'] = array( '#input' => TRUE, '#return_value' => 1, - '#process' => array('ajax_process_form'), '#theme' => 'checkbox', + '#process' => array('form_process_checkbox', 'ajax_process_form'), '#theme_wrappers' => array('form_element'), '#title_display' => 'after', ); |