From 496621a351a01a7ac5dc8590a8ee39f472224604 Mon Sep 17 00:00:00 2001 From: Sukhwinder Dhillon Date: Wed, 25 Mar 2026 09:40:12 +0100 Subject: [PATCH] Preserve `checked` state of `disabled` checkbox on submit Browsers do not submit `disabled` inputs. Since `CheckboxElement`'s `hidden` fallback element always used the `unchecked` value, a `checked` but `disabled` checkbox would appear `unchecked` on the next submit. Fix `renderUnwrapped()` to use the `checked` value in the `hidden` element when the checkbox is `checked` and `disabled`, preserving its state across submissions. --- src/FormElement/CheckboxElement.php | 6 +++++- tests/FormElement/CheckboxElementTest.php | 26 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/FormElement/CheckboxElement.php b/src/FormElement/CheckboxElement.php index 28782ed6..1e4b5603 100644 --- a/src/FormElement/CheckboxElement.php +++ b/src/FormElement/CheckboxElement.php @@ -119,7 +119,11 @@ public function renderUnwrapped() { $html = parent::renderUnwrapped(); - return (new HiddenElement($this->getValueOfNameAttribute(), ['value' => $this->getUncheckedValue()])) . $html; + $value = $this->getAttribute('disabled')->getValue() && $this->isChecked() + ? $this->getCheckedValue() + : $this->getUncheckedValue(); + + return (new HiddenElement($this->getValueOfNameAttribute(), ['value' => $value])) . $html; } /** diff --git a/tests/FormElement/CheckboxElementTest.php b/tests/FormElement/CheckboxElementTest.php index c14a5f5e..36aa1303 100644 --- a/tests/FormElement/CheckboxElementTest.php +++ b/tests/FormElement/CheckboxElementTest.php @@ -115,6 +115,32 @@ public function testSetCheckValues() ); } + public function testDisabledCheckedCheckboxRendersHiddenElementWithCheckedValue() + { + $checkbox = new CheckboxElement('test'); + $checkbox->setChecked(true); + $checkbox->getAttributes()->set('disabled', true); + + $this->assertHtml( + '' + . '', + $checkbox + ); + } + + public function testDisabledUncheckedCheckboxRendersHiddenElementWithUncheckedValue() + { + $checkbox = new CheckboxElement('test'); + $checkbox->setChecked(false); + $checkbox->getAttributes()->set('disabled', true); + + $this->assertHtml( + '' + . '', + $checkbox + ); + } + public function testCheckboxNotValidIfRequiredAndUnchecked() { $checkbox = new CheckboxElement('test');