Creating a custom Filter
Sylius Grids come with built-in filters, but there are use-cases where you need something more than a basic filter. Grids let you define your own filter types!
To add a new filter, we need to create an appropriate class and form type.
<?php
declare(strict_types=1);
namespace App\Grid\Filter;
use App\Form\Type\Filter\SuppliersStatisticsFilterType;
use Sylius\Bundle\GridBundle\Doctrine\DataSourceInterface;
use Sylius\Component\Grid\Attribute\AsFilter;
use Sylius\Component\Grid\Filtering\FilterInterface;
#[AsFilter(
formType: SuppliersStatisticsFilterType::class, // (custom) Symfony FormType
template: '@SyliusBootstrapAdminUi/shared/grid/filter/select.html.twig', // or you can use your own Twig template
type: 'suppliers_statistics', // optional - FQCN by default
)]
class SuppliersStatisticsFilter implements FilterInterface
{
public function apply(DataSourceInterface $dataSource, $name, $data, array $options = []): void
{
// Your filtering logic.
// $data['stats'] contains the submitted value!
$queryBuilder = $dataSource->getQueryBuilder();
$queryBuilder
->andWhere('stats = :stats')
->setParameter(':stats', $data['stats'])
;
// You can leverage the ExpressionBuilder to apply driver-agnostic filters to the data source.
// Combined with restrict(), it provides query builder–style functionalities for grid filters.
$dataSource->restrict($dataSource->getExpressionBuilder()->equals('stats', $data['stats']));
}
}
And the form type:
<?php
namespace App\Form\Type\Filter;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SuppliersStatisticsFilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'stats',
ChoiceType::class,
['choices' => range($options['range'][0], $options['range'][1])]
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver
->setDefaults([
'range' => [0, 10],
])
->setAllowedTypes('range', ['array'])
;
}
}
Now you can use your new filter type in any grid configuration!
<?php
use App\Entity\Tournament;
use Sylius\Bundle\GridBundle\Builder\Action\Action;
use Sylius\Bundle\GridBundle\Builder\ActionGroup\ItemActionGroup;
use Sylius\Bundle\GridBundle\Builder\GridBuilder;
use Sylius\Bundle\GridBundle\Builder\Filter\Filter;
use Sylius\Bundle\GridBundle\Config\GridConfig;
return static function (GridConfig $grid) {
$grid->addGrid(GridBuilder::create('app_tournament', Tournament::class)
->addFilter(
Filter::create('stats', 'suppliers_statistics')
->setFormOptions(['range' => [0, 100]])
)
)
};
OR
<?php
declare(strict_types=1);
namespace App\Grid;
use App\Entity\Tournament;
use Sylius\Bundle\GridBundle\Builder\GridBuilderInterface;
use Sylius\Bundle\GridBundle\Grid\AbstractGrid;
#[AsGrid(
name: 'app_tournament',
resourceClass: Tournament::class,
)]
final class TournamentGrid extends AbstractGrid
{
public function __invoke(GridBuilderInterface $gridBuilder): void
{
$gridBuilder
->addFilter(
Filter::create('stats', 'suppliers_statistics')
->setFormOptions(['range' => [0, 100]])
)
;
}
}
Last updated