andanteproject/page-filter-form-bundle
This package is a Symfony Bundle (compatible with Laravel via Symfony integration) designed to simplify the creation of filter forms for pagination, sorting, and searching in applications. To get started:
Installation:
composer require andante/page-filter-form-bundle
Ensure your project meets the updated requirements: PHP 7.4+ (with 8.2/8.5 now officially supported) and Symfony 7.1+ (or Symfony 4.0+ for legacy projects).
Enable the Bundle:
Add to config/bundles.php (Symfony) or register via Laravel's service provider if using a hybrid setup:
return [
// ...
Andante\PageFilterFormBundle\AndantePageFilterFormBundle::class => ['all' => true],
];
First Use Case: Create a filter form in a controller or service:
use Andante\PageFilterFormBundle\Form\FilterForm;
$filterForm = new FilterForm();
$filterForm->add('search', TextType::class, ['label' => 'Search']);
$filterForm->add('sort', ChoiceType::class, [
'choices' => ['name' => 'Name', 'date' => 'Date'],
'label' => 'Sort by'
]);
// Handle submission (e.g., in a Laravel controller)
if ($request->isMethod('post')) {
$filterForm->handleRequest($request);
$filters = $filterForm->getFilters();
}
Render the form in a Blade template (Symfony Twig or Laravel Blade via {{ Form::form($filterForm) }}).
Dynamic Filtering:
Use the FilterForm class to build reusable filter forms. Example:
$form = new FilterForm();
$form->add('status', EntityType::class, [
'class' => User::class,
'choice_label' => 'status',
->add('date_range', RangeType::class, [
'label' => 'Date Range',
'widget' => 'single_text',
]);
Integration with Laravel:
AppServiceProvider:
$this->app->bind(FilterForm::class, function ($app) {
return new FilterForm();
});
public function handleFilter(Request $request, FilterForm $filterForm) {
$filterForm->handleRequest($request);
return $filterForm->getFilters();
}
Query Builder Integration: Chain filter results to Eloquent queries:
$filters = $filterForm->getFilters();
$query = User::query();
if ($filters['search']) {
$query->where('name', 'like', "%{$filters['search']}%");
}
if ($filters['sort']) {
$query->orderBy($filters['sort']);
}
FilterForm to add validation logic:
class CustomFilterForm extends FilterForm {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'validation_groups' => ['filter_validation'],
]);
}
}
JsonResponse or Laravel’s Json::encode() to return filtered data dynamically:
return response()->json([
'data' => $query->get(),
'filters' => $filterForm->getFilters(),
]);
Symfony\Component\DependencyInjection\Extension\Extension (not HttpKernel\Extension). This is non-breaking but requires Symfony 4.0+ (previously 3.4+). Update your composer.json constraints if pinning Symfony versions:
"symfony/framework-bundle": "^4.0 || ^5.0 || ^6.0 || ^7.0"
Form Submission Issues:
handleRequest() is called before accessing $filterForm->getFilters().@csrf in Blade forms).Dependency Injection:
FilterForm class to avoid autowiring conflicts:
$this->app->bind(Andante\PageFilterFormBundle\Form\FilterForm::class);
Configuration Quirks:
resources/config/services.yaml may need manual inclusion in Laravel’s config/services.php:
'bundles' => [
Andante\PageFilterFormBundle\AndantePageFilterFormBundle::class => ['all' => true],
],
Custom Field Types:
Extend FilterForm to support domain-specific fields:
$form->add('custom_field', CustomType::class, ['options' => [...]]);
Register the type in Symfony’s form type system (Laravel: use Form::extend()).
Filter Processing:
Override FilterForm::getFilters() to transform raw input:
public function getFilters() {
$filters = parent::getFilters();
$filters['date_range'] = Carbon::parse($filters['date_range']);
return $filters;
}
Symfony Kernel Integration:
For Laravel-Symfony hybrids, ensure the bundle’s Extension is loaded in config/packages/andante_page_filter_form.yaml:
andante_page_filter_form:
default_options: { /* custom defaults */ }
Cache::remember()).N+1 issues when hydrating filter choices (e.g., EntityType for large tables). Use query_builder:
$form->add('user', EntityType::class, [
'class' => User::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')->where('u.active = 1');
},
]);
How can I help you explore Laravel packages today?