Commit 0d74d52c authored by Dries's avatar Dries

- Patch #915936 by sun: make it easier to define checkboxes/radios with customized sub-elements.

parent d3852cd3
......@@ -2786,22 +2786,28 @@ function weight_value(&$form) {
*/
function form_process_radios($element) {
if (count($element['#options']) > 0) {
$weight = 0;
foreach ($element['#options'] as $key => $choice) {
if (!isset($element[$key])) {
// Generate the parents as the autogenerator does, so we will have a
// unique id for each radio button.
$parents_for_id = array_merge($element['#parents'], array($key));
$element[$key] = array(
'#type' => 'radio',
'#title' => $choice,
'#return_value' => check_plain($key),
'#default_value' => isset($element['#default_value']) ? $element['#default_value'] : NULL,
'#attributes' => $element['#attributes'],
'#parents' => $element['#parents'],
'#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
);
}
// Maintain order of options as defined in #options, in case the element
// defines custom option sub-elements, but does not define all option
// sub-elements.
$weight += 0.001;
$element += array($key => array());
// Generate the parents as the autogenerator does, so we will have a
// unique id for each radio button.
$parents_for_id = array_merge($element['#parents'], array($key));
$element[$key] += array(
'#type' => 'radio',
'#title' => $choice,
'#return_value' => check_plain($key),
'#default_value' => isset($element['#default_value']) ? $element['#default_value'] : NULL,
'#attributes' => $element['#attributes'],
'#parents' => $element['#parents'],
'#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
'#weight' => $weight,
);
}
}
return $element;
......@@ -2911,25 +2917,30 @@ function form_process_checkboxes($element) {
if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
$element['#default_value'] = array();
}
$weight = 0;
foreach ($element['#options'] as $key => $choice) {
if (!isset($element[$key])) {
// Integer 0 is not a valid #return_value, so use '0' instead.
// @see form_type_checkbox_value().
// @todo For Drupal 8, cast all integer keys to strings for consistency
// with form_process_radios().
if ($key === 0) {
$key = '0';
}
$element[$key] = array(
'#type' => 'checkbox',
'#processed' => TRUE,
'#title' => $choice,
'#return_value' => $key,
'#default_value' => isset($value[$key]) ? $key : NULL,
'#attributes' => $element['#attributes'],
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
);
// Integer 0 is not a valid #return_value, so use '0' instead.
// @see form_type_checkbox_value().
// @todo For Drupal 8, cast all integer keys to strings for consistency
// with form_process_radios().
if ($key === 0) {
$key = '0';
}
// Maintain order of options as defined in #options, in case the element
// defines custom option sub-elements, but does not define all option
// sub-elements.
$weight += 0.001;
$element += array($key => array());
$element[$key] += array(
'#type' => 'checkbox',
'#title' => $choice,
'#return_value' => $key,
'#default_value' => isset($value[$key]) ? $key : NULL,
'#attributes' => $element['#attributes'],
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
'#weight' => $weight,
);
}
}
return $element;
......
......@@ -1190,28 +1190,13 @@ function comment_form_node_form_alter(&$form, $form_state) {
COMMENT_NODE_HIDDEN => t('Hidden'),
),
COMMENT_NODE_OPEN => array(
'#type' => 'radio',
'#title' => t('Open'),
'#description' => t('Users with the "Post comments" permission can post comments.'),
'#return_value' => COMMENT_NODE_OPEN,
'#default_value' => $comment_settings,
'#parents' => array('comment'),
),
COMMENT_NODE_CLOSED => array(
'#type' => 'radio',
'#title' => t('Closed'),
'#description' => t('Users cannot post comments, but existing comments will be displayed.'),
'#return_value' => COMMENT_NODE_CLOSED,
'#default_value' => $comment_settings,
'#parents' => array('comment'),
),
COMMENT_NODE_HIDDEN => array(
'#type' => 'radio',
'#title' => t('Hidden'),
'#description' => t('Comments are hidden from view.'),
'#return_value' => COMMENT_NODE_HIDDEN,
'#default_value' => $comment_settings,
'#parents' => array('comment'),
),
);
// If the node doesn't have any comments, the "hidden" option makes no
......
......@@ -369,6 +369,66 @@ class FormsTestCase extends DrupalWebTestCase {
}
}
/**
* Tests building and processing of core form elements.
*/
class FormElementTestCase extends DrupalWebTestCase {
protected $profile = 'testing';
public static function getInfo() {
return array(
'name' => 'Element processing',
'description' => 'Tests building and processing of core form elements.',
'group' => 'Form API',
);
}
function setUp() {
parent::setUp(array('form_test'));
}
/**
* Tests expansion of #options for #type checkboxes and radios.
*/
function testOptions() {
$this->drupalGet('form-test/checkboxes-radios');
// Verify that all options appear in their defined order.
foreach (array('checkbox', 'radio') as $type) {
$elements = $this->xpath('//input[@type=:type]', array(':type' => $type));
$expected_values = array('0', 'foo', '1', 'bar');
foreach ($elements as $element) {
$expected = array_shift($expected_values);
$this->assertIdentical((string) $element['value'], $expected);
}
}
// Enable customized option sub-elements.
$this->drupalGet('form-test/checkboxes-radios/customize');
// Verify that all options appear in their defined order, taking a custom
// #weight into account.
foreach (array('checkbox', 'radio') as $type) {
$elements = $this->xpath('//input[@type=:type]', array(':type' => $type));
$expected_values = array('0', 'foo', 'bar', '1');
foreach ($elements as $element) {
$expected = array_shift($expected_values);
$this->assertIdentical((string) $element['value'], $expected);
}
}
// Verify that custom #description properties are output.
foreach (array('checkboxes', 'radios') as $type) {
$elements = $this->xpath('//input[@name=:name]/following-sibling::div[@class=:class]', array(
':name' => $type . '[foo]',
':class' => 'description',
));
$this->assertTrue(count($elements), t('Custom %type option description found.', array(
'%type' => $type,
)));
}
}
}
/**
* Test form alter hooks.
*/
......
......@@ -98,6 +98,12 @@ function form_test_menu() {
'page arguments' => array('form_test_select'),
'access callback' => TRUE,
);
$items['form-test/checkboxes-radios'] = array(
'title' => t('Checkboxes, Radios'),
'page callback' => 'drupal_get_form',
'page arguments' => array('form_test_checkboxes_radios'),
'access callback' => TRUE,
);
$items['form-test/disabled-elements'] = array(
'title' => t('Form test'),
......@@ -186,6 +192,14 @@ function form_test_menu() {
return $items;
}
/**
* Form submit handler to return form values as JSON.
*/
function _form_test_submit_values_json($form, &$form_state) {
drupal_json_output($form_state['values']);
drupal_exit();
}
/**
* Form builder for testing hook_form_alter() and hook_form_FORM_ID_alter().
*/
......@@ -892,6 +906,63 @@ function form_test_select_submit($form, &$form_state) {
exit();
}
/**
* Form constructor to test expansion of #type checkboxes and radios.
*/
function form_test_checkboxes_radios($form, &$form_state, $customize = FALSE) {
$form['#submit'] = array('_form_test_submit_values_json');
// Expand #type checkboxes, setting custom element properties for some but not
// all options.
$form['checkboxes'] = array(
'#type' => 'checkboxes',
'#title' => 'Checkboxes',
'#options' => array(
0 => 'Zero',
'foo' => 'Foo',
1 => 'One',
'bar' => 'Bar',
),
);
if ($customize) {
$form['checkboxes'] += array(
'foo' => array(
'#description' => 'Enable to foo.',
),
1 => array(
'#weight' => 10,
),
);
}
// Expand #type radios, setting custom element properties for some but not
// all options.
$form['radios'] = array(
'#type' => 'radios',
'#title' => 'Radios',
'#options' => array(
0 => 'Zero',
'foo' => 'Foo',
1 => 'One',
'bar' => 'Bar',
),
);
if ($customize) {
$form['radios'] += array(
'foo' => array(
'#description' => 'Enable to foo.',
),
1 => array(
'#weight' => 10,
),
);
}
$form['submit'] = array('#type' => 'submit', '#value' => 'Submit');
return $form;
}
/**
* Build a form to test disabled elements.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment