PHPackages                             silverstripe-terraformers/gridfield-rich-filter-header - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. silverstripe-terraformers/gridfield-rich-filter-header

ActiveSilverstripe-vendormodule[Search &amp; Filtering](/categories/search)

silverstripe-terraformers/gridfield-rich-filter-header
======================================================

Rich filter header component for GridField

4.0.0(2mo ago)1325.7k↓45.2%101BSD-3-ClausePHPPHP ^8.3

Since Apr 12Pushed 2mo ago11 watchersCompare

[ Source](https://github.com/silverstripe-terraformers/gridfield-rich-filter-header)[ Packagist](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)[ RSS](/packages/silverstripe-terraformers-gridfield-rich-filter-header/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (9)Dependencies (11)Versions (19)Used By (1)

GridField rich filter header
============================

[](#gridfield-rich-filter-header)

[![Latest Stable Version](https://camo.githubusercontent.com/e4f7e2fa06243bb82e13c1be5b179915f08d9229325f6d2de13cf4abd09f34c0/687474703a2f2f706f7365722e707567782e6f72672f73696c7665727374726970652d7465727261666f726d6572732f677269646669656c642d726963682d66696c7465722d6865616465722f76)](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)[![Total Downloads](https://camo.githubusercontent.com/860d80bb63e7078a9cc0f2f8556bced8729b458efdfb684ebc514e60c2c63eba/687474703a2f2f706f7365722e707567782e6f72672f73696c7665727374726970652d7465727261666f726d6572732f677269646669656c642d726963682d66696c7465722d6865616465722f646f776e6c6f616473)](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)[![Latest Unstable Version](https://camo.githubusercontent.com/a131bf32420163831e35b621173f17c9676d13fa64759685dd04b2d52dcddf66/687474703a2f2f706f7365722e707567782e6f72672f73696c7665727374726970652d7465727261666f726d6572732f677269646669656c642d726963682d66696c7465722d6865616465722f762f756e737461626c65)](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)[![License](https://camo.githubusercontent.com/d580c3ddc99ee75eec79c1800a98b80372430a3b17da72b4487b16176fed570d/687474703a2f2f706f7365722e707567782e6f72672f73696c7665727374726970652d7465727261666f726d6572732f677269646669656c642d726963682d66696c7465722d6865616465722f6c6963656e7365)](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)[![PHP Version Require](https://camo.githubusercontent.com/0816255a5f6d874f9ec71510feb834060ff71a560860db7af062215db29889c9/687474703a2f2f706f7365722e707567782e6f72672f73696c7665727374726970652d7465727261666f726d6572732f677269646669656c642d726963682d66696c7465722d6865616465722f726571756972652f706870)](https://packagist.org/packages/silverstripe-terraformers/gridfield-rich-filter-header)

This `GridField` component is intended to replace the default `GridFieldFilterHeader` component and provide rich functionality not available in the original.

Here is a brief comparison of these components:

`GridFieldFilterHeader` (original component)

- no filter related configuration available
- filtering only works if `GridField` column name matches `DB` column name, which is not the case in many situations (date fromatting, column content getter function)
- `TextField` is always used as a filter input `FormField`
- `PartialMatchFilter` is always used for filtering
- filtering is always applied to the DB field of respective `GridField` column
- it's not possible to NOT display a filter

`RichFilterHeader` (component in this module)

- filters are fully configurable
- you can specify the mapping between `GridField` column name and `DB` column name so you can freely use features like date fromatting, column content getter function
- you can choose to use any `FormField` in your filters, `TextField` is used only as a default
- `FormFields` which use XHR like `AutoCompleteField` are supported as well
- any `SearchFilter` can be used, `PartialMatchFilter` is used only as a default
- you can filter based on any data by specifying your own filter method

Overall this module allows you to fully customise your `GridField` filters including rare edge cases and special requirements.

Requirements
------------

[](#requirements)

- table header component needs to be present in the `GridField` (for example `GridFieldSortableHeader`)
- the last column of the table needs to have a vacant header cell so the filter widget could be displayed there
- for example you can't have the last column with sorting header widget and filter widget at the same time

Installation
------------

[](#installation)

`composer require silverstripe-terraformers/gridfield-rich-filter-header`

Basic configuration
-------------------

[](#basic-configuration)

Full filter configuration format looks like this:

```
'GridField_column_name' => [
    'title' => 'DB_column_name',
    'filter' => 'search_filter_type',
],
```

Concrete example:

```
'Expires.Nice' => [
    'title' => 'Expires',
    'filter' => 'ExactMatchFilter',
],
```

`search_filter_type` can be any `SearchFilter`, see search filter documentation for more information

[https://docs.silverstripe.org/en/4/developer\_guides/model/searchfilters/](https://docs.silverstripe.org/en/4/developer_guides/model/searchfilters/)

Shorter configuration formats are available as well:

Field mapping version doesn't include filter specification and will use `PartialMatchFilter`. This should be used if you are happy with using `PartialMatchFilter`

```
'GridField_column_name' => 'DB_column_name',
```

Whitelist version doesn't include filter specification nor field mapping. This configuration will use `PartialMatchFilter` and will assume that both `GridField_column_name` and `DB_column_name` are the same.

```
'GridField_column_name',
```

Multiple filters configuration example:

```
$gridFieldConfig->removeComponentsByType(
    GridFieldSortableHeader::class,
    GridFieldFilterHeader::class,
);

$sort = RichSortableHeader::create();
$filter = RichFilterHeader::create();
$filter
    ->setFilterConfig([
        'getFancyTitle' => 'Title',
        'Expires.Nice' => [
            'title' => 'Expires',
            'filter' => 'ExactMatchFilter',
        ],
    ]);

$gridFieldConfig->addComponent($sort, GridFieldPaginator::class);
$gridFieldConfig->addComponent($filter, GridFieldPaginator::class);
```

If no configuration is provided via `setFilterConfig` method, filter configuration will fall back to `searchable_fields` of the `DataObject` that is listed in the `GridField`. If `searchable_fields` configuration is not available, `summary_fields` will be used instead.

Make sure you add the `RichFilterHeader` component BEFORE the `GridFieldPaginator`otherwise your pagination will be broken since you always want to filter before paginating. Sort header component also needs to be replaced to allow the filter expand button to be shown.

Field configuration
-------------------

[](#field-configuration)

Any `FormField` can be used for filtering. You just need to add it to filter configuration like this:

```
->setFilterFields([
    'Expires' => DateField::create('', ''),
])
```

`Name` of the field can be left empty as it is populated automatically. I recommend to leave the `title` empty as well as you probably don't need to display it as it is redundant to `GridField` column header title in most cases.

Filter methods
--------------

[](#filter-methods)

This configuration covers most edge cases and special requirements where standard `SearchFilter` is not enough. If filter method is specified for a field, it will override the standard filter. Filter method is a callback which will be applied to the `DataList` and you are free to add any functionality you need inside the callback. Make sure that your callback returns a `DataList` with the same `DataClass` as the original.

```
->setFilterMethods([
    'Title' => function (DataList $list, $name, $value) {
        // my custom filter logic is implemented here
        return $filteredList;
    },
])
```

Note that `$name` will have the value of `DB_column_name` from your config.

For your convenience there are couple of filter methods available to cover some cases.

- `AllKeywordsFilter` - will split the text input by space into keywords and will search for records that contains ALL keywords
- `ManyManyRelationFilter` - will search for records that have relation to a specific record via `many_many` relation

Both of these filters can be used in `setFilterMethods` like this:

```
->setFilterMethods([
    'Title' => RichFilterHeader::FILTER_ALL_KEYWORDS,
])
```

Additional examples
-------------------

[](#additional-examples)

### Example #1

[](#example-1)

- filter with `AutoCompleteField` and filtering by `AllKeywordsFilter` filter method
- filter with `DateField` and filtering by `StartsWithFilter`

```
$gridFieldConfig->removeComponentsByType(
    GridFieldSortableHeader::class,
    GridFieldFilterHeader::class,
);

$sort = RichSortableHeader::create();
$filter = RichFilterHeader::create();
$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);
```

[![AutoCompleteField](doc/example_auto_complete.png)](doc/example_auto_complete.png)[![DateField](doc/example_date_field.png)](doc/example_date_field.png)

### Example #2

[](#example-2)

- filter with `DropdownField` and filtering with `ManyManyRelationFilter`

Note that the items that are listed in the `GridField` have a `many_many` relation with `TaxonomyTerm` called `TaxonomyTerms`

```
$gridFieldConfig->removeComponentsByType(
    GridFieldSortableHeader::class,
    GridFieldFilterHeader::class,
);

$sort = RichSortableHeader::create();
$filter = RichFilterHeader::create();
$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);
```

[![DropdownField](doc/example_drop_down_field.png)](doc/example_drop_down_field.png)

### Example #3

[](#example-3)

- filter with `TextField` (with custom placeholder text) and custom filter method

Our custom filter method filters records by three different `DB` columns via `PartialMatch` filter.

```
$gridFieldConfig->removeComponentsByType(
    GridFieldSortableHeader::class,
    GridFieldFilterHeader::class,
);

$sort = RichSortableHeader::create();
$filter = RichFilterHeader::create();
$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);
```

### Example #4

[](#example-4)

- full code example on setup for `has_one` relation using a `DropdownField`

This example covers

- `Player` (has one `Team`)
- `Team` (has many `Player`)
- `PlayersAdmin`

```
