Pregunta

Así que estoy haciendo esto en PHP, pero es un problema lógico, así que intentaré escribirlo de la forma más genérica posible.

Para comenzar, así es como funciona este script de paginación:

  1. para ( dibujar los enlaces de las primeras tres páginas )
  2. if ( puntos suspensivos (...) si hay páginas entre las páginas # 1 y # 3 )
  3. para ( dibujar la página actual y dos páginas a cada lado de los enlaces )
  4. if ( dibujar puntos suspensivos (...) si hay páginas entre las páginas # 3 y # 5 )
  5. para ( dibujar enlaces finales de tres páginas )

El problema es que cuando hay pocas cantidades de páginas (lo noté cuando el recuento de páginas era de 10) debería haber puntos suspensivos pero no se dibuja ninguno.

Sobre el código:

$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;
}

Así que creo que la mejor idea sería modificar una de las dos elipsis si las declaraciones incluyen un caso como este, sin embargo, lo he intentado y estoy perplejo.

También tenga en cuenta que condensé este código por razones de legibilidad, así que no dé consejos como " los bucles son ineficaces porque volverán a calcular current_page - 2 para cada iteración " porque lo sé :)


Para aquellos que desean ver un desglose de cómo funciona actualmente esta lógica, aquí hay un ejemplo de salida (modificado) con iteración $ page_count y $ current_page. http://rafb.net/p/TNa56h71.html

¿Fue útil?

Solución

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

Otros consejos

Esta es probablemente una solución demasiado complicada, pero funciona.

He usado una matriz aquí en lugar de solo imprimir, lo que me permite "hacer más". la lógica.

Parte del problema ocurre cuando " izquierda y derecha de la página " pasa a coincidir con los hombros izquierdos y derechos.

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 salida se puede ver aquí: http://dpaste.com/92648/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top