From a32519e74329c7b869b43c81fc09f51aab1ef2ec Mon Sep 17 00:00:00 2001 From: Dalibor Korpar Date: Fri, 14 Aug 2026 16:54:48 +0200 Subject: [PATCH 1/2] fix: render validation state on DateTimeControl and ColorPicker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both controls used StandardValidationTrait but never declared `implements IValidationInput`. BootstrapRenderer::renderControl() gates the showValidation() call on that interface, so the input never received `is-invalid`. The
was emitted all along, but Bootstrap styles it `display: none` unless a sibling input carries `is-invalid` — so the error message was rendered yet invisible. Affects addDate(), addDateTime(), addTime() and addColor(). Closes #113 Co-Authored-By: Claude Opus 5 --- src/Inputs/ColorPicker.php | 2 +- src/Inputs/DateTimeControl.php | 2 +- tests/Inputs/ColorPickerTest.php | 14 ++++++++++++++ tests/Inputs/DateTimeControlTest.php | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Inputs/ColorPicker.php b/src/Inputs/ColorPicker.php index 9a3ea44..9e40274 100644 --- a/src/Inputs/ColorPicker.php +++ b/src/Inputs/ColorPicker.php @@ -6,7 +6,7 @@ use Contributte\FormsBootstrap\Traits\StandardValidationTrait; use Nette\Utils\Html; -class ColorPicker extends \Nette\Forms\Controls\ColorPicker +class ColorPicker extends \Nette\Forms\Controls\ColorPicker implements IValidationInput { use StandardValidationTrait; diff --git a/src/Inputs/DateTimeControl.php b/src/Inputs/DateTimeControl.php index ea7e01c..e53ff20 100644 --- a/src/Inputs/DateTimeControl.php +++ b/src/Inputs/DateTimeControl.php @@ -6,7 +6,7 @@ use Contributte\FormsBootstrap\Traits\StandardValidationTrait; use Nette\Utils\Html; -class DateTimeControl extends \Nette\Forms\Controls\DateTimeControl +class DateTimeControl extends \Nette\Forms\Controls\DateTimeControl implements IValidationInput { use StandardValidationTrait; diff --git a/tests/Inputs/ColorPickerTest.php b/tests/Inputs/ColorPickerTest.php index e2e0b80..8bd9374 100644 --- a/tests/Inputs/ColorPickerTest.php +++ b/tests/Inputs/ColorPickerTest.php @@ -3,6 +3,7 @@ namespace Tests\Inputs; use Contributte\FormsBootstrap\BootstrapForm; +use Contributte\FormsBootstrap\Inputs\IValidationInput; use Tests\BaseTestCase; class ColorPickerTest extends BaseTestCase @@ -16,4 +17,17 @@ public function testDefaultTextInput(): void $this->assertEquals('', (string) $input->getLabel()); } + public function testShowsValidationState(): void + { + $form = new BootstrapForm(); + $input = $form->addColor('color', 'Choose color'); + $this->assertInstanceOf(IValidationInput::class, $input); + + $input->addError('Foobar error message'); + + $html = (string) $form; + $this->assertStringContainsString('class="form-control is-invalid"', $html); + $this->assertStringContainsString('
Foobar error message
', $html); + } + } diff --git a/tests/Inputs/DateTimeControlTest.php b/tests/Inputs/DateTimeControlTest.php index 56605c3..6a3bbb9 100644 --- a/tests/Inputs/DateTimeControlTest.php +++ b/tests/Inputs/DateTimeControlTest.php @@ -3,6 +3,7 @@ namespace Tests\Inputs; use Contributte\FormsBootstrap\BootstrapForm; +use Contributte\FormsBootstrap\Inputs\IValidationInput; use Tests\BaseTestCase; class DateTimeControlTest extends BaseTestCase @@ -15,4 +16,17 @@ public function testDefaultDate(): void $this->assertEquals('', $dt->getControl()->render()); } + public function testShowsValidationState(): void + { + $form = new BootstrapForm(); + $dt = $form->addDate('date', 'Date'); + $this->assertInstanceOf(IValidationInput::class, $dt); + + $dt->addError('Foobar error message'); + + $html = (string) $form; + $this->assertStringContainsString('class="form-control is-invalid"', $html); + $this->assertStringContainsString('
Foobar error message
', $html); + } + } From 66fda61341d9c9d00d5a33a00596219d9ca2c38c Mon Sep 17 00:00:00 2001 From: Dalibor Korpar Date: Fri, 14 Aug 2026 17:01:04 +0200 Subject: [PATCH 2/2] tests: attach a presenter before rendering in validation-state tests Rendering a BootstrapForm resolves the presenter via lookup(); on the lowest supported nette/application that throws when the form has no parent, so the two new tests failed under --prefer-lowest while passing against current dependencies. Use the presenter-mock + non-empty action convention already used by the renderer tests. --- tests/Inputs/ColorPickerTest.php | 5 +++++ tests/Inputs/DateTimeControlTest.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/tests/Inputs/ColorPickerTest.php b/tests/Inputs/ColorPickerTest.php index 8bd9374..d4503b7 100644 --- a/tests/Inputs/ColorPickerTest.php +++ b/tests/Inputs/ColorPickerTest.php @@ -4,6 +4,7 @@ use Contributte\FormsBootstrap\BootstrapForm; use Contributte\FormsBootstrap\Inputs\IValidationInput; +use Nette\Application\UI\Presenter; use Tests\BaseTestCase; class ColorPickerTest extends BaseTestCase @@ -20,6 +21,10 @@ public function testDefaultTextInput(): void public function testShowsValidationState(): void { $form = new BootstrapForm(); + // Rendering a form requires a presenter with a non-empty action; see BaseTestCase users. + $form->setParent($this->createMock(Presenter::class)); + $form->setAction('/'); + $input = $form->addColor('color', 'Choose color'); $this->assertInstanceOf(IValidationInput::class, $input); diff --git a/tests/Inputs/DateTimeControlTest.php b/tests/Inputs/DateTimeControlTest.php index 6a3bbb9..4f1d31e 100644 --- a/tests/Inputs/DateTimeControlTest.php +++ b/tests/Inputs/DateTimeControlTest.php @@ -4,6 +4,7 @@ use Contributte\FormsBootstrap\BootstrapForm; use Contributte\FormsBootstrap\Inputs\IValidationInput; +use Nette\Application\UI\Presenter; use Tests\BaseTestCase; class DateTimeControlTest extends BaseTestCase @@ -19,6 +20,10 @@ public function testDefaultDate(): void public function testShowsValidationState(): void { $form = new BootstrapForm(); + // Rendering a form requires a presenter with a non-empty action; see BaseTestCase users. + $form->setParent($this->createMock(Presenter::class)); + $form->setAction('/'); + $dt = $form->addDate('date', 'Date'); $this->assertInstanceOf(IValidationInput::class, $dt);