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.
El día de hoy vamos a ver cómo restablecer la impresora térmica GOOJPRT PT-210 a…
Hoy voy a enseñarte cómo imprimir en una impresora térmica conectada por USB a una…
En este post voy a enseñarte a programar un servidor web en Android asegurándonos de…
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 web usa cookies.
Ver comentarios
buen articulo
Excelente hermano, muchas gracias por tus conocimientos, que Dios le siga bendiciendo...