Loading core/lib/Drupal/Core/Render/Element/Tableselect.php +9 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,9 @@ * $options = [ * 1 => ['color' => 'Red', 'shape' => 'Triangle'], * 2 => ['color' => 'Green', 'shape' => 'Square'], * 3 => ['color' => 'Blue', 'shape' => 'Hexagon'], * // Prevent users from selecting a row by adding a '#disabled' property set * // to TRUE. * 3 => ['color' => 'Blue', 'shape' => 'Hexagon', '#disabled' => TRUE], * ]; * * $form['table'] = array( Loading Loading @@ -180,6 +182,9 @@ public static function preRenderTableselect($element) { } } } if (!empty($element['#options'][$key]['#disabled'])) { $row['class'][] = 'disabled'; } $rows[] = $row; } // Add an empty header or a "Select all" checkbox to provide room for the Loading Loading @@ -238,6 +243,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st foreach ($element['#options'] as $key => $choice) { // Do not overwrite manually created children. if (!isset($element[$key])) { $disabled = !empty($element['#options'][$key]['#disabled']); if ($element['#multiple']) { $title = ''; if (isset($element['#options'][$key]['title']) && is_array($element['#options'][$key]['title'])) { Loading @@ -254,6 +260,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st '#return_value' => $key, '#default_value' => isset($value[$key]) ? $key : NULL, '#attributes' => $element['#attributes'], '#disabled' => $disabled, '#ajax' => $element['#ajax'] ?? NULL, ]; } Loading @@ -269,6 +276,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#id' => HtmlUtility::getUniqueId('edit-' . implode('-', $parents_for_id)), '#disabled' => $disabled, '#ajax' => $element['#ajax'] ?? NULL, ]; } Loading core/modules/system/tests/modules/form_test/form_test.routing.yml +8 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,14 @@ form_test.tableselect_js: requirements: _access: 'TRUE' form_test.tableselect_disabled_rows: path: '/form_test/tableselect/disabled-rows/{test_action}' defaults: _form: '\Drupal\form_test\Form\FormTestTableSelectDisabledRowsForm' _title: 'Tableselect disabled rows tests' requirements: _access: 'TRUE' form_test.vertical_tabs: path: '/form_test/vertical-tabs' defaults: Loading core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectDisabledRowsForm.php 0 → 100644 +44 −0 Original line number Diff line number Diff line <?php namespace Drupal\form_test\Form; use Drupal\Core\Form\FormStateInterface; /** * Builds a form to test table select with disabled rows. * * @internal */ class FormTestTableSelectDisabledRowsForm extends FormTestTableSelectFormBase { /** * {@inheritdoc} */ public function getFormId() { return '_form_test_tableselect_disabled_rows_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $test_action = NULL) { $multiple = ['multiple-true' => TRUE, 'multiple-false' => FALSE][$test_action]; $form = $this->tableselectFormBuilder($form, $form_state, [ '#multiple' => $multiple, '#js_select' => TRUE, '#ajax' => NULL, ]); // Disable the second row. $form['tableselect']['#options']['row2']['#disabled'] = TRUE; return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { } } core/modules/system/tests/src/FunctionalJavascript/Form/ElementsTableSelectTest.php +48 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,52 @@ public function testAjax() { } } /** * Tests table select with disabled rows. */ public function testDisabledRows() { // Asserts that a row number (1 based) is enabled. $assert_row_enabled = function ($delta) { $row = $this->assertSession()->elementExists('xpath', "//table/tbody/tr[$delta]"); $this->assertFalse($row->hasClass('disabled')); $input = $row->find('css', 'input[value="row' . $delta . '"]'); $this->assertFalse($input->hasAttribute('disabled')); }; // Asserts that a row number (1 based) is disabled. $assert_row_disabled = function ($delta) { $row = $this->assertSession()->elementExists('xpath', "//table/tbody/tr[$delta]"); $this->assertTrue($row->hasClass('disabled')); $input = $row->find('css', 'input[value="row' . $delta . '"]'); $this->assertTrue($input->hasAttribute('disabled')); $this->assertEquals('disabled', $input->getAttribute('disabled')); }; // Test radios (#multiple == FALSE). $this->drupalGet('form_test/tableselect/disabled-rows/multiple-false'); // Check that only 'row2' is disabled. $assert_row_enabled(1); $assert_row_disabled(2); $assert_row_enabled(3); // Test checkboxes (#multiple == TRUE). $this->drupalGet('form_test/tableselect/disabled-rows/multiple-true'); // Check that only 'row2' is disabled. $assert_row_enabled(1); $assert_row_disabled(2); $assert_row_enabled(3); // Table select with checkboxes allow selection of all options. $select_all_checkbox = $this->assertSession()->elementExists('xpath', '//table/thead/tr/th/input'); $select_all_checkbox->check(); // Check that the disabled option was not enabled or selected. $page = $this->getSession()->getPage(); $page->hasCheckedField('row1'); $page->hasUncheckedField('row2'); $assert_row_disabled(2); $page->hasCheckedField('row3'); } } Loading
core/lib/Drupal/Core/Render/Element/Tableselect.php +9 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,9 @@ * $options = [ * 1 => ['color' => 'Red', 'shape' => 'Triangle'], * 2 => ['color' => 'Green', 'shape' => 'Square'], * 3 => ['color' => 'Blue', 'shape' => 'Hexagon'], * // Prevent users from selecting a row by adding a '#disabled' property set * // to TRUE. * 3 => ['color' => 'Blue', 'shape' => 'Hexagon', '#disabled' => TRUE], * ]; * * $form['table'] = array( Loading Loading @@ -180,6 +182,9 @@ public static function preRenderTableselect($element) { } } } if (!empty($element['#options'][$key]['#disabled'])) { $row['class'][] = 'disabled'; } $rows[] = $row; } // Add an empty header or a "Select all" checkbox to provide room for the Loading Loading @@ -238,6 +243,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st foreach ($element['#options'] as $key => $choice) { // Do not overwrite manually created children. if (!isset($element[$key])) { $disabled = !empty($element['#options'][$key]['#disabled']); if ($element['#multiple']) { $title = ''; if (isset($element['#options'][$key]['title']) && is_array($element['#options'][$key]['title'])) { Loading @@ -254,6 +260,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st '#return_value' => $key, '#default_value' => isset($value[$key]) ? $key : NULL, '#attributes' => $element['#attributes'], '#disabled' => $disabled, '#ajax' => $element['#ajax'] ?? NULL, ]; } Loading @@ -269,6 +276,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#id' => HtmlUtility::getUniqueId('edit-' . implode('-', $parents_for_id)), '#disabled' => $disabled, '#ajax' => $element['#ajax'] ?? NULL, ]; } Loading
core/modules/system/tests/modules/form_test/form_test.routing.yml +8 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,14 @@ form_test.tableselect_js: requirements: _access: 'TRUE' form_test.tableselect_disabled_rows: path: '/form_test/tableselect/disabled-rows/{test_action}' defaults: _form: '\Drupal\form_test\Form\FormTestTableSelectDisabledRowsForm' _title: 'Tableselect disabled rows tests' requirements: _access: 'TRUE' form_test.vertical_tabs: path: '/form_test/vertical-tabs' defaults: Loading
core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectDisabledRowsForm.php 0 → 100644 +44 −0 Original line number Diff line number Diff line <?php namespace Drupal\form_test\Form; use Drupal\Core\Form\FormStateInterface; /** * Builds a form to test table select with disabled rows. * * @internal */ class FormTestTableSelectDisabledRowsForm extends FormTestTableSelectFormBase { /** * {@inheritdoc} */ public function getFormId() { return '_form_test_tableselect_disabled_rows_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $test_action = NULL) { $multiple = ['multiple-true' => TRUE, 'multiple-false' => FALSE][$test_action]; $form = $this->tableselectFormBuilder($form, $form_state, [ '#multiple' => $multiple, '#js_select' => TRUE, '#ajax' => NULL, ]); // Disable the second row. $form['tableselect']['#options']['row2']['#disabled'] = TRUE; return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { } }
core/modules/system/tests/src/FunctionalJavascript/Form/ElementsTableSelectTest.php +48 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,52 @@ public function testAjax() { } } /** * Tests table select with disabled rows. */ public function testDisabledRows() { // Asserts that a row number (1 based) is enabled. $assert_row_enabled = function ($delta) { $row = $this->assertSession()->elementExists('xpath', "//table/tbody/tr[$delta]"); $this->assertFalse($row->hasClass('disabled')); $input = $row->find('css', 'input[value="row' . $delta . '"]'); $this->assertFalse($input->hasAttribute('disabled')); }; // Asserts that a row number (1 based) is disabled. $assert_row_disabled = function ($delta) { $row = $this->assertSession()->elementExists('xpath', "//table/tbody/tr[$delta]"); $this->assertTrue($row->hasClass('disabled')); $input = $row->find('css', 'input[value="row' . $delta . '"]'); $this->assertTrue($input->hasAttribute('disabled')); $this->assertEquals('disabled', $input->getAttribute('disabled')); }; // Test radios (#multiple == FALSE). $this->drupalGet('form_test/tableselect/disabled-rows/multiple-false'); // Check that only 'row2' is disabled. $assert_row_enabled(1); $assert_row_disabled(2); $assert_row_enabled(3); // Test checkboxes (#multiple == TRUE). $this->drupalGet('form_test/tableselect/disabled-rows/multiple-true'); // Check that only 'row2' is disabled. $assert_row_enabled(1); $assert_row_disabled(2); $assert_row_enabled(3); // Table select with checkboxes allow selection of all options. $select_all_checkbox = $this->assertSession()->elementExists('xpath', '//table/thead/tr/th/input'); $select_all_checkbox->check(); // Check that the disabled option was not enabled or selected. $page = $this->getSession()->getPage(); $page->hasCheckedField('row1'); $page->hasUncheckedField('row2'); $assert_row_disabled(2); $page->hasCheckedField('row3'); } }