Home > Software design >  How to make several selections for search with Symfony?
How to make several selections for search with Symfony?

Time:09-20

Hello Symfony experts !

I have a question. I'd like to know if it's possible to build a search bar with have several forms.

I am building a website where I want to show events. I would like to make a search available by location (city and country) and by type of event.

I already built the three entities : City, Country and Categories (Type of events). I entered the categories, cities and countries in which the events will take place in the database. I would like users to have access to a selection to make their choice.

How is it possible to do it ? Do you have some documentation about it ?

Thank very much. :)

CodePudding user response:

If I understand correctly, you actually have 3 form types: one for each of your City, Country and Category.

Now you, need another form type used to filter your events. So you need a fourth form type (lets name this one EventFilter) with three fields to select your filter elements. Selecting entities can be done with an EntityType.

Your form should look something like:

class EventFilterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('country', EntityType::class, ['class' => Country::class, 'required' => false])
            ->add('city', EntityType::class, ['class' => City:class, 'required' => false])
            ->add('category', EntityType::class, ['class' => Category::class, 'required' => false]);
    }
}

You use it as every form in your controller

    public function showEvents(Request $request): Response
    {
        $form->createForm(EventFilterType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // Something like ['country' => null, 'city' => City, ...]
            $data = $form->getData();
        }
    }

One step futher

I you want to have your code extra clean, you should write a class to handle your form data:

class EventFilter {
    public function __construct(
        public ?Country $country = null,
        public ?City $city = null,
        public ?Category $category = null,
    ) {}
}

This allows you to add proper validation. For example, if $city and $country are set, check if the city is in the country.

In the controller, you will get an EventFilter instance when calling $form->getData(). You can event set some initial value more easily:

    public function showEvents(Request $request): Response
    {
        $filter = new EventFilter(
            category: $this->getUser()?->getPreferedCategory(),
        );
        $form->createForm(EventFilterType::class, $filter);

        // ...
    }
  • Related