Paginar consultas con MySQL, PHP y Ajax

Si desemos paginar los resultados de una consulta, podemos hacerlo con PHP y quedaría excelente, por ejemplo en la Portada de este Blog, en la parte final, se puede apreciar un ejemplo en acción. Sin embargo, si queremos que al momento de pasar de una página a otra no recarge toda la página sino solo el contenido que nos interesa. Para ello podemos hacer uso de Ajax.

Por ejemplo, nuestra tabla Empleados tiene como 150 registros, pero cargar esos 150 en una página web tomaría su tiempo. Así que es mejor si los mostramos por páginas o bloques de 10 registros (por ejemplo) , y colocamos el número de páginas en forma de enlaces para navegar por los todas las páginas. En el caso del ejemplo, sería algo de 15 páginas (150/10). Vamos a materializar nuestro aplicación, haciendo uso del lenguaje PHP, MySQL como gestor de Base de Datos y Ajax. Explicaré el objetivo que tiene cada archivo, aunque también incluyo comentarios en los script como para que se entienda mejor. Cualquier duda o pregunta, pueden hacerla con toda confianza.

[Ver el resultado final]

Vamos a trabajar con la tabla Empleados, la cual hemos venido usando en anteriores ejemplos. [Ver Tabla]. Los datos de la conexión a la Base de Datos se guardarán en el archivo conexion.php.

<?php
//Configuracion de la conexion a base de datos
$bd_host = "miservidor"; 
$bd_usuario = "miusuario"; 
$bd_password = "micontraseña"; 
$bd_base = "mibasededatos"; 
$con = mysql_connect($bd_host, $bd_usuario, $bd_password); 
mysql_select_db($bd_base, $con); 
?>

Ahora en un archivo JavaScript, el cual llamaremos ajax.js hacemos uso del objeto XMLHttpRequest para hacer peticiones al servidor sin necesidad de recargar toda una página web (está función hemos venido usandola en anteriores tutoriales). También, crearemos la función llamada Pagina(nroPagina), esta recibirá un valor correspondiente a un número de página y se enlazará con el archivo paginador.php para procesar ese número de página. Y el resultado se mostrará en la capa (<div>) "contenido".

