IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

phpiste

[Actualité] Exemple simple pour intégrer dataTable avec symfony2

Noter ce billet
par , 21/04/2015 à 12h27 (3005 Affichages)
Prérequis de l'exemple :
Pour réaliser l'exemple vous devez disposer:
D'un projet symfony2 déjà en place
une base de donnée

J'ai utilisé le bundle AcmeDemoBundle automatiquement installé avec la commande
symfony new

Bundle existant
Pour info il existe deux supers bundles existant qui marchent très bien
https://github.com/stwe/DatatablesBundle
https://github.com/AliHichem/AliDatatableBundle
Dans notre exemple on va rester simple et le plus découplé possible coté vue qui sera facilement changeable par une autre purement html totalement isolé du site symfony2 (ce dernier jouera seulement le rôle de fournisseur d'api)

Présentation du plugin dataTable
Le plugin datatable offre une manière élégante pour transformer des tableaux purement html en un tableau riche en fonctionnalités (Pagination, tri, filtrage, ...) avec un minimum de code JavaScript.
Je ne vais trop rentrer en détail car la doc officiel du script est largement complète.
Lien vers la doc.

Problématique:
par contre en travaillant avec cette librairie vous remarquerez que si le nombre de données à gérer augmente, la page rame et les interactions perdent leurs fluidités.

Solutions:
Récupérer en ajax les données du tableau

Pour cela voici le code source de l'exemple (j'ai essayé de rester le plus simple possible) qui couvre cette fonctionnalité de datatable (Server side processing)

@le Modele
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
 
namespace Acme\DemoBundle\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * User
 *
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\UserRepository")
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
 
    /**
     * @var string
     *
     * @ORM\Column(type="string")
     */
    private $name;
 
    /**
     * @var string
     *
     * @ORM\Column(type="datetime")
     */
    private $createdAt;
 
    public function __construct()
    {   
        $this->createdAt = new \dateTime('now');
    }
 
    public function getId() 
    {
        return $this->id;
    }
 
    public function getName() 
    {
        return $this->name;
    }
 
    public function getCreatedAt() 
    {
        return $this->createdAt;
    }
}
@La Vue
Code twig : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{% extends "AcmeDemoBundle::layout.html.twig" %}
 
{% block head %}
{{ parent() }}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.6/css/jquery.dataTables.min.css" />
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://cdn.datatables.net/1.10.6/js/jquery.dataTables.min.js"></script>
<script>
$(function() {
  $('#user-list').DataTable({
        "processing": true,
        "serverSide": true,
        "ajax": "{{ path('user_paginate') }}",
        "sAjaxDataProp": "data",
        "pageLength": 10,
        "columns":[
            {"data": "id"},
            {"data": "name"},
            {"data": "created_at"}
        ]
    });
});
</script>
{% endblock %}
 
{% block body %}
 
<table id="user-list">
    <thead>
        <tr>
            <th>ID</th>
            <th>Nom</th>
            <th>Crée le</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>
{% endblock %}

@Le Controlleur
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
 
namespace Acme\DemoBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 
class UserController extends Controller
{
    /**
     * @Route("/list", name="user_list")
     */
    public function indexAction()
    {
        return  $this->render('AcmeDemoBundle:User:index.html.twig',array());  
    }
 
    /**
     * @Route("/paginate", name="user_paginate")
     */
    public function paginateAction(Request $request)
    {
        $length = $request->get('length');
        $length = $length && ($length!=-1)?$length:0;
 
        $start = $request->get('start');
        $start = $length?($start && ($start!=-1)?$start:0)/$length:0;
 
        $search = $request->get('search');
        $filters = [
            'query' => @$search['value']
        ];
 
        $users = $this->getDoctrine()->getRepository('AcmeDemoBundle:User')->search(
            $filters, $start, $length
        );
 
        $output = array(
            'data' => array(),
            'recordsFiltered' => count($this->getDoctrine()->getRepository('AcmeDemoBundle:User')->search($filters, 0, false)),
            'recordsTotal' => count($this->getDoctrine()->getRepository('AcmeDemoBundle:User')->search(array(), 0, false))
        );
 
        foreach ($users as $user) {
            $output['data'][] = [
                'id' => $user->getId(),
                'name' => $user->getName(),
                'created_at' => $user->getCreatedAt()->format('Y-m-d'),
            ];
        }
 
        return new Response(json_encode($output), 200, ['Content-Type' => 'application/json']);
    }
}
@La requette
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
namespace Acme\DemoBundle\Repository;
 
use Doctrine\ORM\EntityRepository;
 
class UserRepository extends EntityRepository
{
    public function search($data, $page = 0, $max = NULL, $getResult = true)
    {
        $qb = $this->_em->createQueryBuilder();
        $query = isset($data['query']) && $data['query']?$data['query']:null;
 
        $qb
            ->select('u')
            ->from('AcmeDemoBundle:User', 'u')
        ;
 
        if ($query) {
            $qb
                ->andWhere('u.name like :query')
                ->setParameter('query', "%".$query."%")
            ;
        }
 
        if ($max) {
            $preparedQuery = $qb->getQuery()
                ->setMaxResults($max)
                ->setFirstResult($page * $max)
            ;
        } else {
            $preparedQuery = $qb->getQuery();
        }
 
        return $getResult?$preparedQuery->getResult():$preparedQuery;
    }
}
@Raffinnement
  • Améliorer la récupération des résultats (getSingleScalarResult au lieux du count)
  • Alléger le contrôleur
  • Ajouter le tri des résultats
  • Formater les cellules d'une façon particulière
  • Ajouter les actions
  • Ajouter des actions groupées (bash actions)


@Todo
Test !!

@Code source sur github
très bientôt disponible

Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Viadeo Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Twitter Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Google Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Facebook Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Digg Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Delicious Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog MySpace Envoyer le billet « Exemple simple pour intégrer dataTable avec symfony2 » dans le blog Yahoo

Mis à jour 09/09/2018 à 15h11 par LittleWhite (Coloration du code)

Catégories
Javascript , PHP , Développement Web , symfony2

Commentaires

  1. Avatar de bastar911
    • |
    • permalink
    Je vous remercie pour ce précieux tuto !

    Thx !
  2. Avatar de mojowork
    • |
    • permalink
    Ca n'est pas
    select('m')
    mais
    select('u')

    et merci beaucoup pour ce tuto qui me sauve la vie
  3. Avatar de medas8918
    • |
    • permalink
    Bonjour,
    est ce normal que j'ai comme affichage le json?
  4. Avatar de phpiste
    • |
    • permalink
    fixed !
    thanks.
    Citation Envoyé par mojowork
    Ca n'est pas
    select('m')
    mais
    select('u')

    et merci beaucoup pour ce tuto qui me sauve la vie