Bonjour,

Après lecture de la documentation de cakephp2, je ne comprend toujours pas le fonctionnement de la pagination en ajax.

Pouvez vous m'expliquer ?

Merci d'avance

6 réponses


BenFarhat
Réponse acceptée

Juste pour info la pagination est hyper-simple
au niveau controller tu dois faire un truc du genre suivant (ici c'est pour l'action index)

public function index() {
$this->set('title_for_layout',"TITRE DE TA PAGE");
$this->MODEL->recursive = 0; // tu changes MODEL avec le nom de ton model genre: Pots, User, Produit etc....
$this->paginate = array(
'limit' => 20, // la tu met le nombre d'élements par page
'order' => array('champ' => 'asc'), // ici tu met à la place de champ le nom du "champ" surlequel tu veut faire un tri (ASC ou DESC)
);
$this->set('data', $this->paginate());
}

puis dans ta vue (ici ce sera /app/View/MODEL/index.ctp tu mets ceci

....
<hr />
    <table cellpadding="0" cellspacing="0" class="table table-bordered table-hover">
    <tr>
        <th><?php echo $this->Paginator->sort('id','id'); ?></th>
        <th><?php echo $this->Paginator->sort('name','nom'); ?></th>
            <th><?php echo $this->Paginator->sort('champ1','titre champ1'); ?></th>
        <th><?php echo $this->Paginator->sort('champ2','titre champ2'); ?></th>
        <th>Opérations</th>
    </tr>
    <?php
    foreach ($data as $poste): ?>
    <tr>
        <td><?php echo h($poste'MODEL']'id']); ?> </td>
        <td><?php echo h($poste'MODEL']'name']); ?> </td>
                <td><?php echo h($poste'MODEL']'champ1']); ?> </td>
                <td><?php echo h($poste'MODEL']'champ2']); ?> </td>
        <td class="actions">
            <?php echo $this->Html->link('<i class="icon-eye-open icon-white"></i> Consulter', array('action' => 'view', $poste'MODEL']'id']),array('escape'=>false,'class'=>'btn btn-success')); ?>
            <?php echo $this->Html->link('<i class="icon-pencil icon-white"></i> Editer', array('action' => 'edit', $poste'MODEL']'id']),array('class'=>'btn btn-info','escape'=>false)); ?>
            <?php echo $this->Form->postLink('<i class="icon-remove icon-white"></i> Effacer', array('action' => 'delete', $poste'MODEL']'id']),array('class'=>'btn btn-danger','escape'=>false), __(Configure::read('message.msg_verifsupprimer').'# %s?', $poste'MODEL']'id'])); ?>
        </td>
    </tr>
        <?php endforeach; ?>
    </table>
    <div class="alert alert-info">
    <?php
    echo $this->Paginator->counter(array(
    'format' => __('Page <strong>{:page}</strong> sur<strong>{:pages}</strong>, affichage de <strong>{:current}</strong> sur un total de <strong>{:count}</strong>, premier <strong>{:start}</strong>, Dernier <strong>{:end}</strong>')
    ));
    ?>  </div>
    <div class="pager">
    <?php
        echo $this->Paginator->prev('<< ', array('tag'=>'li'), null, array('tag'=>'li','class' => 'disabled'));
        echo $this->Paginator->numbers(array('separator' => ''));
        echo $this->Paginator->next(' >>', array('tag'=>'li'), null, array('tag'=>'li','class' => 'disabled'));
    ?>
    </div>
    ....

A présent pour ce qui est de Ajax ca se passe en faite dans le controller avec un petit indice qui viens de ton interface (ta vue)
Donc pour l'indice tu va sous le repertoire app/view/layout et dans le fichier default.ctp (qui contient ton template) tu cherches les lignes suivantes:
<div id="content">
<?php echo $content_for_layout; ?>
</div>
et la pour l'indice ca t'indique que le contenu sera chargé ton un div ayant l'id "content" (noté #div en selecteur css ou jQuery)

