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

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Exemple simple pour intégrer dataTable avec symfony2
Par phpiste

Le , par phpiste

0PARTAGES

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
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
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
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
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

Une erreur dans cette actualité ? Signalez-le nous !