function objetoAjax(){
 var xmlhttp=false;
  try{
   xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  }catch(e){
   try {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
   }catch(E){
    xmlhttp = false;
   }
  }
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
   xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

function Pagina(nropagina){
 //donde se mostrará los registros
 divContenido = document.getElementById('contenido');
 
 ajax=objetoAjax();
 //uso del medoto GET
 //indicamos el archivo que realizará el proceso de paginar
 //junto con un valor que representa el nro de pagina
 ajax.open("GET", "paginador.php?pag="+nropagina);
 divContenido.innerHTML= '<img src="anim.gif">';
 ajax.onreadystatechange=function() {
  if (ajax.readyState==4) {
   //mostrar resultados en esta capa
   divContenido.innerHTML = ajax.responseText
  }
 }
 //como hacemos uso del metodo GET
 //colocamos null ya que enviamos 
 //el valor por la url ?pag=nropagina
 ajax.send(null)
}

El archivo principal de este proceso es paginador.php, este archivo es el encargado de mostrar los registros dependiendo de la página elegida. Describiré los procesos de manera que sea entendible, de todas maneras pueden preguntar por medio del formulario de comentarios:

  • Antes que nada, hacer un require del archivo de conexión a la Base de Datos (conexion.php).
  • Específicamos qué cantidad de registros se mostrarán por página ($RegistrosAMostrar). Pueden cambiar este valor por el que deseen, y el número de páginas se adecuará a ello. Pero para nuestro ejemplo mostraremos 4 registros por página.
  • En el if verificamos la variable $_GET['pag'], si está definida hacemos uso de dos variables: $RegistroAEmpezar que será la variable $_GET['pag'] menos 1 multiplicado por la cantidad de registros a mostrar (Ejm. Elegimos Pagina 5, 5 menos 1 igual 4, 4 multiplicado por 3 igual 12, a partir del registro 12 se empezaría a mostrar la consulta en la página 5), y $PagAct tendrá el valor de la variable $_GET['pag']. En el caso de que las variables no estén definidas las variables $RegistroAEmpezar y $PagAct tendrán el valor de 0 y 1 respectivamente.
  • Luego realizamos una consulta SELECT y usamos LIMIT con valores de las variables $RegistroAEmpezar y $RegistrosAMostrar y en una tabla HTML mostramos los resultados.
  • Realizamos un proceso para determinar el número de páginas dependiendo de la cantidad registros de la tabla ($NroRegistros) y de los registros a mostrar ($RegistrosAMostrar). El proceso lo he comentado en el script para que se entienda mejor.
  • Finalmente especificamos enlaces de navegación (Primero, Anterior, Siguiente, Último), cada uno de estos enlaces hará una llamada a la función JavaScript Pagina(nropagina).
<?php
 require('conexion.php');
 $RegistrosAMostrar=4;

 //estos valores los recibo por GET
 if(isset($_GET['pag'])){
  $RegistrosAEmpezar=($_GET['pag']-1)*$RegistrosAMostrar;
  $PagAct=$_GET['pag'];
  //caso contrario los iniciamos
 }else{
  $RegistrosAEmpezar=0;
  $PagAct=1;
 }

 $Resultado=mysql_query("SELECT * FROM empleado ORDER BY nombres LIMIT $RegistrosAEmpezar, $RegistrosAMostrar",$con);
 echo "<table border='1px'>";
 while($MostrarFila=mysql_fetch_array($Resultado)){
  echo "<tr>";
  echo "<td>".$MostrarFila['nombres']."</td>";
  echo "<td>".$MostrarFila['departamento']."</td>";
  echo "<td>".$MostrarFila['sueldo']."</td>";
  echo "</tr>";
 }
 echo "</table>";

 //******--------determinar las páginas---------******//
 $NroRegistros=mysql_num_rows(mysql_query("SELECT * FROM empleado",$con));
 $PagAnt=$PagAct-1;
 $PagSig=$PagAct+1;
 $PagUlt=$NroRegistros/$RegistrosAMostrar;

 //verificamos residuo para ver si llevará decimales
 $Res=$NroRegistros%$RegistrosAMostrar;
 // si hay residuo usamos funcion floor para que me
 // devuelva la parte entera, SIN REDONDEAR, y le sumamos
 // una unidad para obtener la ultima pagina
 if($Res>0) $PagUlt=floor($PagUlt)+1;
 
 //desplazamiento
 echo "<a onclick="Pagina('1')">Primero</a> ";
 if($PagAct>1) echo "<a onclick="Pagina('$PagAnt')">Anterior</a> ";
 echo "<strong>Pagina ".$PagAct."/".$PagUlt."</strong>";
 if($PagAct<$PagUlt)  echo " <a onclick="Pagina('$PagSig')">Siguiente</a> ";
 echo "<a onclick="Pagina('$PagUlt')">Ultimo</a>";
?>

El archivo index.php tendrá un tabla HTML con tres columnas (Nombres, Departamento, Sueldo) y un capa (<div>) llamado "contenido" dentro de la cual haremos un include del archivo paginador.php.

<html>
<head>
<title>Paginar Resultados</title>
<script type="text/javascript" src="ajax.js"></script>
<style>
td{
 width:200px;
}
a{
 text-decoration:underline;
 cursor:pointer;
}
</style>
</head>
<body>
<div style="margin:auto;width:500px;text-align:center;">
 <table border="1px">
  <tr>
   <td>Nombres</td>
   <td>Departamento</td>
   <td>Sueldo</td>
  </tr>
 </table>
 <div id="contenido">
  <?php include('paginador.php')?>
 </div>
</div>
</body>
</html>

Esta es una manera organizada de mostrar nuestras consultas de una Base de Datos. Cualquier duda, consulta, crítica constructiva abajo en sus comentarios. [Ver el resultado final]

Comentarios

  1. avatar aldo damianovich 2009-06-24 10:13:32 81 buenas de nuevo, no seria mejor crear una funcion ... o sea si tenemos que ahcer esto cada vez que queremos mostrar datos seria bueno llamar a una sola funcion y pasar solo los parametros del string SQL.

    salu2 ymuy bueno este espacio
  2. avatar aldo damianovich 2009-06-24 10:07:05 80 buenas, me sirvio de mucha la paginacion ajax. mi duda es al siguiente.

    si quiero por usar la funcion show/hidde de jquery en el paginador.php (incluyo en index.php el jquery.js) no me funciona...

    en paginado.php pongo el codigo del show/hide que seria este

    <script type="text/javascript">
    $(document).ready(function(){
    // ocultar y mostrar texto completo
    $("#mostrar<?=$row22[id]?>").click(function(){
    $("#ver_mas<?=$row22[id]?>").show("slow");
    $("#btn_vermas<?=$row22[id]?>").hide();
    });

    $("#ocultar<?=$row22[id]?>").click(function(){
    $("#ver_mas<?=$row22[id]?>").hide("slow");
    $("#btn_vermas<?=$row22[id]?>").show();
    });
    }); // $(document).ready(function(){
    </script>


    y en como dije anteriormente incluyo el jquery.js en el index.php


    salu2 y gracias
  3. avatar jesusvld 2009-06-23 09:16:45 79 @Oscar:

    Voy a explicar la paginación con numeración ( 1,2,3,4... Ultima) en un articulo centrado en ello. Paciencia y saludos.
  4. avatar Oscar 2009-06-22 13:01:35 78 Buenas, felicidades por el blog.
    Estoy usando el script éste de paginación y me va de maravilla.

    El problema es que me gustaria saber como podria hacer para que la paginación saliera por numeros y no como sale ahora "Primero 1/10 Siguiente Ultimo".

    ¿No estaria mejor asi?:
    Primero|1,2,3...10|Ultimo
  5. avatar Jotace 2009-06-17 09:46:17 77 Excelente articulo, pero como quedaria esto si se le agregar filtros, es decir si pongo antes de mostrar los datos paginados filtrar por sueldo, departamento, etc.. y mantener los datos filtros.

    Agradeceria que me ayudaras.
  6. avatar Raul David Orozco 2009-06-16 13:37:21 76 Saludos. Muchas gracias por este aporte, me ha aclarado una cantidad de dudas que tenía al respecto.
    Tengo una inquietud, necesito hacer lo mismo que ud hizo aquí pero utilizando en todo momento POST, nunca GET para el paso de los parámetros, quisiera saber si me puede orientar un poco acerca de los cambios necesarios para que funcione de este modo.
    De antemano muchas gracias por su atención.
  7. avatar jesusvld 2009-06-11 09:43:37 75 @Juan Luis:
    Si usas Firefox la extension Firebug, te puede ayudar para saber cual puede ser el error. Haciendo uso de Inspeccionar ó viendo en la Consola si esta llamando al procedimiento correcto.

    Para IE existe DebugBar (http://www.ribosomatic.com/articulos/debugbar-evalua-y-depura-sitios-web-en-ie/).

    Adonde quiero llegar con esto, es puntualizar sobre cual puede ser el problema y así poder ayudar mejor, me avisas como te fue.

    Saludos.
  8. avatar Juan Luis 2009-06-10 11:03:36 74 Hola Jesús: Gracias por resolverme la duda anterior, tenías razón, la consulta estaba mal formulada y después de corregirla, no me funcionan los enlaces; siempre estoy en la página 1 aunque le de a la siguieten, última, et. no me muevo de aquí.
    ¿Me puedes echar una mano?.
    Gracias de nuevo.

    Esta es la parte del código que no me funciona.
    if($Res>0) {
    $PagUlt=floor($PagUlt)+1;
    echo "<a onclick=\"Pagina('1')\">Primera</a> ";}
    if($PagAct>1) { echo "<a onclick=\"Pagina('$PagAnt')\">Anterior</a> ";
    echo "<strong>Pagina ".$PagAct."/".$PagUlt."</strong>";}
    if($PagAct<$PagUlt) {echo " <a onclick=\"Pagina('$PagSig')\">Siguiente</a> ";
    echo "<a onclick=\"Pagina('$PagUlt')\">Ultimo</a>";}
  9. avatar jesusvld 2009-05-31 12:29:09 73 @Juan Luis: El error mysql_fetch_array() ocurre cuando esta mal formulada la consulta, revisa bien que corresponda tal como esta en tu BD con minusculas o mayusculas.
  10. avatar Juan Luis 2009-05-31 12:06:00 72 Hola a todos: he copiado al pie de la letra el script paginación de resultados de esta misma página y me salen 2 errores:

    1º) Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/chs/rescateascensores.es/home/html/paginador.php on line 13

    2º) Fatal error: Call to undefined function Pagina() in /home/chs/rescateascensores.es/home/html/paginador.php on line 28

    El código es este:

    <?php
    require('conexion.php');
    $RegistrosAMostrar=4;
    if(isset($_GET['pag'])){
    $RegistrosAEmpezar=($_GET['pag']-1)*$RegistrosAMostrar;
    $PagAct=$_GET['pag'];
    }else{
    $RegistrosAEmpezar=0;
    $PagAct=1;
    }
    $Resultado=mysql_query("SELECT Referencia, Modalidad, Fecha FROM CursosRealizados ORDER BY ID $RegistrosAEmpezar, $RegistrosAMostrar",$con);
    echo "<table border='1px'>";
    while($MostrarFila=mysql_fetch_array($Resultado)){
    echo "<tr>";
    echo "<td>".$MostrarFila['Referencia']."</td>";
    echo "<td>".$MostrarFila['Modalidad']."</td>";
    echo "<td>".$MostrarFila['Fecha']."</td>";
    echo "</tr>";
    }
    echo "</table>";
    $NroRegistros=mysql_num_rows(mysql_query("SELECT Referencia, Modalidad, Fecha FROM CursosRealizados",$con));
    $PagAnt=$PagAct-1;
    $PagSig=$PagAct+1;
    $PagUlt=$NroRegistros/$RegistrosAMostrar;
    $Res=$NroRegistros%$RegistrosAMostrar;
    if($Res>0) $PagUlt=floor($PagUlt)+1;

    echo "<a onclick=".Pagina('1').">Primero</a> ";
    if($PagAct>1)
    echo "<a onclick=".Pagina('$PagAnt').">Anterior</a> ";
    echo "<strong>Pagina ".$PagAct."/".$PagUlt."</strong>";
    if($PagAct<$PagUlt)
    echo "<a onclick=".Pagina('$PagSig').">Siguiente</a> ";
    echo "<a onclick=".Pagina('$PagUlt').">Ultimo</a> ";
    ?>

    Gracias por la ayuda.

Dejar un comentario