14 - Paginación con AJAX


Un lugar donde puede ayudar el uso de AJAX es en la paginación de datos mientras otro recurso en la página se está ejecutando. Confeccionaremos una página que muestre un video de YouTube e inmediatamente en la parte inferior mostraremos los comentarios del video paginados.

Sin utilizar AJAX estamos obligados a recargar completamente la página lo que haría imposible ver el video y recorrer los comentarios en forma completa (considerando que solo parte de los comentarios están en la página)

Veamos y expliquemos cada uno de los archivos que intervienen.

pagina1.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Problema</title>
  <script src="funciones.js"></script>
</head>
<body>
  <iframe width="420" height="315" src="https://www.youtube.com/embed/KmtzQCSh6xk" frameborder="0" allowfullscreen></iframe>
  <br>
  <div id="detalles">
  </div>
</body>
</html>

Este archivo HTML no tiene nada de especial. Podemos decir que hemos incrustado un video del sito youtube.

También es importante notar que hemos dispuesto un div vacío cuyo id se llama detalles. Es dentro de este div donde iremos mostrando los comentarios en forma asincrónica.

El archivo funciones.js

addEventListener('load',inicializarEventos,false);

function inicializarEventos()
{
  cargarPagina('pagina2.php'); 
}

function presionEnlace(e)
{
  e.preventDefault();
  var url=e.target.getAttribute('href');
  cargarPagina(url);     
}


var conexion1;
function cargarPagina(url) 
{
  if(url=='')
  {
    return;
  }
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open("GET", url, true);
  conexion1.send(null);
}

function procesarEventos()
{
  var detalles = document.getElementById("detalles");
  if(conexion1.readyState == 4)
  {
    detalles.innerHTML = conexion1.responseText;
    var ob1=document.getElementById('sig');
    if (ob1!=null)
      ob1.addEventListener('click',presionEnlace,false);
    var ob2=document.getElementById('ant');
    if (ob2!=null)
      ob2.addEventListener('click',presionEnlace,false);
  } 
  else 
  {
    detalles.innerHTML = '<img src="../cargando.gif">';
  }
}

Dentro de esta función llamamos a la función cargarPagina con el nombre del archivo php que se ejecuta en el servidor y tiene por objetivo enviarnos los comentarios.

La función cargarPagina es la que crea un objeto de la clase XMLHttpRequest:

function cargarPagina(url) 
{
  if(url=='')
  {
    return;
  }
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open("GET", url, true);
  conexion1.send(null);
}

La función procesarEventos:

function procesarEventos()
{
  var detalles = document.getElementById("detalles");
  if(conexion1.readyState == 4)
  {
    detalles.innerHTML = conexion1.responseText;
    var ob1=document.getElementById('sig');
    if (ob1!=null)
      ob1.addEventListener('click',presionEnlace,false);
    var ob2=document.getElementById('ant');
    if (ob2!=null)
      ob2.addEventListener('click',presionEnlace,false);
  } 
  else 
  {
    detalles.innerHTML = '<img src="../cargando.gif">';
  }
}

Cuando la propiedad readyState tiene un cuatro procedemos a cargar el div "detalles" con el trozo de HTML que se generó en el servidor:

    detalles.innerHTML = conexion1.responseText;

Otra cosa muy importante es inicializar el evento click para los hipervínculos siguiente y anterior que contiene todo listado con paginación:

    var ob1=document.getElementById('sig');
    if (ob1!=null)
      ob1.addEventListener('click',presionEnlace,false);
    var ob2=document.getElementById('ant');
    if (ob2!=null)
      ob2.addEventListener('click',presionEnlace,false);

Es importante notar los if. Esto debido a que cuando no hay más registros que mostrar no habrá un hipervínculo. Imagine que la primer página no tiene que tener un hipervínculo "Anteriores".

Por último tenemos el archivo pagina2.php:

<?php
header('Content-Type: text/html; charset=utf-8');

if (isset($_REQUEST['pos']))
  $inicio=$_REQUEST['pos'];
else
  $inicio=0;

$conexion=mysqli_connect("localhost","root","","bdajax") or
    die("Problemas con la conexión");

$registros=mysqli_query($conexion,"select * from comentarios limit $inicio,3") or
  die("Problemas en el select:".mysqli_error($conexion));
$impresos=0;
while ($reg=mysqli_fetch_array($registros))
{
  $impresos++;
  echo "Nombre:".$reg['nombre']."<br>";
  echo "Fecha:".$reg['fecha']."<br>";
  echo "Comentarios:".$reg['descripcion']."<br>";
  echo "<br>";
}
mysqli_close($conexion);
if ($inicio==0)
  echo "anteriores ";
else
{
  $anterior=$inicio-3;
  echo "<a href=\"pagina2.php?pos=$anterior\" id=\"ant\">Anteriores </a>";
}
if ($impresos==3)
{
  $proximo=$inicio+3;
  echo "<a href=\"pagina2.php?pos=$proximo\" id=\"sig\">Siguientes</a>";
}
else
  echo "siguientes";
?>

Lo primero que hacemos es verificar si llega el parámetro pos, como habíamos visto desde el inicializar eventos indicabamos cargar la página pagina2.php sin especificar parámetros. Es decir la variable $incio se inicializa con 0. $inicio nos sirve para saber a partir de cual registro debemos rescatar.

if (isset($_REQUEST['pos']))
  $inicio=$_REQUEST['pos'];
else
  $inicio=0;

Luego de conectarnos y seleccionar la base de datos procedemos a efectuar un select utilizando el limit para rescatar hasta tres registros (es decir página de tamaño 2):

$registros=mysqli_query($conexion,"select * from comentarios limit $inicio,3") or
  die("Problemas en el select:".mysqli_error($conexion));

Mediante un while recorremos los registros rescatados y los imprimimos con el comando echo. Además utilizamos un contador para saber cuantos registros se imprimieron:

$impresos=0;
while ($reg=mysqli_fetch_array($registros))
{
  $impresos++;
  echo "Nombre:".$reg['nombre']."<br>";
  echo "Fecha:".$reg['fecha']."<br>";
  echo "Comentarios:".$reg['descripcion']."<br>";
  echo "<br>";
}

Si $inicio vale cero significa que no hay registros anteriores, en caso que sea distinto a cero creamos un hipervínculo y pasamos como parámetro el valor de $inicio menos 3:

if ($inicio==0)
  echo "anteriores ";
else
{
  $anterior=$inicio-3;
  echo "<a href=\"pagina2.php?pos=$anterior\" id=\"ant\">Anteriores </a>";
}

Para el hipervínculo de "Siguientes" procedemos de forma similar, si $impresos vale 3 significa que posiblemente haya más registros que mostrar, por lo que creamos un hipervínculo y pasamos como parámetro el valor de $inicio más 3.

if ($impresos==3)
{
  $proximo=$inicio+3;
  echo "<a href=\"pagina2.php?pos=$proximo\" id=\"sig\">Siguientes</a>";
}
else
  echo "siguientes";


Problema resuelto.


Confeccionar una página que muestre un video e inmediatamente en la parte inferior mostrar los comentarios del video paginados. Actualizar los datos de cada página en forma asíncrona.


pagina1.html



Ejecutar ejemplo



funciones.js




pagina2.php


Retornar