Pagination intelligente

Par shadowkamikaze, il y a 9 ans


Bonjour,

Je voudrais faire une pagination intelligente, c'est à dire exactement comme le site de Grafikart
Comme ceci :
Pagination intelligente

Mon code actuel affiche la pagination classique (toute les pages)

Mon contrôleur :

$res = $this->Post->query("SELECT COUNT(id) AS nbPosts FROM posts"); $nbPosts = intval($res[0]->nbPosts); $perPage = 1; $nbPages = ceil($nbPosts / $perPage); if (isset($_GET["p"]) && intval($_GET["p"]) !== 0 && intval($_GET["p"]) <= $nbPages) { $p = $_GET["p"]; } else { if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) { header("Location: " . $this->getRoute("admin.post.index")); } $p = 1; } $posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC LIMIT ".($p-1)*$perPage.",$perPage");

Ma vue :

<?php if ($nbPosts > $perPage) : ?> <div class="pagination" id="pagination"> <?php for ($i=1; $i < $nbPages+1; $i++) : ?> <?php if ($i === 1) : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>"><?= $i; ?></a> <?php else : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?= $i; ?></a> <?php endif; ?> <?php endfor; ?> </div> <?php endif; ?>

Le résultat :

Pagination classique

11 réponses

betaWeb, il y a 9 ans

Il te faut filtrer ça dans la boucle qui génère ta pagination, en n'affichant que les 3 premières et la dernière (par exemple).

<?php if ($nbPosts > $perPage) : ?> <div class="pagination" id="pagination"> <?php for ($i=1; $i < 4; $i++) : ?> <?php if ($i === 1) : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>"><?= $i; ?></a> <?php else : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?= $i; ?></a> <?php endif; ?> <?php endfor; ?> <div class="separator">...</div> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $nbPosts ; ?>"><?= $nbPosts ; ?></a> </div> <?php endif; ?>

C'est la version "sale", je te laisse refactorer ;)

AlexJM, il y a 9 ans

http://stackoverflow.com/questions/28240777/custom-pagination-view-in-laravel-5 regarde la deuxième partie de la première réponse. Certes c'est du blade, mais le blade n'est pas trop compliqué

Edit : finalement, essaye ça :

<?php // config $link_limit = 7; // maximum number of links (a little bit inaccurate, but will be ok for now) $last_page = X;// ton calcul doit trouver la dernière page $current_page = X;// ton calcul doit trouver la page courrante if ($last_page > 1): ?> <ul class="pagination"> <!-- DÉBUT : lien pour la première page --> <li class="<?= ($current_page == 1) ? ' disabled' : '' ?>"> <a href="/ton/lien/pour/la/premiere/page">First</a> </li> <!-- FIN : lien pour la dernière page--> <!-- DÉBUT : pagination 'intelligente' --> <?php for ($i = 1; $i <= $last_page; $i++): $half_total_links = floor($link_limit / 2); $from = $current_page - $half_total_links; $to = $current_page + $half_total_links; if ($current_page < $half_total_links) { $to += $half_total_links - $current_page; } if ($last_page - $current_page < $half_total_links) { $from -= $half_total_links - ($last_page - $current_page) - 1; } if ($from < $i && $i < $to): ?> <li class="<?= ($current_page == $i) ? ' active' : '' ?>"> <a href="/ton/lien/pour/la/$i eme/page"><?=$i?></a> </li> <?php endif; endfor; ?> <!-- FIN : pagination 'intelligente' --> <!-- DÉBUT : lien pour la dernière page --> <li class="<?= ($current_page == $last_page) ? ' disabled' : '' ?>"> <a href="/ton/lien/pour/la/dernière/page">Last</a> </li> <!-- FIN : lien pour la dernière page --> </ul> <?php endif; ?>

Je t'ai déjà adapté le code depuis du blade, à toi de le faire pour qu'il corresponde à ton code ;)

AlexJM, il y a 9 ans

Mis à part de remplacer ça :

if (isset($_GET["p"]) && intval($_GET["p"]) !== 0 && intval($_GET["p"]) <= $nbPages) { $p = $_GET["p"]; } else { if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) { header("Location: ".$this->getRoute("admin.post.index")); } $p = 1; } $currentPage = intval($p);

par ça :

if (isset($_GET["p"]) && intval($_GET["p"]) > 0 && intval($_GET["p"]) <= $nbPages) { $currentPage = intval($_GET["p"]); } else { if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) { header("Location: ".$this->getRoute("admin.post.index")); } $currentPage = 1; }

Je pense pas

shadowkamikaze, il y a 9 ans

