Problem/Motivation

Form element "checkboxes" with "required" fails the $is_empty_value validation, if all selected options are disabled.

Steps to reproduce

1. Get the default Drupal instance with "Article" node bundle and field_tags field.
Create two tags (Tag1, Tag2), create an article and add the "Tag1" to it (only one tag).

2. Mark the field_tags field as "required" in field settings.

3. Change for the field_tags field the widget type to "Check boxes/radio buttons".

4. Open the Article edit form, see that the "Tag1" checkbox is checked. Submit the form - it should be submitted successfully.

5. Make the "Tag1" checkbox disabled in the Article edit form via custom hook:

function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if($form_id !== 'node_article_edit_form') {
    return;
  }
  $form['field_tags']['widget'][1]['#disabled'] = TRUE;
}

6. Open the Article edit form again. See the "Tag1" checkbox checked and disabled.

7. Press the "Save" button and see the error message "Tags field is required".
But the "Tag1" value is selected (regardless of disabled status), so the field is not empty!

8. Check the non-disabled "Tag2" checkbox and save - validation should be passed well.

So in the step 7 - Drupal shouldn't show the required error, because the "Tag1" value is selected, regardless of disabled status.

Proposed resolution

In the function Drupal\Core\Render\Element\Checkboxes::valueCallback() fill actual values from default values even if the user input is empty:

    else {
      $value = [];

      // Because the disabled checkboxes don't receive their input from the
      // form submission, we should fill their default value.
      if (!empty($element['#default_value'])) {
        foreach ($element['#default_value'] as $key) {
          if (!empty($element[$key]['#disabled'])) {
            $value[$key] = $key;
          }
        }
      }
      
      return $value;
    }

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork drupal-3293609

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Murz created an issue. See original summary.

murz’s picture

Issue summary: View changes

murz’s picture

Attaching a static patch file with those changes, to make it possible to use in composer until #3204538: GitLab Merge Requests Unable to Generate Incremental Patch Files is resolved.

cilefen’s picture

Status: Active » Needs review
smustgrave’s picture

Issue tags: +Bug Smash Initiative
StatusFileSize
new2.93 KB
new3.79 KB

Added some tests.

Status: Needs review » Needs work

The last submitted patch, 6: 3293609-6.patch, failed testing. View results

smustgrave’s picture

Status: Needs work » Needs review
StatusFileSize
new2.94 KB
new3.79 KB

Would help if I uploaded the right patch.

The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing. View results

abhijith s’s picture

StatusFileSize
new267.05 KB
new414.82 KB

Applied patch #8 on 9.5.x and it works fine.Attaching screen recordings for reference.

Manibharathi E R’s picture

StatusFileSize
new258.07 KB
new48.72 KB

Patch #8 applied successfully on Drupal 9.5.x.

Steps to Reproduce:
1. Install the New Drupal Instance
2. Go to the Structure->content->article->manage fields
3. Mark the "Required fields" in the field_tags settings.
4. Go to the Structure->content->Article->manage form display
5. Change the widget settings of the Tags field Auto select to Radio Button/ checkboxes
6. Create one Article content.
7. Make the "Tag1" checkbox disabled in the Article edit form via custom hook:

function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if($form_id !== 'node_article_edit_form') {
return;
}
$form['field_tags']['widget'][1]['#disabled'] = TRUE;
}
8. Then Try to edit the Article content. You can able to reproduce the issue.

Test results:
After adding the Patch can able to edit the Article content.

smustgrave’s picture

If you feel it works please review the code and move to RTBC

ameymudras’s picture

Status: Needs review » Reviewed & tested by the community

Tested the patch #8 with Drupal 9.5 and php 8.1

- The issue summary is clear and provides steps to reproduce
- The patch applies cleanly
- The tests pass and test only patch has been provided
- As tested in #11 the patch fixes the issue
- The code looks good to me

Marking as RTBC for now

The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing. View results

The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing. View results

The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing. View results

The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing. View results

murz’s picture

StatusFileSize
new937 bytes

Re-attaching the fixing patch file, to make it last and disable "The last submitted patch, 8: 3293609-8-tests-only.patch, failed testing" messages.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 18: 3293609-14.patch, failed testing. View results

murz’s picture

Status: Needs work » Needs review

