Symfony : barre de recherche dans la sidebar

Symfony : barre de recherche dans la sidebar

Comment créer une barre de recherche qui apparaitra directement dans la sidebar ou la navbar ?

Il est assez simple de créer une page de recherche et d'y mettre la barre de recherche. Tout se passe dans le même fichier.
Mais comment faire quand on a une barre de recherche dans la sidebar ou la navbar pour afficher les "bons résultats" sur la "bonne page" ?

1- Création d'un controller SearchController.php :

symfony console make:controller Search

 

Dans SearchController.php, on va directement créer une function searchBar avec le formulaire, juste en dessous de la function index() :

public function searchBar()
    {
        $form = $this->createFormBuilder()
            ->setAction($this->generateUrl('handleSearch'))
            ->add('query', TextType::class, [
                'label' => false,
                'attr' => [
                    'class' => 'form-control',
                    'placeholder' => 'Entrez un mot-clé'
                ]
            ])
            ->add('recherche', SubmitType::class, [
                'attr' => [
                    'class' => 'btn btn-primary'
                ]
            ])
            ->getForm();
        return $this->render('search/searchBar.html.twig', [
            'form' => $form->createView()
        ]);
    }

 

Ici, on crée le formulaire qui sera affiché dans la sidebar.
Avec un champ query (TextType) qui est le champ où on entre les mot-clés de recherche et un champ recherche (SubmitType) qui est en fait le bouton submit.
On "render" le template search/searchBar.html.twig.

Ensuite, dans ce controller, il faut gérer la requête. C'est la partie importante et plus "complexe" :

    /**
     * @Route("/handleSearch", name="handleSearch")
     * @param Request $request
     */
    public function handleSearch(Request $request, ArticleRepository $repo)
    {
        $query = $request->request->get('form')['query'];
        if($query) {
            $articles = $repo->findArticlesByName($query);
        }

        return $this->render('search/index.html.twig', [
            'articles' => $articles
        ]);
    }

 

On ajoute une @Route (handleSearch) qui va s'occuper de récupérer la funtion findArticlesByName() dans le ArticleRepository et va "render" le template search/index.html.twig.

2- Création d'une fonction de recherche dans le repository

Dans le repository ArticleRepository.php, on crée une function findArticlesByName()qui "ira chercher" les infos du title et du content (cela peut s'appeler titre et contenu chez vous : à adapter) :

    // Find/search articles by title/content
    public function findArticlesByName(string $query)
    {
        $qb = $this->createQueryBuilder('p');
        $qb
            ->where(
                $qb->expr()->andX(
                    $qb->expr()->orX(
                        $qb->expr()->like('p.title', ':query'),
                        $qb->expr()->like('p.content', ':query'),
                    ),
                    $qb->expr()->isNotNull('p.created_at')
                )
            )
            ->setParameter('query', '%' . $query . '%')
        ;
        return $qb
            ->getQuery()
            ->getResult();
    }

 

3- Les templates

Dans les templates, nous aurons search/searchBar.thml.twig avec seulement :

{{ form(form) }}

 

Et search/index.thml.twig qui aura notamment cette partie de code importante :

../..
{% if app.request.method == 'POST' %}
    <div>
        {% if articles | length == 0 %}
            <h4>Aucun résulat pour votre recherche.</h4>
           {% else %}
               <h3 class="mt-3">Vos résulats de recherche :</h3>
               {% for article in articles %}
                   <div class="mt-3 p-3 bg-light border rounded">
                       <a href="{{ path('article_show', {'slug': article.slug}) }}">
                              <h6 class="text-dark"><i class="bi bi-arrow-down-right-square-fill text-primary"></i> {{ article.title }}</h6>
                              <div class="text-dark small p-1 rounded">
                                    Posté le {{ article.createdAt|format_datetime('medium', 'short') }} par {{ article.author }}
                              </div>
                       </a>
                   </div>
              {% endfor %}
          {% endif %}
     </div>
{% endif %}

 

On vérifie qu'il y a une requête en POST et le nombre de résultats. Si articles | length == 0 il n'y a donc aucun résultat. Sinon, on boucle sur articles et on affiche les infos issues des articles "sélectionnés" par la requête de recherche.
Pour faire court, si on trouve le mot clé recherché dans un titre ou un contenu d'article, l'article est "sélectionné".

Enfin, il faut afficher la barre de recherche (soit dans la sidebar, soit dans la navbar) en faisant un "render" de controller et en choisissant la function searchBar :

{{ render(controller(
        'App\\Controller\\SearchController::searchBar'
 )) }}

 

Voila : vous devriez avoir une barre de recherche accessible depuis la sidebar ou la navbar et qui renvoie les résultats sur la page search/index.html.twig.

citizenz7
Posté par citizenz7

Geek quinqua nivernais fan d'ovalie, de linuxerie, de musique et de Net

1 commentaire

tuxyJeff Répondre

Merci !

Laisser un commentaire

Votre adresse email ne sera pas publiée.

Email:
Pseudo:
Message:
Accepter les CGU
Recopiez le code antispam: