Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH Allow overriding GridFieldFilterHeader placeholder #11418

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 50 additions & 15 deletions src/Forms/GridField/GridFieldFilterHeader.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi
*/
protected ?string $searchField = null;

private string $placeHolderText = '';

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'),
Expand All @@ -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);
}
Comment on lines -333 to -344
Copy link
Member Author

@GuySartorelli GuySartorelli Oct 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this method because private methods should be nearer the bottom than public methods.


/**
* Returns the search form for the component
*
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Comment on lines +486 to +493
Copy link
Member Author

@GuySartorelli GuySartorelli Oct 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note I've removed the code that relied on $gridField->Title because that was effectively dead code.
I've removed the corresponding parameter for $gridField from the method signature since this is a private method.

See #11416 (comment) for why I did that instead of changing it to use the Title() method.

}
24 changes: 24 additions & 0 deletions tests/php/Forms/GridField/GridFieldFilterHeaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading