2008-11-21 10 views
2

Donc je le fais en PHP mais c'est un problème de logique donc je vais essayer de l'écrire aussi génériquement que possible.Problème de pagination [PHP]

Pour commencer voici comment fonctionne ce script Pagination:

  1. pour (piochez trois premières pages liens)
  2. si (tirage de (...) s'il y a des pages entre les pages de # 1 et # 3 pages de)
  3. pour (dessiner page en cours et deux pages de chaque côté de celui-ci relie)
  4. si (dessiner elipsis (...) s'il y a des pages entre les pages 3 et les pages de # 5)
  5. pour (piochez trois dernières pages Liens)

Le problème est que quand il y a de faibles quantités de pages (je l'ai remarqué lorsque le nombre de pages était à 10) il devrait y avoir une ellipse mais aucun n'est dessiné.

Sur le code:

$page_count = 10; //in actual code this is set properly 
$current_page = 1; //in actual code this is set properly 

for ($i = 1;$i <= 3;$i++) 
{ 
    if ($page_count >= $i) 
     echo $i; 
} 

if ($page_count > 3 && $current_page >= 7) 
    echo "..."; 

for ($i = $current_page - 2;$i <= current_page + 2;$i++) 
{ 
    if ($i > 3 && $i < $page_count - 2) 
     echo $i; 
} 

if ($page_count > 13 && $current_page < $page_count - 5) 
    echo "..."; 

for ($i = $page_count - 2;$i <= $page_count;$i++) 
{ 
    if ($page_count > 3) 
     echo $i; 
} 

Je figure la meilleure idée serait d'être de modifier l'un des deux points de suspension si les déclarations d'inclure un cas comme celui-ci, mais je l'ai essayé et je suis perplexe.

s'il vous plaît Notez également que je condensé ce code pour l'amour de lisibilité si s'il vous plaît ne pas donner des conseils comme « ceux pour les boucles sont inefficaces parce qu'ils recalcule CURRENT_PAGE - 2 pour chaque itération » parce que je sais :)


Pour ceux qui veulent voir comment fonctionne cette logique, voici un exemple de sortie (modifiée) avec itération $ page_count et $ current_page. http://rafb.net/p/TNa56h71.html

+0

Ce n'est pas un problème de PHP! Merci de ne pas ajouter de balise PHP car l'exemple de code n'est même pas écrit en PHP! –

+0

Vous pouvez fournir un code d'exemple * working * afin que les personnes qui veulent tester leur propre logique n'aient pas à ré-implémenter votre code 'psuedo' dans leur propre langue juste pour pouvoir le tester. –

+0

Ok je l'ai changé en code PHP:/ –

Répondre

5
<?php 

/** 
* windowsize must be odd 
* 
* @param int $totalItems 
* @param int $currentPage 
* @param int $windowSize 
* @param int $anchorSize 
* @param int $itemsPerPage 
* @return void 
*/ 
function paginate($totalItems, $currentPage=1, $windowSize=3, $anchorSize=3, $itemsPerPage=10) { 
    $halfWindowSize = ($windowSize-1)/2; 

    $totalPages = ceil($totalItems/$itemsPerPage); 
    $elipsesCount = 0; 
    for ($page = 1; $page <= $totalPages; $page++) { 
     // do we display a link for this page or not? 
     if ($page <= $anchorSize || 
      $page > $totalPages - $anchorSize || 
      ($page >= $currentPage - $halfWindowSize && 
      $page <= $currentPage + $halfWindowSize) || 
      ($page == $anchorSize + 1 && 
      $page == $currentPage - $halfWindowSize - 1) || 
      ($page == $totalPages - $anchorSize && 
      $page == $currentPage + $halfWindowSize + 1)) 
     { 
      $elipsesCount = 0; 
      if ($page == $currentPage) 
       echo ">$page< "; 
      else 
       echo "[$page] "; 
     // if not, have we already shown the elipses? 
     } elseif ($elipsesCount == 0) { 
      echo "... "; 
      $elipsesCount+=1; // make sure we only show it once 
     } 
    } 
    echo "\n"; 
} 

// 
// Examples and output 
// 

paginate(1000, 1, 3, 3); 
// >1< [2] [3] ... [98] [99] [100] 

paginate(1000, 7, 3, 3); 
// [1] [2] [3] ... [6] >7< [8] ... [98] [99] [100] 

paginate(1000, 4, 3, 3); 
// [1] [2] [3] >4< [5] ... [98] [99] [100] 

paginate(1000, 32, 3, 3); 
// [1] [2] [3] ... [31] >32< [33] ... [98] [99] [100] 

paginate(1000, 42, 7, 2); 
// [1] [2] ... [39] [40] [41] >42< [43] [44] [45] ... [99] [100] 
+0

Bonne réponse - J'utilise maintenant une version légèrement édulcorée car je n'en ai pas besoin en tant que fonction car certaines de vos variables sont constantes dans la mienne. Notez qu'il y a un bug; vous devez changer "- 1" et "+ 1" sur les lignes 25 et 27 respectivement à "- 2" et "+ 2" –

2

Ceci est probablement une solution trop compliquée, mais cela fonctionne.

J'ai utilisé un tableau ici au lieu de simplement imprimer, ce qui me permet de "faire" la logique.

Une partie du problème se produit lorsque «gauche et droite de la page» coïncide avec les épaules gauche et droite.

function cdotinator ($current_page, $page_count) 
{ 
    $stepsize = 3; 
    $elipse = '...'; 
    # Simple Case. 
    if ($page_count <= 2 * $stepsize) 
    { 
    $out = range(1, $page_count); 
    $out[$current_page - 1 ] = '*' . $current_page . '*'; 
    return $out; 
    } 
    #Complex Case 
    # 1) Create All Pages 
    $out = range(1, $page_count); 
    # 2) Replace "middle" pages with "." placeholder elements 
    for($i = $stepsize+1 ; $i <= ($page_count - $stepsize) ; $i ++) 
    { 
    $out[ $i - 1 ] = '.' ; 
    } 
    # 3.1) Insert the pages around the current page 
    for($i = max(1,($current_page - floor($stepsize/2))) ; 
     $i <= min($page_count,($current_page + floor($stepsize/2))); 
     $i ++) 
    { 
    $out[ $i - 1] = $i; 
    } 
    # 3.2 Bold Current Item 
    $out[ $current_page - 1 ] = '*' . $current_page . '*' ; 

    # 4) Grep out repeated '.' sequences and replace them with elipses 
    $out2 = array(); 
    foreach($out as $i => $v) 
    { 
    # end, current == peek() 
    end($out2); 
    if(current($out2) == $elipse and $v == '.') 
    { 
     continue; 
    } 
    if($v == '.') 
    { 
     $out2[] = $elipse; 
     continue; 
    } 
    $out2[]= $v; 
    } 

    return $out2; 

} 

La sortie peut être vu ici: http://dpaste.com/92648/