puis pour l'ajax tu as juste à dire ou se fera l'update et tu lui donne l'id précédemment trouvé

$this->Paginator->options(array(
    'update' => '#content', // Ca c'est l'id de la div ou sera afficher le contenu de tes pages tu le trouve dans la vue default.ctp sous le repertoire app/view/layout
    'evalScripts' => true, // ca c'est pour dire que si dans le code de retour ou la page de retour chargé par ajax il y a un script, est ce qu'il doit l'evaluer/executer ou non
    'before' => $this->Js->get('#busy-indicator')->effect('fadeIn', array('buffer' => false)), // ca c'est dans la doc et en gros ca veut dire avant d'aller chercher les pages demande affiche (avec l'effet fade/fondu) la div dont l'id est #busy-indicator et qui contient en principe le message de "chargement des données) Pour info au niveau de css tu dois avoir ceci #busy-indicator{display:none;} pour que cet element soit caché
    'complete' => $this->Js->get('#busy-indicator')->effect('fadeOut', array('buffer' => false)), // la c'est pour faire disparaitre l'element busy-indicator quand les données on été chargé
));

Et rappelle toi de mettre en haut du controller ou tu as mis ce code d'importer les components et helpers suivant

public $components = array('RequestHandler');
public $helpers = array('Js');

Voila, le mieux et d'essayer, quitte a t’emmêler les pinceaux... sur le tas ca deviens bien plus claire

Ok, merci pour les informations :)

Sauf que pour moi, il ne change rien en ajax mais tout en brute (la pages et non la div)

<div class="text-centered">
 <?php $this->Paginator->options(array(
    'update' => '#searchtutoriel', // Ca c'est l'id de la div ou sera afficher le contenu de tes pages tu le trouve dans la vue default.ctp sous le repertoire app/view/layout
    'evalScripts' => true, // ca c'est pour dire que si dans le code de retour ou la page de retour chargé par ajax il y a un script, est ce qu'il doit l'evaluer/executer ou non
    'before' => $this->Js->get('#busy-indicator')->effect('fadeIn', array('buffer' => false)), // ca c'est dans la doc et en gros ca veut dire avant d'aller chercher les pages demande affiche (avec l'effet fade/fondu) la div dont l'id est #busy-indicator et qui contient en principe le message de "chargement des données) Pour info au niveau de css tu dois avoir ceci #busy-indicator{display:none;} pour que cet element soit caché
    'complete' => $this->Js->get('#busy-indicator')->effect('fadeOut', array('buffer' => false)), // la c'est pour faire disparaitre l'element busy-indicator quand les données on été chargé
)); ?>
            <?php echo $this->Paginator->numbers(array('model' => 'Tutoriel')); ?>
     </div>

cela vient de quoi ?

