padam87 / form-filter-bundle
The simplest way to build search forms in Symfony.
Installs: 342
Dependents: 1
Suggesters: 0
Security: 0
Stars: 3
Watchers: 2
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: ^8.0
- doctrine/orm: ^2.3 || ^3.0
- symfony/config: ^6.0 || ^7.0
- symfony/dependency-injection: ^6.0 || ^7.0
- symfony/form: ^6.0 || ^7.0
README
The simplest way to build search forms in Symfony.
Installation
composer require padam87/form-filter-bundle
Usage
My goal was to create a simpler, lighter way to build to search forms than what is currently available. No learning curve, just a simple abstraction. The bundle uses built-in form types, with some extra filter types for convenience.
The bundle provides a form type extension, and makes 2 new options available for every type:
filter
bool / callable, default: truefilter_expr
string, has to be a valid doctrine expr, default: eq
Build a form
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\OptionsResolver\OptionsResolver; class UserFilterType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', TextType::class) ->add('email', TextType::class) ; } public function configureOptions(OptionsResolver $resolver) { $resolver ->setDefaults( [ 'method' => Request::METHOD_GET, 'csrf_protection' => false, ] ) ; } }
As you can see, the search fields are using the built in TextType
.
Controller
$filters = $this->createForm(UserFilterType::class); $filters->handleRequest($request); $qb = $em->getRepository(User::class)->createQueryBuilder('alias'); $this->get('padam87_form_filter.filters')->apply($qb, $filters); // paginate, render template etc.
Advanced usage
filter_expr
- You can change the expression used in the filter, for example in the example above it would nice to use a like
expression instead of eq
.
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', TextType::class, ['filter_expr' => 'like']) ->add('email', TextType::class, ['filter_expr' => 'like']) ; }
filter
- The filter option gives you full control over the field's behavior.
If a simple expression is not enough, you can use a callback to customize the filter.
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', TextType::class, ['filter_expr' => 'like']) ->add('email', TextType::class, ['filter_expr' => 'like']) ->add( 'city', TextType::class, [ 'filter' => function(QueryBuilder $qb, $alias, $value) { $qb //->join('u.address', 'a') ->andWhere($qb->expr->eq('a.city', ':city')) ->setParameter('city', $value) ; return $qb; } ] ) ; }
NOTE: You should not use joins here, write a custom method in the repository, eg getListQb
and join everything you need to filter there.
Filter types
- BooleanFilterType - 3 state filter for boolean values. (A simple checkbox would only have 2 states).
- RangeFilterType - A filter for ranges (numeric, date, any other)
$builder ->add( 'createdAt', RangeFilterType::class, [ 'from_field_type' => DateType::class, 'from_field_options' => [ 'widget' => 'single_text', ], 'to_field_type' => DateType::class, 'to_field_options' => [ 'widget' => 'single_text', ], 'to_field_expr' => 'lt' ] ) ;