KnpPaginatorBundle with JQuery partial postback

This post continues the previous post Pagination in Symfony2 with KnpPaginatorBundle.

First of all you should add JQuery to your twig template. I recommend that you do not download JQuery and put it in your assets, but instead include it in your header like this:

That will save you some bandwith and there is a big chance that the browser visiting your site already has the jquery-latest.min.js already in it’s cache.

Partial postbacks will speed up the user experience since we do not need to reload the whole page everytime we change page in the pagination, just the table. So first we need to do is create a new route that can handle the postback and in the same time we need to keep the old route’s functionality in case that the browser client do not have javascript. So lets start with the controller.

 * Lists all Person entities.
 * @Route("/", name="person")
 * @Template()
public function indexAction()
    return array('paginator' => $paginator);


 * Lists all Person entities.
 * @Route("/personListPostBack/", name="person_list_postback")
 * @Template()
public function generatePersonListPostbackAction(){
    return $this->render('MLKBackEndBundle:Person:_personList.html.twig', array('paginator' => $paginator));

 * Generates the personList
 * @return \Zend\Paginator\Paginator 
private function getList(){
    $em = $this->getDoctrine()->getEntityManager();
    $dql = "Select a from MLKBackEndBundle:Person a";
    $query = $em->createQuery($dql);

    $adapter = $this->get('knp_paginator.adapter');

    $paginator = new \Zend\Paginator\Paginator($adapter);
    $paginator->setCurrentPageNumber($this->get('request')->query->get('page', 1));
    return $paginator;

Now lets update the view:

{% extends '::base.html.twig' %}
{% block body %}

Person list

{% include 'MLKBackEndBundle:Person:_personList.html.twig' %}
{% endblock %} {% block javascripts %} {% endblock %}

As you can see the table generation has been moved to _personList.html.twig and if you have a look in the PersonController you can see that the generatePersonListPostbackAction also uses that twig.

If we look at the javascript we can see that it looks for elements with the class paginator and then finds the a attribues that are inside of them (as in <a href). When a link are clicked it updates the content of the element with the id person_list with what is returned from the url that is stored in the javascript variable link.

The link is created with twigs path function (that echos the url of the route) and then we add the original post data from the url with the help of an regular expression.

Wow that was quite alot of information. Lets have a look at the _personList.html.twig and see if we can round everything up.

    {% for entity in paginator %}
    {% endfor %}
{{ paginator|sortable('Id', '') }} {{ paginator|sortable('Firstname', 'a.firstName') }} {{ paginator|sortable('Lastname', 'a.lastName') }} {{ paginator|sortable('Birthday', 'a.birthday') }} Actions
{{ }} {{ entity.firstName }} {{ entity.lastName }} {% if entity.birthday %}{{ entity.birthday|date('Y-m-d') }}{% else %}No Value{% endif %}
{{ paginator|paginate }}

As you can see not much have changed here, the class of the headers get set to “pagination” and as you might have noticed in the first part when the paginator is rendered it creates a div with the class “paginator” so we do not need to add anything there.

That was alot of information but hopefully you understandeverything. If not, please feel free to post your questions here below or at #symfony @

May the force be with you!

Leave a Reply

  • (will not be published)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>