Euh?? pas trop bien compris c'est quoi ce que tu as mis??? Ce bout de code la: [code] <?php $this->Paginator->options(array( 'update' => '#searchtutoriel', // Ca c'est l'id de la div ou sera afficher le contenu de tes pages tu le trouve dans la vue default.ctp sous le repertoire app/view/layout 'evalScripts' => true, // ca c'est pour dire que si dans le code de retour ou la page de retour chargé par ajax il y a un script, est ce qu'il doit l'evaluer/executer ou non 'before' => $this->Js->get('#busy-indicator')->effect('fadeIn', array('buffer' => false)), // ca c'est dans la doc et en gros ca veut dire avant d'aller chercher les pages demande affiche (avec l'effet fade/fondu) la div dont l'id est #busy-indicator et qui contient en principe le message de "chargement des données) Pour info au niveau de css tu dois avoir ceci #busy-indicator{display:none;} pour que cet element soit caché 'complete' => $this->Js->get('#busy-indicator')->effect('fadeOut', array('buffer' => false)), // la c'est pour faire disparaitre l'element busy-indicator quand les données on été chargé )); ?>[/code] ne doit pas être dans la vue mais dans le controlleur dans ton cas ca doit être le fichier /App/Controller/TutorielsController.php Si ca ne te dérange pas ca serait bien que tu me mettes une copie du contenu de App/Controller/TutorielsController.php App/Model/Tutoriel.php App/View/tutoriels/index.php Merci :) Sinon revisionne les tutoriels fait par jonhatan: [url=http://www.grafikart.fr/tutoriels/cakephp]http://www.grafikart.fr/tutoriels/cakephp[/url] Si je peut me permettre... je penses que le plus gros a faire est de comprendre Cake dans son principe Tu as des conventions à suivre: si tu les suit; tu as moins de code à faire et cake fait pour toi ce que tu doit coder à la main pendant de longue heures parsemées de café et de pauses anti-stress à regarder sa série préférée [url=http://book.cakephp.org/2.s0/fr/getting-started/cakephp-conventions.html]http://book.cakephp.org/2.0/fr/getting-started/cakephp-conventions.html[/url] Ensuite tu as trois parties, MVC Prenon l'exemple d'un resto M c'est le contenu, (le poisson, les legumes, les fruits les jus etc...) C c'est le controlleur, le cuisinier à l'arrière du resto V c'est la vue (sans vouloir être macho c'est la belle serveuse qui soigne sa présentation et te ramène sur un plateau ce que tu as demandé et qu'a préparé le cuisto à l'arrière** Dans ton cas, la ou tu met l'affichage (le titre, les tableaux, les menus, photos etc....) c'est dans View Pour définir comment se présente tes Tutos (l'id, le titre, la date de publication, le contenu du tuto...) c'est dans Model (les données sont dans ta base pas dans le fichier model qui ne fait que décrire et gérer ta base par exemple en faisant toit même quand ca t'arrange tes contrôles d'intégrité) Pour ce qui est de traité ces informations et les founir à la vue c'est dans Controlleur, toi quand tu parles de Pagination en ajax tu parle de la fonction réelle de paginer et de rapporter les données par 20 et dans ton cas en utilisant ajax, c'est donc dans le controlleur) Quand tu parle de la pagination en tant que lien qui seront afficher sur ton appli ou site web c'est dans la vue. Avant de finir rappelle toi qu'il y a des élements qui étendent ou améliore le principe de l'MVC (dans le sens ou ces élements rajoutent des fonctionnalités ou aides a faire plus facilement quelquechose) Si tu veux QUELQUECHOSE qui améliore tes VUES, ca s'appelle HELPERS et tu les trouves dans le repertoire View/Helpers par exempe Form qui te permette trés rapidement de faire des formulaire et qui automatiquement rajoute les champs ou seront affichés les messages d'erreurs ect... Si tu veux QUELQUECHOSE qui améliore tes Controlleurs, ca s'appelle COMPONENTS et tu les trouves dans le repertoir Controller/Component Par exemple ACL et AUTH qui te permet avant de faire une opération sur les données ou de t'afficher une vue de vérifier si tu en as le droit Si tu veux QUELQUECHOSE qui améliore ton model ca s'appelle BEHAVIOR et tu les trouves dans Model/Behavior Si par contre tu as quelqueschoses qui améliore deux ou trois choses à la fois (c'est en même temps un behavior et/ou un component et/ou un helpers alors on parle de PLUGIN et c'est dans App/Plugins que ca se trouve Si jamais tu veut un plugins on va dire qui ne suit pas les conventions de cakephp ca sera dans Vendors, par exemple tout en développant avec Cake tu peux très bien utiliser les classes fournies par le framework Zend :) :)

En faite c'est que le je fait un système de recherche dans plusieurs model ( Post, Tutoriel et Review ) et les résultats sont présents dans la même pages mais trier par type (model) et en dessous de chaque model, il y a la pagination qui est présente et je voudrais que sa change que les contenu via ajax du model et non toute la pages.

Pour les récupérations des résultats je fait comme ce-ci

<?php 
class SearchsController extends AppController{

    public $components = array('RequestHandler');
    public $helpers = array('Js');

