Paginación manual y personalizada en Laravel (sin Eloquent)

- Andrés Cruz

In english
Paginación manual y personalizada en Laravel (sin Eloquent)

Muchas veces necesitamos tener algo de organización o agrupación sobre algún conjunto de elementos, ya sea que venga de la base de datos o no, y con organización me refiero a poder mostrar un conjunto de estos elementos o datos bajo demanda y que podamos organizarlos en grupo e ir visitando cada uno de estos grupos a placer; básicamente esto es la paginación y vamos a ver cómo podemos paginar de manera manual en Laravel sin necesidad de emplear Eloquent o conexiones a la base de datos.

En cualquier proyecto en Laravel, tenemos distintos mecanismos para hacer la paginación acorde a la documentación oficial, tanto automática como paginar un conjunto de datos o listados fácilmente.

Comencemos definiendo que es la paginación

¿Qué es la paginación?

La paginación en Laravel es una funcionalidad integrada en este tipo de frameworks como lo es Laravel; empleando la paginación, se puede dividir un conjunto grande de datos en trozos; es decir, que si tenemos 30 registros y queremos paginar de 10 en 10, tendríamos 3 grupos o páginas; para moverse entre las páginas, se usa un indice.

Aunque parece poco, la paginación es un método ideal para simplificar los registros a mostrar; supongamos que no tenemos 30 registros, si no unos 500 o más, y quieres mostrar un listado pagina do nuevamente de 10 niveles, mediante la paginación podemos dividir todo el pull de registros e ir mostrando de 10 en 10; para pasar a otro grupo, simplemente precionamos sobre un enlace y vamos al siguiente grupo; esto evita tener una página extremadamente pesada, con 500 o más registros, evita generar un página tan grande y lo que conyeva cargar la misma.

Esto se logra utilizando los métodos paginate() o simplePaginate() de Eloquent, que se encargan de cortar los resultados de la consulta en varias páginas según el número de registros que queremos mostrar en cada una.

La paginación es un número de páginas que corresponde con la cantidad de enlaces señalados que generalmente aparece en la parte de abajo de una página web que sirve para separar el contenido y separar el contenido en partes.

Para usar la paginación, usamos algo como:

Post::pagination(10)

Para tener una paginación de 10 niveles, adicionalmente, puedes colocar más métodos de Eloquent como where para personalizar la consulta.

Otro ejemplo de paginación en Laravel

Supongamos que tenemos una tabla de "Posts" en nuestra base de datos que queremos mostrar en una vista. Queremos mostrar solo 10 resultados por página.

En el controlador:

public function index()
{
    $posts = DB::table('posts')->paginate(10);
    return view('posts.index', ['posts' => $posts]);
}

En la vista:

@foreach ($posts as $post)
    <p>{{ $post->title }}</p>
@endforeach

{{ $posts->links() }}

El método paginate() divide la consulta en páginas de 10 elementos cada una, y el método links() genera los enlaces para navegar entre las distintas páginas. Así, en la vista, se mostrarán los primeros 10 resultados y un conjunto de enlaces para acceder a las páginas siguientes.

Este es solo un ejemplo básico, Laravel nos ofrece varias opciones para personalizar la apariencia y comportamiento de la paginación para adaptarla a nuestras necesidades que veremos algunas en los siguientes apartados.

Paginación manual en Laravel

Para esto, tenemos un par de clases muy parecidas en Laravel que podemos emplear con un funcionamiento muy parecido, la más sencilla, sería la llamada Paginator y tiene la siguiente estructura:

__construct($items, $perPage, $currentPage = NULL, array $options = [])

Como puedes suponer, los primeros dos argumentos son obligatorios, que corresponden al conjunto de datos y el nivel de paginación (aunque somos nosotros los que tenemos que indicar los datos a mostrar cómo vamos a ver un poco más adelante).

Vamos a trabajar con el siguiente modelo de datos:

