Paginación de resultados en Laravel
En este post te voy a mostrar cómo puedes realizar una paginación en Laravel; es decir, mostrar registros (de la base de datos) por página, en lugar de mostrarlos todos a la vez.
Laravel ya provee una manera realmente sencilla de agregar paginación, incluso da la opción de agregar los enlaces a la página, y por supuesto, también permite cosas como la búsqueda u otros métodos del Query Builder, todo esto sin escribir ninguna consulta SQL manual.
Si simplemente quieres paginar tus resultados, invoca a paginate
de tu modelo y pásale como argumento cuántos elementos quieres por página.
Por ejemplo, yo tengo mi modelo llamado Producto
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Producto extends Model
{
protected $fillable = ["codigo_barras", "descripcion", "precio_compra", "precio_venta", "existencia", "es_servicio",
];
}
Ahora en mi controlador para enviarlo a la vista, indico el uso del namespace:
use App\Producto;
Y para paginar, envío los resultados así:
<?php
$productos = Producto::paginate(5);
return view("productos.productos_index", [
"productos" => $productos,
]);
En este caso estoy paginando cada 5 registros. Ahora en mi vista los dibujo en una tabla; puedo iterarlos fácilmente con un foreach
:
<table class="table table-bordered">
<thead>
<tr>
<th>Código de barras</th>
<th>Descripción</th>
<th>Precio de compra</th>
<th>Precio de venta</th>
<th>Utilidad</th>
<th>Existencia</th>
<th>¿Servicio?</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
</thead>
<tbody>
@foreach($productos as $producto)
<tr>
<td>{{$producto->codigo_barras}}</td>
<td>{{$producto->descripcion}}</td>
<td>{{$producto->precio_compra}}</td>
<td>{{$producto->precio_venta}}</td>
<td>{{$producto->precio_venta - $producto->precio_compra}}</td>
<td>{{$producto->existencia}}</td>
<td>
@if($producto->es_servicio)
<i class="fa fa-check"></i>
@else
<i class="fa fa-times"></i>
@endif
</td>
<td>
<a class="btn btn-warning" href="{{route("productos.edit",[$producto])}}">
<i class="fa fa-edit"></i>
</a>
</td>
<td>
<form action="{{route("productos.destroy", [$producto])}}" method="post">
@method("delete")
@csrf
<button type="submit" class="btn btn-danger">
<i class="fa fa-trash"></i>
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
Además, si quiero que se muestren los enlaces para navegar a las distintas páginas (por defecto Laravel genera el HTML para Bootstrap) invoco a links
justo abajo de mi tabla:
{{$productos->links()}}
El código completo queda así:
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Código de barras</th>
<th>Descripción</th>
<th>Precio de compra</th>
<th>Precio de venta</th>
<th>Utilidad</th>
<th>Existencia</th>
<th>¿Servicio?</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
</thead>
<tbody>
@foreach($productos as $producto)
<tr>
<td>{{$producto->codigo_barras}}</td>
<td>{{$producto->descripcion}}</td>
<td>{{$producto->precio_compra}}</td>
<td>{{$producto->precio_venta}}</td>
<td>{{$producto->precio_venta - $producto->precio_compra}}</td>
<td>{{$producto->existencia}}</td>
<td>
@if($producto->es_servicio)
<i class="fa fa-check"></i>
@else
<i class="fa fa-times"></i>
@endif
</td>
<td>
<a class="btn btn-warning" href="{{route("productos.edit",[$producto])}}">
<i class="fa fa-edit"></i>
</a>
</td>
<td>
<form action="{{route("productos.destroy", [$producto])}}" method="post">
@method("delete")
@csrf
<button type="submit" class="btn btn-danger">
<i class="fa fa-trash"></i>
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
{{$productos->links()}}
</div>
Si te fijas, toma el número de página de la URL. Por ejemplo, lo siguiente muestra la página 2:
http://localhost/nombre_de_tu_proyecto/public/productos?page=2
Fíjate en el parámetro de page
que está en 2
.
Si quieres agregar filtros o aprovechar lo que ofrece el query builder, puedes invocar a varios métodos y al final paginar con paginate
.
Por ejemplo, supongamos que quieres filtrar los productos por búsqueda basándote en una variable de la URL, y que los quieres ordenar por descripción.
<?php
# Función llamada desde el controlador; es un ejemplo, tú puedes colocar el código donde gustes
public function index(Request $request)
{
$busqueda = "";
if ($request->get("busqueda")) {
$busqueda = $request->get("busqueda");
}
# Exista o no exista búsqueda, los ordenamos
$builder = Producto::orderBy("descripcion");
if ($busqueda) {
# Si hay búsqueda, agregamos el filtro
$builder->where("descripcion", "LIKE", "%$busqueda%");
}
# Al final de todo, invocamos a paginate que tendrá todos los filtros
$productos = $builder->paginate(5);
return view("productos.productos_index", [
"productos" => $productos,
]);
}
En este caso podemos invocar a todos los métodos para hacer consultas de SQL. Por ejemplo, estamos invocando a orderBy
y a where
; pero al final obtenemos los resultados con paginate
.
Todo sigue funcionando igual, haya búsqueda o no, y los links también funcionan. Si hay menos resultados para la búsqueda, el número de enlaces para páginas cambiará, es decir, se toman en cuenta todos los filtros y el total de registros devueltos.
En caso de que no utilices el framework Bootstrap o quieras mostrar los enlaces de manera manual, también es posible. Puedes obtener el total de elementos accediendo a total
, así:
$productos->total();
Para saber cuántos mostrar por página (aunque eso también se define al invocar a paginate
, pero esto funciona para hacerlo desde la vista) invoca a perPage
.
Ya con esto puedes obtener las páginas así:
$paginas = ceil($productos->total() / $productos->perPage()
Y hacer un ciclo for que muestre los enlaces desde 1 hasta el total de páginas, justo como lo detallo en mi post de paginación manual de registros con PHP.
Recuerda que en este caso $productos
es lo que devuelve el método paginate
al invocarlo sobre un modelo.
Si te gusta este framework, te invito a ver más sobre Laravel en mi blog.
En este post te quiero compartir un código de C++ para listar y cancelar trabajos…
Gracias a WebAssembly podemos ejecutar código de otros lenguajes de programación desde el navegador web…
Revisando y buscando maneras de imprimir un PDF desde la línea de comandos me encontré…
Esta semana estuve recreando la API del plugin para impresoras térmicas en Android (HTTP a…
Hoy te enseñaré a extraer la cadena base64 de una clave PEM usando una función…
Encender un foco con un Bot de Telegram es posible usando una tarjeta como la…
Esta web usa cookies.
Ver comentarios
buen articulo
Excelente hermano, muchas gracias por tus conocimientos, que Dios le siga bendiciendo...