IntroducciónCuando se trabaja con aplicaciones web y tablas, debemos siempre de mostrar el resultado de nuestras consultas a nuestros usuarios. Cuando estos datos se vuelven demasiados, presentarlos al usuario se vuelve complicado y nos agrega carga extra si siempre mostramos todos los datos.
La paginación nos permite mostrar los datos en grupos, con lo que obtenemos dos grandes beneficios, primero reducir el uso de recursos por parte de nuestra aplicación, y segundo podemos crear interfaces más amigables para el usuario.
Con este tutorial y usando CakePHP+MySQL podremos crear un control de paginación simple desde cero para una tabla de contactos.
Requisitos:- CakePHP
- MySQL
- CakePHP configurado y funcional
1-Los datosAntes que nada, debemos de crear una tabla en nuestra base de datos. En MySQL podemos crear una tabla de contactos con el siguiente código:
CREATE TABLE contactos
(
id
INT UNSIGNED AUTO_INCREMENT
NOT NULL, nombres
VARCHAR(150) NOT NULL,
apellidos
VARCHAR(150)
NOT NULL,
telefono
INT(8)
NOT NULL,
PRIMARY_KEY(id)
);
Lo que nos queda, es ingresar algunos datos:
INSERT INTO contactos(nombres,apellidos,telefono)
VALUES('
Mario','
Gomez',
22905930),
('
Karla','
Gonzalez',
22475423),
('
Ernesto','
Rivera',
22445787),
('
Juan','
Sanchez',
22417251),
('
Ricardo','
Lemus',
22453652),
('
Flor','
Aguilar',
22451535),
('
David','
Ochoa',
22454584),
('
Catalina','
Cruz',
22334525),
('
Marvin','
Arriaza',
22453541),
('
Carlos','
Batres',
26532458),
('
Juan','
Alfaro',
22453668),
('
Marina','
Salazar',
22639586),
('
Karla','
Miranda',
22365984),
('
Salvador','
Hernandez',
22654854),
('
Marta','
Urrutia',
22635428),
('
Benjamin','
Campos',
22364586),
('
Alejandro','
Rodriguez',
554822416);
Ahora que ya tenemos nuestra tabla con los datos, es cuando podemos ponernos a jugar un poquito con PHP.
2-El Modelo.El primer paso es crear nuestro modelo de datos, para este ejemplo será bastante simple ya que tenemos una única tabla. Asumiendo que ya tenemos instalado y configurado nuestro Cake, creamos un archivo con nombre
Contacto.php en el directorio
<CAKE>/app/models/.
<?php
class Contacto extends AppModel {
var $name = "Contacto";
}
?>
Como hemos seguido la nomenclatura utilizada por Cake para el diseño de nuestra tabla, entonces no hay necesidad de hacer nada mas.
Nota: Si el nombre de la tabla en la base de datos no es el plural (en inglés), de el nombre de la clase, entonces debemos de definir el nombre de la tabla a utilizar con
var $useTable = <nombretabla>;. En inglés, el plural de cualquier objeto se obtiene agregando una
's' al final del nombre del mismo. Por ejemplo para
contact (Contacto en inglés), el plural corresponde a
contacts. En español no sucede igual y podríamos tener problemas con algunas palabras. Por ejemplo para
Perfil, el plural en español es
Perfiles. En este caso y para un modelo con nombre
Perfil deberíamos de utilizar
var $useTable="perfiles";.
3-Entendiendo la paginación.Antes de comenzar a editar código, vamos a entender un poquito como funciona esto de la paginación. Vamos a hacer un par de calculos y vamos a crear un algoritmo que nos sirva para cualquier base de datos.
Primero, antes que nada debemos de conocer cuantos resultados nos devuelve una consulta. Para hacerlo siempre existen funciones de conteo de resultados en los gestores. En mysql la siguiente consulta nos deberá de devolver la cantidad de filas para la tabla contactos:
SELECT COUNT(*)
FROM contactos;
El resultado deberá de ser más o menos el siguiente:
+----------+
| COUNT(*) |
+----------+
| 17 |
+----------+
1 row in set (0.00 sec)
Es decir, que debemos de mostrarle 17 resultados al usuario. Sin embargo imaginemos que nos interesa mostrarle únicamente 4 por vez. Entonces tenemos que hacer un par de cálculos:
Total de resultados = 17
Resultados a mostrar = 4
Páginas totales = Total de resultados / Resultados a mostrar = 17/4 = 4.25
Aquí nos encontramos con un problema, necesitamos 4 y 1/4 de página para mostrar todos los resultados. Sin embargo no es posible mostrar únicamente media página, así que lo que hacemos es aproximar el número de páginas al entero positivo mayor. Es decir que necesitaremos 15 páginas para mostrar todos los resultados.
Tip: PHP cuenta con una función que nos facilita ese trabajo, y es la funcion "
ceil(<numero>)", que aproxima todo numero decimal a su entero positivo mayor. Por ejemplo ceil(2.1) = 3, ceil(2.7) = 3.
4- Modificando nuestro modeloAhora que ya conocemos todos los datos necesarios para realizar una páginacion, vamos a modificar un poco nuestro modelo original para facilitarnos el trabajo. Para ello vamos a utilizar la función
findCount(<condiciones>), que es el equivalente en SQL a "
SELECT COUNT(*)
FROM WHERE <condiciones>".
Vamos a crear una función "totalContactos()" que nos devuelva el total de contactos de la tabla.
<?php
class Contacto extends AppModel {
var $name = "Contacto";
// Devuelve el total de contactos almacenados
// en la tabla "contactos".
function totalContactos() {
return $this->findCount();
}
}
?>
5- Creando un Controlador adecuadoAhora que ya conocemos como funciona la paginación y como obtener el total de resultados para una consulta, vamos a crear un controlador que establezca todas las variables necesarias para enviar a la vista.
En el controlador debemos de obtener todos los contactos que queremos mostrar y establecerlos como variable para pasarlos a la vista. También necesitamos pasar el total de páginas y la cantidad de perfiles que se muestran.
Creamos nuestro controlador como contactos_controller.php en el directorio <CAKE>/app/controllers
<?php
class ContactosController extends AppController {
// IMPORTANTE
// Debes especificar que
// utilizaras el modelo Contacto
var $models = array(
'Contacto'
);
// Utilizaremos el helper Html
// para crear los links
var $helpers = array(
'Html'
);
function listar($pagina=1) {
$mostrarResultados = 4;
// Obtiene $mostrarResultados de la tabla contactos
// de la pagina $pagina
$contactos = $this->Contacto->findAll(null, null, ,$mostrarResultados , $pagina);
// Establecemos el arreglo que contiene
// a los contactos
$this->set('contactos', $perfilmodelos);
// Obtenemos el numero total de contactos
$totalContactos = $this->Contacto->totalContactos();
// Variables de la paginacion
$this->set("totalContactos", $totalContactos);
$this->set("mostrarResultados", $showResults);
$this->set("paginaActual", $pagina);
$this->set("totalPaginas", ceil($totalContactos / $mostrarResultados));
}
}
?>
La función que nos facilita el trabajo de paginación es "
findAll(<condiciones>,<campos>,<columna_a_ordenar>,<limite>,<pagina>". Como estamos obteniendo todos los campos, dejamos los primeros tres parametros en null.
4-Creando la vistaLo único que nos queda es crear una vista para mostrar nuestros datos. Como ya establecimos todas las variables que ibamos a necesitar esta resulta la parte más sencilla.
Vamos a crear el archivo listar.thtml en <CAKE>/app/views/contactos/
<html>
<head><title>EJemplo de paginación</title></head>
<body>
<table>
<tr>
<td>Nombres</td>
<td>Apellidos</td>
<td>Telefono</td>
</tr>
<?php
// Si no hay datos a mostrar
if(empty($contactos)) { ?>
<tr>
<td colspan="3">No hay datos que mostrar</td>
</tr>
<?php
// Si hay datos:
} else {
// Mostramos cada uno de los datos
// encontrados
foreach($contactos as $i=>$contacto) {
?>
<tr>
<td><?php echo $contacto['Contacto']['nombres']; ?></td>
<td><?php echo $contacto['Contacto']['apellidos']; ?></td>
<td><?php echo $contacto['Contacto']['telefono']; ?></td>
</tr>
<?php
} // Fin foreach
} // Fin Hay datos ?>
<!--// POR ULTIMO CREAMOS LOS VINCULOS DE NAVEGACION //-->
<p align="center">
<?php
// Si no estamos en la primera página
// Y hay mas de dos páginas
// mostramos el vinculo "Primera"
if(($paginaActual>1) && ($totalPaginas>2)) { ?>
[<?php echo $html->link("Primera","/contactos/listar/1"); ?>]
<?php
}
?>
<?php
// Si no estamos en la primera página
// mostramos el vinculo "Anterior"
if($paginaActual>1) { ?>
[<?php echo $html->link("Anterior","/contactos/listar/".($paginaActual-1)); ?>]
<?php
}
?>
<?php
// Si no estamos en la última página
// mostramos el vinculo "Siguiente"
if($paginaActual<$totalPaginas) { ?>
[<?php echo $html->link("Siguiente","/contactos/listar/".($paginaActual+1)); ?>]
<?php
}
?>
<?php
// Si no estamos en la ultima pagina
// Y hay mas de dos páginas
// mostramos el vinculo "Ultima"
if(($paginaActual<$totalPaginas) && ($totalPaginas>2)) { ?>
[<?php echo $html->link("Última","/contactos/listar/".$totalPaginas); ?>]
<?php
}
?><br />
<?php
// Si hay mas de una página entonces
// mostramos la página actual
if($totalPaginas>1)
?>
Página <?php echo $paginaActual ?> de <?php echo $totalPaginas ?>;
<?php
}
?>
</p>
</table>
</body>
</html>