From ebbd6427b2905ef49625b6048f5105b87e07f4b5 Mon Sep 17 00:00:00 2001 From: Guy Sartorelli <36352093+GuySartorelli@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:49:39 +1300 Subject: [PATCH] ENH Allow overriding GridFieldFilterHeader placeholder (#11418) --- src/Forms/GridField/GridFieldFilterHeader.php | 65 ++++++++++++++----- .../GridField/GridFieldFilterHeaderTest.php | 24 +++++++ 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/Forms/GridField/GridFieldFilterHeader.php b/src/Forms/GridField/GridFieldFilterHeader.php index 2e96e28f889..a6d2947f5c6 100755 --- a/src/Forms/GridField/GridFieldFilterHeader.php +++ b/src/Forms/GridField/GridFieldFilterHeader.php @@ -49,6 +49,8 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi */ protected ?string $searchField = null; + private string $placeHolderText = ''; + /** * @inheritDoc */ @@ -245,6 +247,24 @@ public function canFilterAnyColumns($gridField) return false; } + /** + * Get the text to be used as a placeholder in the search field. + * If blank, the placeholder will be generated based on the class held in the GridField. + */ + public function getPlaceHolderText(): string + { + return $this->placeHolderText; + } + + /** + * Set the text to be used as a placeholder in the search field. + * If blank, this text will be generated based on the class held in the GridField. + */ + public function setPlaceHolderText(string $placeHolderText): static + { + $this->placeHolderText = $placeHolderText; + return $this; + } /** * Generate a search context based on the model class of the of the GridField @@ -318,7 +338,7 @@ public function getSearchFieldSchema(GridField $gridField) $schema = [ 'formSchemaUrl' => $schemaUrl, 'name' => $searchField, - 'placeholder' => _t(__CLASS__ . '.Search', 'Search "{name}"', ['name' => $this->getTitle($gridField, $inst)]), + 'placeholder' => $this->getPlaceHolder($inst), 'filters' => $filters ?: new \stdClass, // stdClass maps to empty json object '{}' 'gridfield' => $gridField->getName(), 'searchAction' => $searchAction->getAttribute('name'), @@ -330,19 +350,6 @@ public function getSearchFieldSchema(GridField $gridField) return json_encode($schema); } - private function getTitle(GridField $gridField, object $inst): string - { - if ($gridField->Title) { - return $gridField->Title; - } - - if (ClassInfo::hasMethod($inst, 'i18n_plural_name')) { - return $inst->i18n_plural_name(); - } - - return ClassInfo::shortName($inst); - } - /** * Returns the search form for the component * @@ -386,7 +393,7 @@ public function getSearchForm(GridField $gridField) $field->addExtraClass('stacked no-change-track'); } - $name = $this->getTitle($gridField, singleton($gridField->getModelClass())); + $name = $this->getTitle(singleton($gridField->getModelClass())); $this->searchForm = $form = new Form( $gridField, @@ -456,4 +463,32 @@ public function getHTMLFragments($gridField) ) ]; } + + /** + * Get the text that will be used as a placeholder in the search field. + * + * @param object $obj An instance of the class that will be searched against. + * If getPlaceHolderText is empty, this object will be used to build the placeholder + * e.g. 'Search "My Data Object"' + */ + private function getPlaceHolder(object $obj): string + { + $placeholder = $this->getPlaceHolderText(); + if (!empty($placeholder)) { + return $placeholder; + } + if ($obj) { + return _t(__CLASS__ . '.Search', 'Search "{name}"', ['name' => $this->getTitle($obj)]); + } + return _t(__CLASS__ . '.Search_Default', 'Search'); + } + + private function getTitle(object $inst): string + { + if (ClassInfo::hasMethod($inst, 'i18n_plural_name')) { + return $inst->i18n_plural_name(); + } + + return ClassInfo::shortName($inst); + } } diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php index 2a760c25ade..b205551b5e6 100644 --- a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php @@ -3,6 +3,7 @@ namespace SilverStripe\Forms\Tests\GridField; use LogicException; +use ReflectionMethod; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; @@ -118,6 +119,29 @@ public function testSearchFieldSchema() $this->assertEquals('testfield', $searchSchema->gridfield); } + /** + * Tests the private method that returns the placeholder for the search field + */ + public function testGetPlaceHolder() + { + $gridField = new GridField('test'); + $filterHeader = new GridFieldFilterHeader(); + $reflectionGetPlaceHolder = new ReflectionMethod($filterHeader, 'getPlaceHolder'); + $reflectionGetPlaceHolder->setAccessible(true); + + // No explicit placeholder or model i18n_plural_name method + $this->assertSame('Search "ArrayData"', $reflectionGetPlaceHolder->invoke($filterHeader, new ArrayData())); + + // No explicit placeholder, but model has i18n_plural_name method + $model = new DataObject(); + $this->assertSame('Search "' . $model->i18n_plural_name() . '"', $reflectionGetPlaceHolder->invoke($filterHeader, $model)); + + // Explicit placeholder is set, which overrides both of the above cases + $filterHeader->setPlaceHolderText('This is the text'); + $this->assertSame('This is the text', $reflectionGetPlaceHolder->invoke($filterHeader, $model)); + $this->assertSame('This is the text', $reflectionGetPlaceHolder->invoke($filterHeader, new ArrayData())); + } + public function testHandleActionReset() { // Init Grid state with some pre-existing filters