    public function beforefilter(){
        parent::beforeFilter();
        $this->Auth->allow('index');
    }

    public $uses = array('Tutoriel','Post','Review');

    public $paginate = array(
    'Post' => array(
        'limit' => 1,
        'order' => array(
            'Post.created' => 'desc'
        ),
        'fields' => array(
           'Post.id', 'Post.title', 'Post.slug', 'Post.id_category','Post.id_author', 'Post.created', 'Post.online', 'Post.img_preview', 'Category.name', 'User.username'
            )
        ),
     'Review' => array(
        'limit' => 1,
        'order' => array(
            'Review.created' => 'desc'
            ),
        'fields' => array(
           'Review.id', 'Review.title', 'Review.slug', 'Review.id_category','Review.id_author', 'Review.created', 'Review.online', 'Review.img-preview', 'Category.name', 'User.username'
            )
        ),
     'Tutoriel' => array(
        'limit' => 1,
        'order' => array(
            'Tutoriel.created' => 'desc'
            ),
        'fields' => array(
           'Tutoriel.id', 'Tutoriel.title', 'Tutoriel.slug', 'Tutoriel.id_category','Tutoriel.id_author', 'Tutoriel.created', 'Tutoriel.online', 'Tutoriel.img_preview', 'Category.name', 'User.username'
            )
        )
    );

    function index(){
        if(!empty($this->request->data'Search']'searchentry'])){
            $search = $this->request->data'Search']'searchentry'];    
            Controller::paginate();
            $datapost = $this->paginate('Post', array('Post.title LIKE' => '%'.$search.'%', 'Post.online' => 1));
            $datareview = $this->paginate('Review', array('Review.title LIKE' => '%'.$search.'%', 'Review.online' => 1));
            $datatutoriel = $this->paginate('Tutoriel', array('Tutoriel.title LIKE' => '%'.$search.'%', 'Tutoriel.online' => 1));
            $this->set('searchpost', $datapost);
            $this->set('searchreview', $datareview);
            $this->set('searchtutoriel', $datatutoriel);
        }else{
        }
    }

}

?>

hmmm :)
A force de trop écrire j'ai du mal me faire comprendre et je m'en excuse :)

bien... je pense savoir ou se situe ton problème:
primo tu doit mettre ceci

<?php $this->Paginator->options(array(
    'update' => '#searchtutoriel',
    'evalScripts' => true, 
    'before' => $this->Js->get('#searchtutoriel')->effect('fadeOut', array('buffer' => false)),
    'complete' => $this->Js->get('#searchtutoriel')->effect('fadeIn', array('buffer' => false)), 
)); ?>

cela devrait en principe faire un fondu sur le div dont l'id est searchtutoriel, puis le refaire apparaitre doucement des que ta page est chargé

ensuite je pense a ton layout de base

Ensuite pour éviter que la page chargé viennent avec le gabarit qui est autour il faut dire à cakephp au niveau de ton controleur SearchsController ou carrément dans l'AppController je veut les donné seulement et je vais les mettre dans le div searchtutoriel sans le reste, pour ceci tu doit avoir ces lignes qui en gros dise si j'utilise ajax (ici on utilise RequestHandler pour le savoir) je ne veux pas de gabarait (layout) autour des données à afficher

public function beforeFilter() {
        if($this->RequestHandler->isAjax()){
            $this->layout=null;
            Configure::write('debug', 0);
        }

puis la ou je me pose la question c'est au niveau de ton ajax, cakephp va créer un code qui va dire un truc du genre SI JE CLICQUE ICI CHARGE LE LIENS ET MET LE DANS CA!!! bref ce code cakephp a besoin de savoir ou l'écrire, généralement on demande dans le répertoire View/layout sous le fichier default.ctp de mettre juste avant la fermeture de la balise html cette ligne <?php echo $this->Js->writeBuffer();?>

...
    <?php echo $this->Js->writeBuffer();?> 
  </body>
</html>

J'espère que cela résoudra ton problème :)