All tests are passed after requiring a retest, so moving to "Needs review".

murz’s picture

Status: Needs review » Reviewed & tested by the community

And even reverting back "Reviewed & tested by the community", because nothing is changed.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

The latest patch on the issue doesn't have the tests from #8 - we definitely should have them.

+++ b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php
@@ -257,6 +264,23 @@ public function testCheckBoxes() {
+    $this->submitForm([], 'Save');
+    $this->assertSession()->pageTextNotContains('Error message');

We should be testing for something positive. Rather than page not containing something. Like some text that appears when you do the save. We should also test the value of the field.

smustgrave’s picture

Status: Needs work » Needs review
StatusFileSize
new785 bytes
new3.89 KB

Updated test case and added them back.

asha nair’s picture

StatusFileSize
new2.64 MB
new1.89 MB

Applied patch in #23 on d.5.x-dev successfully. Adding screen recording for reference

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ghost of drupal past’s picture

Thanks for working on this.

I have two concerns here

  1. Why is Checkboxes being patched instead of Checkbox? I am ready to admit I do not fully understand what goes pear shaped here but Checkbox::processCheckbox has a comment "for checkboxes with #access=FALSE or #disabled=TRUE, the #value is #default_value" which seems rather relevant. Why does this not fire?
  2. Why is the test on a field instead of something directly on forms?
gaurav-mathur’s picture

StatusFileSize
new20.11 KB
new15.52 KB

After Applied patch #8 on 9.5.x and works fine.Attached screenshot.

smustgrave’s picture

@Charlie ChX Negyesi if you have a solution for using checkbox we can take a look!

And reason for the tests was to mimic the steps from the IS.

ady1503’s picture

Hello.

I'm asking for the community's help again because I think there is a bug in drupal core with the form #state API.

Specifically, checkboxes and lists are not activated as required by form #state.

In the case of checkboxes, the requirement asterisk is not added, but required="required" and aria-required="true" attribute are added, but the checkboxes do not become required.

The same is with the lists except that the asterisk is added, but it is not required either.

I have a list, which I use with the checkbox/radio widget, which is the master.

And I also use the other slave list with the checkbox/radio widget, I have controlled the visibility and the requirement with form #state.

When I choose a value or checkbox from the master list the slave list becomes visible and should be and required.

And the requirement doesn't work, an visibility working well.

I read a lot about this bug, since the drupal 7 version it is not well fixed.

If someone can give me some solution.

Thanks for help.

/**
 * Implements hook_form_BASE_FORM_ID_alter() for node form.
 */
function buangh_mantenimiento_diario_piscina_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id): void {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->getType() !== 'mantenimiento_diario_piscina') {
    return;
  }

// field hide/view
$form['field_operacion_filtro_mantenimi']['#states'] = [
  'visible' => [
    ':input[name^="field_operacion_de_mantenimiento[Limpieza del filtro]"]' => ['checked' => TRUE],
  ],
];
// field required
$form['field_operacion_filtro_mantenimi']['widget']['#states'] = [
  'required' => [
    ':input[name^="field_operacion_de_mantenimiento[Limpieza del filtro]"]' => ['checked' => TRUE],
  ],
];

}
smustgrave’s picture

Did you try the patch on this ticket?

smustgrave’s picture

Status: Needs review » Needs work

For #26.

To see if a better solution can be had.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dmitry.korhov’s picture

StatusFileSize
new3.67 KB

rebased for 10.1.1

joachim’s picture

Re #26, this doesn't seem to be a problem at the checkbox level. This form works and passes validation:

    $form['test-3293609'] = [
      '#type' => 'checkbox',
      '#title' => 'test 3293609',
      '#default_value' => TRUE,
      '#disabled' => TRUE,
      '#required' => TRUE,
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

This one with a checkboxes element fails validation:

    $form['test-3293609'] = [
      '#type' => 'checkboxes',
      '#title' => 'test 3293609',
      '#options' => [
        'alpha' => 'Alpha',
        'beta' => 'Beta',
      ],
      '#default_value' => [
        'alpha' => 'alpha',
      ],
      '#required' => TRUE,
    ];
    $form['test-3293609']['alpha']['#disabled'] = TRUE;

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];
amitajgaonkar’s picture

StatusFileSize
new877 bytes

Rebased for 11.2.3

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.