Oui j'ai zaaper cette variable ^^, j'ai fait la modification
Merci pour vos réponses et votre réactivité

shadowkamikaze, il y a 9 ans

AlexJM

Ton script fonctionne correctement, je l'ai adapté à mon application, cepandant il y a beaucoup de conditions ^^
Ton script manquait quelques vérifications rien de méchant.
S'il y a des choses à changer pour l'optimisation de mon code, dites le moi merci.

Voici mon code :

Contrôleur

public function index() { // Variables pour la pagination $res = $this->Post->query("SELECT COUNT(*) AS nbPosts FROM posts", "", true); $nbPosts = intval($res->nbPosts); $itemsPerPage = 1; $nbPages = intval(ceil($nbPosts / $itemsPerPage)); $nbLinks = 9; // Récupération du numéro de la page courante if (isset($_GET["p"]) && intval($_GET["p"]) > 0 && intval($_GET["p"]) <= $nbPages) { $currentPage = $_GET["p"]; } else { if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) { header("Location: ".$this->getRoute("admin.post.index")); } $currentPage = 1; } // Traitement de la pagination $halfTotalLinks = floor($nbLinks / 2); $start = $currentPage - $halfTotalLinks; $end = $currentPage + $halfTotalLinks; // Variables renvoyées à la vue $name = "posts"; $posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC LIMIT ".($currentPage - 1) * $itemsPerPage.",".$itemsPerPage); $category = $this->Category; $pagination = [ "nbPosts" => $nbPosts, "itemsPerPage" => $itemsPerPage, "lastPage" => $nbPages, "currentPage" => $currentPage, "nbLinks" => $nbLinks, "start" => $start, "end" => $end, "halfTotalLinks" => $halfTotalLinks ]; $this->setTitle("Articles"); $this->render("admin/posts/index", compact("name", "posts", "category", "pagination"), "admin"); }

Vue

<?php if ($pagination["nbPosts"] > $pagination["itemsPerPage"]) : ?> <ul class="pagination"> <li> <?php if ($pagination["currentPage"] === 1) : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>" class="active">1</a> <?php else: ?> <a href="<?= $this->getRoute("admin.post.index"); ?>">1</a> <?php endif; ?> </li> <?php if ($pagination["currentPage"] > $pagination["halfTotalLinks"] + 1) : ?> <li><span class="more">...</span></li> <?php endif; ?> <?php for ($i = 1; $i <= $pagination["lastPage"]; $i++) : ?> <?php if ($pagination["start"] < $i && $i < $pagination["end"]) : ?> <?php if ($i !== 1 && $i !== $pagination["lastPage"]) : ?> <li> <?php if ($pagination["currentPage"] === $i) : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>" class="active"><?=$i?></a> <?php else: ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?=$i?></a> <?php endif; ?> </li> <?php endif; ?> <?php endif; ?> <?php endfor; ?> <?php if ($pagination["currentPage"] < $pagination["lastPage"] - ($pagination["halfTotalLinks"] + 1)) : ?> <li><span class="more">...</span></li> <?php endif; ?> <li> <?php if ($pagination["currentPage"] === $pagination["lastPage"]) : ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $pagination["lastPage"]; ?>" class="active"><?= $pagination["lastPage"]; ?></a> <?php else: ?> <a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $pagination["lastPage"]; ?>"><?= $pagination["lastPage"]; ?></a> <?php endif; ?> </li> </ul> <?php endif; ?>
shadowkamikaze, il y a 9 ans

Pour compter le nombre de résultats, c'est quoi la solution la plus rapide ?

Une requête SQL :

$res = $this->Post->query("SELECT COUNT(*) AS nbPosts FROM posts", "", true); $nbPosts = intval($res->nbPosts);

Ou la fonction count de PHP

$nbPosts = count($this->Post->query("SELECT * FROM posts"));

Autre cas :

// Je fait ma requête SQL pour afficher mes articles $posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC"; // Pour compter les résultats une 2ème requête SQL ou la fonction count count($posts);
AlexJM, il y a 9 ans

l'autre cas car tu ne fais qu'une requête ;)

shadowkamikaze, il y a 9 ans

Et pour les 2 première solutions ?

AlexJM, il y a 9 ans

je dirais le count en SQL, surtout avec un grand nombre de données, avec un petit nombre c'est moins significatif je pense

shadowkamikaze, il y a 9 ans

Ok merci de ta réponse ^^

shadowkamikaze, il y a 9 ans

Sinon pour mes fichiers (la pagination) il y a moyen de les optimiser plus ?