Search code examples
symfonyknppaginatorbundle

how can i append an anchor to the url using knp_paginator


I am using symfony 4.4 to develop an e-commerce website. I have a section with an id="projects" at the centre of the page so you have to scroll down to reach it. This section is built with knp paginator inside my ProductRepository to make it work with the search form, and some parts of the section are links to another page that also has a products section that you have to scroll to. I want to attach #projects to the URLs to scroll the user down to the section, but I don't know how to do this the way that knp paginator builds the page.

I have tried to append a #projects to the path inside twitter_bootstrap_v4_pagination.html.twig (the template that I have defined in the knp_paginator.yaml), but when I do this the paginator doesn't work anymore and #projects is not appended to the url.

    {% if pageCount > 1 %}
        <nav>
            {% set classAlign = (align is not defined) ? '' : align=='center' ? ' justify-content-center' : (align=='right' ? ' justify-content-end' : '') %}
            {% set classSize = (size is not defined) ? '' : size=='large' ? ' pagination-lg' : (size=='small' ? ' pagination-sm' : '') %}
            <ul class="pagination{{ classAlign }}{{ classSize }}">
    
                {% if previous is defined %}
                    <li class="page-item">
                        <a  class="page-link" rel="prev" href="{{ path(route, query|merge({(pageParameterName): previous})) }}#projects">&laquo;&nbsp;{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</a>
                    </li>
                {% else %}
                    <li class="page-item disabled">
                        <span class="page-link">&laquo;&nbsp;{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}</span>
                    </li>
                {% endif %}
    
                {% if startPage > 1 %}
                    <li class="page-item">
                        <a class="page-link" href="{{ path(route, query|merge({(pageParameterName): 1})) }}#projects">1</a>
                    </li>
                    {% if startPage == 3 %}
                        <li class="page-item">
                            <a class="page-link" href="{{ path(route, query|merge({(pageParameterName): 2})) }}#projects">2</a>
                        </li>
                    {% elseif startPage != 2 %}
                        <li class="page-item disabled">
                            <span class="page-link">&hellip;</span>
                        </li>
                    {% endif %}
                {% endif %}
    
                {% for page in pagesInRange %}
                    {% if page != current %}
                        <li class="page-item">
                            <a class="page-link" href="{{ path(route, query|merge({(pageParameterName): page})) }}#projects">{{ page }}</a>
                        </li>
                    {% else %}
                        <li class="page-item active">
                            <span class="page-link">{{ page }}</span>
                        </li>
                    {% endif %}
    
                {% endfor %}
    
                {% if pageCount > endPage %}
                    {% if pageCount > (endPage + 1) %}
                        {% if pageCount > (endPage + 2) %}
                            <li class="page-item disabled">
                                <span class="page-link">&hellip;</span>
                            </li>
                        {% else %}
                            <li class="page-item">
                                <a class="page-link" href="{{ path(route, query|merge({(pageParameterName): (pageCount - 1)})) }}#projects">{{ pageCount -1 }}</a>
                            </li>
                        {% endif %}
                    {% endif %}
                    <li class="page-item">
                        
                    </li>
                {% endif %}
    
                {% if next is defined %}
                    <li class="page-item">
                        <a class="page-link" rel="next" href="{{ path(route, query|merge({(pageParameterName): next})) }}#projects">{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}&nbsp;&raquo;</a>
                    </li>
                {% else %}
                    <li  class="page-item disabled">
                        <span class="page-link">{{ 'label_next'|trans({}, 'KnpPaginatorBundle') }}&nbsp;&raquo;</span>
                    </li>
                {% endif %}
            </ul>
        </nav>
    {% endif %}

If I change #projects to another id that doesn't exist inside my index.html.twig, for example #randomId, the paginator works fine and the url is changed "http://127.0.0.1:8000/home?page=2#randomId", but it doesn't solve my problem.

Note: I have also tried to change manually the url to http://127.0.0.1:8000/home?page=2#projects and it worked. I don't know why it wouldn't accept and existing id inside the index.html.twig.

If needed here is the controller :

<?php

namespace App\Controller;
use App\Data\SearchData;
use App\Entity\Contact;
use App\Entity\ContactDevis;
use App\Entity\Evv;
use App\Form\ContactType;
use App\Form\ContactDevisType;
use App\Form\SearchForm;
use App\Repository\ProduitRepository;
use App\Repository\EvvRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;


/**
  * @Route("/")
  */
class EnoveController extends AbstractController
{
    /**
      * @Route("/home", name="enove_index", methods={"GET","POST"})
      */
    public function index(ProduitRepository $produitRepository, EvvRepository $evvRepository, Request $request , Request $request_contact, Request $request_devis, \Swift_Mailer $mailer)
    {
        $contact = new Contact();
        $contactdevis = new ContactDevis();
        $data = new SearchData();
        $evv = new Evv();
        $data->page = $request->get('page',1);
        $form_filter = $this->createForm(SearchForm::class, $data);
        $form_filter->handleRequest($request);
        
        
        //dd($data);
        $evv = $evvRepository->findAll();
        $produit = $produitRepository->findSearch($data);
        $form_contact = $this->createForm(ContactType::class, $contact);
        $form_contact->handleRequest($request_contact);
        
        if($form_contact->isSubmitted() && $form_contact->isValid())
        {
            $contact = $form_contact->getData();
            $this->addFlash('success', 'votre email à été acheminer à Enove');
            $message = (new \Swift_Message('Nouveau contact'))
                // On attribue l'expéditeur
                ->setFrom($contact->getEmail())
                // On attribue le destinataire
                ->setTo('[email protected]')
                // On crée le texte avec la vue
                ->setBody(
                    $this->renderView(
                        'emails/contact.html.twig', compact('contact')
                    ),
                    'text/html'
                )
            ;
            $mailer->send($message);
            return $this->redirectToRoute('enove_index' ,
            [
                'produits' => $produit,
                'form_filter' => $form_filter->createView(),
                'evvs' =>$evv,
            ] );
        }
        $form_devis = $this->createForm(ContactDevisType::class, $contactdevis);
        $form_devis->handleRequest($request_devis);

        if($form_devis->isSubmitted() && $form_devis->isValid())
        {
            $contactdevis = $form_devis->getData();
            $this->addFlash('success', 'votre email à été acheminer à Enove');
            $message2 = (new \Swift_Message('Devis'))
                // On attribue l'expéditeur
                ->setFrom($contactdevis->getEmail())
                // On attribue le destinataire
                ->setTo('[email protected]')
                // On crée le texte avec la vue
                ->setBody(
                    $this->renderView(
                        'emails/contact_devis.html.twig', compact('contactdevis')
                    ),
                    'text/html'
                )
            ;
            $mailer->send($message2);
            //dd($contactdevis);
            return $this->redirectToRoute('enove_index' ,
            [
                'produits' => $produit,
                'form_filter' => $form_filter->createView(),
                'evvs' =>$evv,
            ] );
        }
        //dump($request->request);

        return $this->render(
                            'FrontEndEnove/index.html.twig',
                            [
                                'produits' => $produit,
                                'form_filter' => $form_filter->createView(),
                                'form_contact' => $form_contact->createView(),
                                'form_devis' => $form_devis->createView(),
                                'evvs' => $evv,
                            ]
                            );

    }
}

Solution

  • Well in my case I changed the ProductRpository with adding this

    $query = $query->getQuery();
        
        $pagination = $this->paginator->paginate($query,$search->page,6);
        $pagination->setParam('_fragment', 'projects');
       return $pagination;
    

    and the problem was still here, guess what I had a problem in template, the jQuery was forcing it to go back to the top I just had to delete it.