$elements = range(1, 123);

En el cual, simplemente tenemos un array de 123 elementos que van desde 1 a 123.

La paginación más sencilla que podemos construir luce de la siguiente manera:

$res = new Paginator($currentElements, 10);

En la cual solamente especificamos los datos y cuantos elementos vamos a paginar; que en esta caso serían 10; vamos ha hacer un dd de la variable $res:

Paginación simple

Aquí como puedes ver, tenemos todo lo que necesitamos, las variables de control para saber datos sobre la paginación y los items.

Paginar con Paginate

Si hacemos un dd de esto vimos que tenemos la estructura anterior, justo con los items a paginar, ahora qué pasa si queremos ir a otra página; para eso tenemos que indicar un tercer parámetro, si colocamos el siguiente parámetro, veremos que:

$res = new Paginator($currentElements, 10, 3); 
Paginar problema en el currentPage

Básicamente nada cambia, sigue dando el mismo resultado sin importar que nivel de paginación indiquemos, que en este caso estamos indicando que queremos ir a la página número 3.

Si queremos paginar, tenemos que hacerlo de manera manual; por ejemplo:

$currentPage = 3;
$perPage = 10;
 
$currentElements = array_slice($elements, $perPage * ($currentPage - 1), $perPage);
 
$res = new Paginator($currentElements, $perPage, $currentPage);

Y si hacemos un dd:

Paginado correctamente

Ahora sí tenemos nuestros datos paginados.

Paginación dinámica en base a pase de parámetros

Como vemos un poco más adelante, podemos pasar algunos parámetros para obtener el índice de que pagina quiere ver nuestro usuario, de momento abstraerse  de esto y suponte que vamos a recibir esta información desde nuestra vista en un parámetro que por defecto se llama page; por lo tanto, como son datos que vamos a recibir de nuestro usuario y que con esto solamente vamos a consultar datos, por lo tanto, vamos a recibirlo vía get.

Así que en resumen:

$currentPage = $request->page;
$perPage = 10;
 
$currentElements = array_slice($elements, $perPage * ($currentPage - 1), $perPage);
 
$res = new Paginator($currentElements, $perPage, $currentPage);

Con esto, podemos recibir cual página quiere ver nuestro usuario y construir el listado a mostrar bajo demanda.

Visualizar resultados en una vista

Recuerda que nosotros también tenemos una función llamada link que se encarga de pintar los enlaces de paginación en la vista; por defecto, emplea el diseño de Bootstrap si así configurastes tu proyecto:

@foreach ($res as $r)
    {{ $r }}
@endforeach
 
{{ $res->links() }} 
Enlaces de paginación

Paginar con LengthAwarePaginator

Ahora, tenemos otra clase que podemos emplear que sería la de LengthAwarePaginator cuya única diferencia sería que la misma recibe el total de los elementos con los cuales vamos a trabajar:

__construct($items, $total, $perPage, $currentPage = NULL, array $options = [])

Por lo tanto, vamos a llevar nuestro ejemplo a:

$currentPage = $request->page;
$perPage = 10;
 
$currentElements = array_slice($elements, $perPage * ($currentPage - 1), $perPage);
 
$res = new LengthAwarePaginator($currentElements, count($elements), $perPage, $currentPage);

Por lo demás todo es exactamente igual; vamos a hacer un dd de lo anterior:

Length Paginator

Opciones para la paginación

Para ambas variantes, tenemos una parámetro más que sería para hacer la paginación:

$res = new LengthAwarePaginator($currentElements, count($elements), $perPage, $currentPage, ['path' => url('dashboard/category')]);

O simplemente:

$res->setPath('/dashboard/category');

Esto se emplearía por la función de links en nuestra vista para colocar como parte del path en los enlaces de navegación:

Length Paginator Path

Recuerda que esto es uno de los muchos temas que trabajamos en nuestro curso de Laravel que puedes tomar desde la sección de cursos.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.