From 894e9d074b5dd23e473047237dede8dd074bb3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Vaculi=CC=81k?= Date: Thu, 16 Apr 2026 12:22:00 +0200 Subject: [PATCH] Fix: FilterSelect implicit validation breaks form on hidden column (#1281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nette's SelectBox constructor adds an implicit "Filled" validation rule when no prompt is set. For a FilterSelect on a column that's hidden (setDefaultHide / handleHideColumn), the input isn't rendered and no value is submitted — the rule fails, the filter container becomes invalid, and Container::getValues() in Datagrid::filterSucceeded() triggers an E_USER_WARNING. Filters are search inputs, not required data entry, so reset the rules on the underlying SelectBox. Added a regression test that validates the filter container with no value submitted and asserts it stays valid. --- src/Filter/FilterSelect.php | 7 +++++++ tests/Cases/FilterTest.phpt | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/Filter/FilterSelect.php b/src/Filter/FilterSelect.php index f25d4d53e..7f4a65c46 100644 --- a/src/Filter/FilterSelect.php +++ b/src/Filter/FilterSelect.php @@ -104,6 +104,13 @@ protected function addControl( { $input = $container->addSelect($key, $name, $options); + // SelectBox adds an implicit "Filled" rule when no prompt is set. + // A filter is never required, and when its column is hidden the input + // isn't rendered, so nothing is submitted and the rule fails — which + // invalidates the whole filter container and triggers a warning on + // getValues(). Filters don't need validation, so drop it here. + $input->getRules()->reset(); + if ($this->getPrompt() !== null) { $input->setPrompt($this->getPrompt()); } diff --git a/tests/Cases/FilterTest.phpt b/tests/Cases/FilterTest.phpt index 02d665df5..2969857e3 100644 --- a/tests/Cases/FilterTest.phpt +++ b/tests/Cases/FilterTest.phpt @@ -110,6 +110,40 @@ final class FilterTest extends TestCase Assert::count(0, $grid->filter); } + /** + * Regression test for https://github.com/contributte/datagrid/issues/1281 + * + * A FilterSelect on a hidden column isn't rendered in HTML, so no value is + * submitted for it. SelectBox's constructor adds an implicit "Filled" rule + * when no prompt is set, which used to fail validation for the missing + * value, invalidate the filter container, and trigger an E_USER_WARNING + * from Container::getValues() in Datagrid::filterSucceeded(). + */ + public function testFilterSelectHasNoImplicitValidation(): void + { + $factory = new TestingDatagridFactoryRouter(); + /** @var Datagrid $grid */ + $grid = $factory->createTestingDatagrid()->getComponent('grid'); + + $grid->addColumnText('name', 'Name') + ->setFilterText(); + + $grid->addColumnText('status', 'Status') + ->setFilterSelect(['yes' => 'Yes', 'no' => 'No']); + + $filterForm = $grid->createComponentFilter(); + + $filterContainer = $filterForm->getComponent('filter'); + Assert::type(Container::class, $filterContainer); + + $filterContainer->validate(); + + // With no value set (as if the select was hidden and not submitted), + // the container must still be valid — no implicit Filled rule should + // fire on the FilterSelect. + Assert::true($filterContainer->isValid()); + } + } (new FilterTest())->run();