silverstripe-terraformers / gridfield-rich-filter-header
来自 GridField 的丰富筛选头组件
Requires
- php: ^8.1
- silverstripe/cms: ^5
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-21 22:00:03 UTC
README
此 GridField
组件旨在替换默认的 GridFieldFilterHeader
组件,并提供原始版本中不可用的丰富功能。
以下是这些组件的简要比较
GridFieldFilterHeader
(原始组件)
- 没有可用的筛选相关配置
- 只有当
GridField
列名称与DB
列名称匹配时,筛选功能才有效,这在许多情况下并不适用(日期格式、列内容获取函数) - 始终使用
TextField
作为筛选输入FormField
- 始终使用
PartialMatchFilter
进行筛选 - 始终将对应
GridField
列的数据库字段应用筛选 - 无法选择不显示筛选
RichFilterHeader
(本模块中的组件)
- 筛选可以完全配置
- 您可以为
GridField
列名称与DB
列名称之间的映射指定,这样您就可以自由地使用日期格式、列内容获取函数等特性 - 您可以选择在筛选中使用任何
FormField
,TextField
仅作为默认选项使用 - 支持使用 XHR 的
FormFields
,例如AutoCompleteField
- 可以使用任何
SearchFilter
,默认情况下使用PartialMatchFilter
- 您可以通过指定自己的筛选方法来根据任何数据进行筛选
总的来说,此模块允许您完全自定义 GridField
筛选,包括罕见边缘情况和特殊要求。
需求
- 表头组件需要存在于
GridField
中(例如GridFieldSortableHeader
) - 表的最后一列需要有一个空白的表头单元格,以便在那里显示筛选小部件
- 例如,您不能同时在最后一列具有排序表头小部件和筛选小部件
安装
composer require silverstripe-terraformers/gridfield-rich-filter-header
基本配置
完整的筛选配置格式如下所示
'GridField_column_name' => [ 'title' => 'DB_column_name', 'filter' => 'search_filter_type', ],
具体示例
'Expires.Nice' => [ 'title' => 'Expires', 'filter' => 'ExactMatchFilter', ],
search_filter_type
可以是任何 SearchFilter
,有关更多信息,请参阅搜索筛选文档
https://docs.silverstripe.org/en/4/developer_guides/model/searchfilters/
还有更短的配置格式可用
字段映射版本不包括筛选规范,将使用 PartialMatchFilter
。如果您对使用 PartialMatchFilter
满意,应使用此配置
'GridField_column_name' => 'DB_column_name',
白名单版本不包括筛选规范和字段映射。此配置将使用 PartialMatchFilter
并假定 GridField_column_name
和 DB_column_name
相同
'GridField_column_name',
多个筛选配置示例
$gridFieldConfig->removeComponentsByType( GridFieldSortableHeader::class, GridFieldFilterHeader::class, ); $sort = new RichSortableHeader(); $filter = new RichFilterHeader(); $filter ->setFilterConfig([ 'getFancyTitle' => 'Title', 'Expires.Nice' => [ 'title' => 'Expires', 'filter' => 'ExactMatchFilter', ], ]); $gridFieldConfig->addComponent($sort, GridFieldPaginator::class); $gridFieldConfig->addComponent($filter, GridFieldPaginator::class);
如果未通过 setFilterConfig
方法提供配置,筛选配置将回退到 GridField
中列出的 DataObject
的 searchable_fields
。如果 searchable_fields
配置不可用,则使用 summary_fields
代替。
请确保在 GridFieldPaginator
之前添加 RichFilterHeader
组件,否则您的分页将会损坏,因为您始终希望在分页之前进行筛选。排序头组件也需要替换,以允许显示筛选展开按钮。
字段配置
任何 FormField
都可用于过滤。只需将其添加到过滤配置,如下所示
->setFilterFields([ 'Expires' => DateField::create('', ''), ])
字段的 名称
可以留空,因为它会自动填充。我建议将 标题
也留空,因为你可能不需要显示它,因为在大多数情况下它与 GridField
列表头标题重复。
过滤方法
此配置涵盖了大多数边缘情况和特殊要求,在这些情况下标准 SearchFilter
不够用。如果为字段指定了过滤方法,它将覆盖标准过滤。过滤方法是一个回调,它将被应用于 DataList
,你可以在回调内部添加任何所需的功能。确保你的回调返回一个与原始相同的 DataClass
的 DataList
。
->setFilterMethods([ 'Title' => function (DataList $list, $name, $value) { // my custom filter logic is implemented here return $filteredList; }, ])
请注意,$name
将具有配置中的 DB_column_name
的值。
为了您的方便,提供了一些过滤方法来覆盖某些情况。
AllKeywordsFilter
- 将文本输入按空格分割成关键词,并搜索包含所有关键词的记录ManyManyRelationFilter
- 将搜索与特定记录通过many_many
关系关联的记录
这两个过滤器都可以在 setFilterMethods
中使用,如下所示
->setFilterMethods([ 'Title' => RichFilterHeader::FILTER_ALL_KEYWORDS, ])
其他示例
示例 #1
- 使用
AutoCompleteField
进行过滤,并通过AllKeywordsFilter
过滤方法进行过滤 - 使用
DateField
进行过滤,并通过StartsWithFilter
进行过滤
$gridFieldConfig->removeComponentsByType( GridFieldSortableHeader::class, GridFieldFilterHeader::class, ); $sort = new RichSortableHeader(); $filter = new RichFilterHeader(); $filter ->setFilterConfig([ 'Label', 'DisplayDateEnd.Nice' => [ 'title' => 'DisplayDateEnd', 'filter' => 'StartsWithFilter', ], ]) ->setFilterFields([ 'Label' => $dealsLookup = AutoCompleteField::create('', ''), 'DisplayDateEnd' => DateField::create('', ''), ]) ->setFilterMethods([ 'Label' => RichFilterHeader::FILTER_ALL_KEYWORDS, ]); $dealsLookup ->setSourceClass(SystemDeal::class) ->setSourceFields(['Label']) ->setDisplayField('Label') ->setLabelField('Label') ->setStoredField('Label') ->setSourceSort('Label ASC') ->setRequireSelection(false); $gridFieldConfig->addComponent($sort, GridFieldPaginator::class); $gridFieldConfig->addComponent($filter, GridFieldPaginator::class);
示例 #2
- 使用
DropdownField
进行过滤,并通过ManyManyRelationFilter
进行过滤
请注意,在 GridField
中列出的条目与 TaxonomyTerm
有一个名为 TaxonomyTerms
的 many_many
关系
$gridFieldConfig->removeComponentsByType( GridFieldSortableHeader::class, GridFieldFilterHeader::class, ); $sort = new RichSortableHeader(); $filter = new RichFilterHeader(); $filter ->setFilterConfig([ 'Label' => 'TaxonomyTerms', ]) ->setFilterFields([ 'TaxonomyTerms' => DropdownField::create( '', '', TaxonomyTerm::get()->sort('Name', 'ASC')->map('ID', 'Name') ), ]) ->setFilterMethods([ 'TaxonomyTerms' => RichFilterHeader::FILTER_MANY_MANY_RELATION, ]); $gridFieldConfig->addComponent($sort, GridFieldPaginator::class); $gridFieldConfig->addComponent($filter, GridFieldPaginator::class);
示例 #3
- 使用
TextField
(带自定义占位符文本)和自定义过滤方法进行过滤
我们的自定义过滤方法通过 PartialMatch
过滤器根据三个不同的 DB
列表进行过滤。
$gridFieldConfig->removeComponentsByType( GridFieldSortableHeader::class, GridFieldFilterHeader::class, ); $sort = new RichSortableHeader(); $filter = new RichFilterHeader(); $filter ->setFilterConfig([ 'Label', ]) ->setFilterFields([ 'Label' => $label = TextField::create('', ''), ]) ->setFilterMethods([ 'Label' => function (DataList $list, $name, $value) { return $list->filterAny([ 'Label:PartialMatch' => $value, 'TitleLineOne:PartialMatch' => $value, 'TitleLineTwo:PartialMatch' => $value, ]); }, ]); $label->setAttribute('placeholder', 'Filter by three different columns'); $gridFieldConfig->addComponent($sort, GridFieldPaginator::class); $gridFieldConfig->addComponent($filter, GridFieldPaginator::class);
示例 #4
- 使用
DropdownField
设置has_one
关系的完整代码示例
此示例涵盖了
Player
(有一个Team
)Team
(有多个Player
)PlayersAdmin
<?php namespace App\Models; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\HasManyList; /** * @property string $Title * @method HasManyList|Player[] Players() */ class Team extends DataObject { /** * @var string */ private static $table_name = 'Team'; /** * @var array */ private static $db = [ 'Title' => 'Varchar', ]; /** * @var array */ private static $has_many = [ 'Players' => Player::class, ]; }
<?php namespace App\Models; use SilverStripe\ORM\DataObject; /** * @property string $Title * @property int $TeamID * @method Team Team() */ class Player extends DataObject { /** * @var string */ private static $table_name = 'Player'; /** * @var array */ private static $db = [ 'Title' => 'Varchar', ]; /** * @var array */ private static $has_one = [ 'Team' => Team::class, ]; /** * @var array */ private static $summary_fields = [ 'Title', 'Team.Title' => 'Team', ]; }
<?php namespace App\Admin; use App\Models\Player; use App\Models\Team; use SilverStripe\Admin\ModelAdmin; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldFilterHeader; use SilverStripe\Forms\GridField\GridFieldPaginator; use Terraformers\RichFilterHeader\Form\GridField\RichFilterHeader; class PlayersAdmin extends ModelAdmin { /** * @var array */ private static $managed_models = [ Player::class => ['title' => 'Players'], ]; /** * @var string */ private static $menu_title = 'Players'; /** * @var string */ private static $url_segment = 'players'; /** * @param mixed|null $id * @param FieldList|null $fields * @return Form */ public function getEditForm($id = null, $fields = null): Form { $form = parent::getEditForm($id, $fields); /** @var GridField $gridField */ $gridField = $form->Fields()->fieldByName('App-Models-Player'); if ($gridField) { // Default sort order $config = $gridField->getConfig(); // custom filters $config->removeComponentsByType( GridFieldSortableHeader::class, GridFieldFilterHeader::class, ); $sort = new RichSortableHeader(); $filter = new RichFilterHeader(); $filter ->setFilterConfig([ 'Title', 'Team.Title' => [ 'title' => 'TeamID', 'filter' => 'ExactMatchFilter', ], ]) ->setFilterFields([ 'TeamID' => $team = DropdownField::create( '', '', Team::get()->sort('Title', 'ASC')->map('ID', 'Title') ), ]); $team->setEmptyString('-- select --'); $config->addComponent($sort, GridFieldPaginator::class); $config->addComponent($filter, GridFieldPaginator::class); } return $form; } }
现在我们可以通过球队过滤球员。