ソースを参照

Fix html validation for checkboxes

Use `this.checked` instead of `this.value` for checkboxes as
we want to validate that checkboxes are checked as their value is fixed.

Port changes from #17683 to 5.x

Fixes #17672
Mark Story 1 年間 前
コミット
c708617aa8

+ 5 - 1
src/View/Helper/FormHelper.php

@@ -1426,9 +1426,13 @@ class FormHelper extends Helper
             $options['templateVars']['customValidityMessage'] = $message;
 
             if ($this->getConfig('autoSetCustomValidity')) {
+                $condition = 'this.value';
+                if ($options['type'] === 'checkbox') {
+                    $condition = 'this.checked';
+                }
                 $options['data-validity-message'] = $message;
                 $options['oninvalid'] = "this.setCustomValidity(''); "
-                    . 'if (!this.value) this.setCustomValidity(this.dataset.validityMessage)';
+                    . "if (!{$condition}) this.setCustomValidity(this.dataset.validityMessage)";
                 $options['oninput'] = "this.setCustomValidity('')";
             }
         }

+ 23 - 0
tests/TestCase/View/Helper/FormHelperTest.php

@@ -7834,6 +7834,7 @@ class FormHelperTest extends TestCase
             ->notEmptyString('email', 'Custom error message')
             ->requirePresence('password')
             ->alphaNumeric('password')
+            ->requirePresence('accept_tos')
             ->notBlank('phone');
 
         $table = $this->getTableLocator()->get('Contacts', [
@@ -7903,6 +7904,28 @@ class FormHelperTest extends TestCase
             ],
         ];
         $this->assertHtml($expected, $result);
+
+        $result = $this->Form->control('accept_tos', ['type' => 'checkbox']);
+        $expected = [
+            ['input' => ['type' => 'hidden', 'name' => 'accept_tos', 'value' => '0']],
+            'label' => ['for' => 'accept-tos'],
+            [
+                'input' => [
+                    'aria-required' => 'true',
+                    'required' => 'required',
+                    'type' => 'checkbox',
+                    'name' => 'accept_tos',
+                    'id' => 'accept-tos',
+                    'value' => '1',
+                    'data-validity-message' => 'This field cannot be left empty',
+                    'oninput' => 'this.setCustomValidity('')',
+                    'oninvalid' => 'this.setCustomValidity(''); if (!this.checked) this.setCustomValidity(this.dataset.validityMessage)',
+                ],
+            ],
+            'Accept Tos',
+            '/label',
+        ];
+        $this->assertHtml($expected, $result);
     }
 
     /**