Paginando datos

Paginación en un CRUD con Laravel 12

Paginación

La paginación es una técnica que permite dividir un conjunto grande de registros en bloques más pequeños llamados páginas.

En lugar de mostrar todos los registros de una tabla, el sistema muestra solo un número limitado de elementos y permite navegar entre páginas.


¿Por qué usar paginación?

En aplicaciones reales es habitual tener cientos o miles de registros.

Sin paginación:

  • Se cargan demasiados datos
  • La página tarda más en renderizar
  • La experiencia del usuario empeora

Con paginación:

  • Se cargan solo los registros necesarios
  • Se mejora el rendimiento
  • La navegación es más cómoda

Ejemplo con recurso Teachers

En nuestro caso concreto:

  • Modelo: Teacher
  • Controlador: TeacherController
  • Vista: teachers.index (usando crud.blade.php)

1. Paginación en el controlador

Laravel proporciona el método: paginate(int $numero_registros) que divide automáticamente los resultados en páginas, indicando en su argumento el número de registros por página.

1
2
3
4
5
public function index()
{
    $teachers = Teacher::paginate(10);
    return view('teachers.index', compact('teachers'));
}

Explicación

  • paginate(10) → devuelve 10 registros por página
  • Laravel crea automáticamente:
    • número de páginas
    • enlaces de navegación
    • información de página actual

2. Mostrar los datos en la vista

En la vista teachers/index.blade.php mostramos los registros normalmente.

1
2
3
4
5
6
@foreach($teachers as $teacher)
<tr>
    <td>{{$teacher->name}}</td>
    <td>{{$teacher->email}}</td>
</tr>
@endforeach

Aquí Laravel ya solo devuelve los registros de la página actual. En nuestro caso, usamos el componente crud.blade.php donde de forma general visualizamos los registros de una tabla


3. Mostrar los enlaces de paginación

Para mostrar los botones de navegación utilizamos: el método links() del objeto paginator que hemos generado en el controlador

1
{{$teachers->links()}}

Laravel genera automáticamente los botones para navegar:

  • botón Previous
  • botón Next
  • números de página

4. Paginación simple

Alternativa al método paginate tenemos otros como simplePaginate que lo que hace es modificar lo que retorna links() haciendo más sencilla la navegación: solo queremos Anterior / Siguiente sin números de página:

1
2
3
4
5
6
public function index()
{
$teachers = Teacher::simplePaginate(10);

    return view('teachers.index', compact('teachers'));
}

Diferencia:

Método Resultado
paginate() números de página
simplePaginate() solo anterior / siguiente

5. Mantener filtros o parámetros

Cuando hay filtros o parámetros en la URL, debemos conservarlos.

Ejemplo:

/teachers?page=2

Laravel lo gestiona automáticamente con links().

Pero si añadimos filtros:

/teachers?department=math&page=2

Podemos mantenerlos usando:

1
{{$teachers->appends(request()->query())->links()}}

6. Saber en qué página estamos

Cuando estamos implementando un crud, es muy importante conocer la página en la que estamos, de forma que is estamos en una página, cualquier acción (borrar o editar), El punto clave es ser consciente de que la navegación se basa en el parámetro page que se recibe en la URL (es decir es un parámetro por get).

Ejemplo:

/teachers?page=3

Podemos obtenerlo con:

1
request()->get('page')

Esto es útil para:

  • volver a la página anterior
  • mantener contexto después de editar

7. Modificar controlador y vistas

Para mantener los números de páginas tenemos que modificar el controlador, leerlo en las vistas y pasarlo entre ambos (de la vista al controlador y del controlador a la vista) No debemos perder este valor, para poderlo mantener

En el index

Recibiremos el número de página como argumento.

Cuando hacemos la paginación, láravel internamete lee el número de página si lo tiene, hace algo del tipo:

$page = request()->query('page', 1);
Por lo que en realidad, en el index no tenemos que realizar ninguna acción. Si queremos podemos pasar explícitamente el número de página para dejarlo mas explícto a la vista
    public function index()
    {
        $teachers = Teacher::paginate(5);
        $campos = Teacher::getLabels();
        $page = request()->get('page', 1);
        return view('teachers.index', compact('teachers', 'campos', 'page'));
    }
Esto lo realizaremos en el crud.blade.php

Observa cómo podemos leer el número de página directamente de request

@props([
    'resource'=>"",
    'campos'=>[], //Array asociativo con nombre_campos => titulo para la tabla ("start_date"=>"Fecha de comienzo")
    'filas'=>[], //Un array de objetos
    'page'=>$page
])

create

Este método es invocado desde la página html.

Ahí debemos de pasar el número de página y luego leerlo en el método create del controlador

<a href="{{route("$resource.create")}}?page={{$page}}" class="btn btn-primary">Añadir {{strtoupper($resource)}}</a>
Y luego en el controlador el método create recogerá el número de página, y lo pasará a la página html para no perderlo
public function create(){
    $page = request()->get('page');
    return view('teachers.create',['page'=>$page]);
        //
}
Y la vista create lo recoge y lo enviará al método store del controlador
@props([
'page'=>$page
])
<x-layouts.layout>

    <div class="flex justify-center items-center min-h-full bg-gray-200">

        <form method="POST" action="{{ route('teachers.store') }}"?page="$page" class="bg-white p-4 rounded-2xl">
            @csrf

El método store

Guardamos el registro y retornamos el index con la página que teníamos

Aquí hay que tener en cuenta que puede ser que el nuevo registro estará en la última página, si queremos mostrarlo, deveremos especificar es página

public function store(StoreTeacherRequest $request)
{
$datos = $request->input();
Teacher::create($datos);
$page = Teacher::paginate(5)->lastPage();
return redirect()->route('teachers.index',['page'=>$page])->with('success','Registro creado satisfactoriamente');
//
}

El método edit

A esta acción venimos del crud, por lo que ahí debemos de pasar el número de página

  • En el crud
    * <td>
                            <a href="{{route("$resource.edit",$fila->id)}}?page={{request('page')}}"
                               class="btn btn-primary">Editar</a>
                        </td>
  • En el método edit
  • Aquí recogemos el número de página y se lo pasamos a la vista
      @props([
      'page'=>$page
      ])
      <x-layouts.layout>
    
        <div class="flex justify-center items-center min-h-full bg-gray-200">
    
    
            <form method="POST" onsubmit="return confirm ('quieres actualizar este profesor')"  action="{{ route('teachers.update', $teacher->id)}}?page={{$page}}" class="bg-white p-4 rounded-2xl">
     
    
  • En el método update que invoca este formulario
      public function update(UpdateTeacherRequest $request, Teacher $teacher)
      {
      $datos = $request->input();
      $teacher->update($datos);
      $page = $request->input('page');
      return redirect()->route('teachers.index',['page'=>$page]);
    
            //
      }

El método delete

  • Como siempre, primero la vista desde donde vamos a realizar esta acción

      <td>
      <form action="{{route("$resource.destroy",$fila->id)}}?page={{request('page')}}" method="POST">
      @csrf
      @method('DELETE')
      <input type="button" value="Borrar" class="btn btn-warning"
      onclick="confirmar(this)"
      >
      </form>
      </td>

  • Ahora el método destroy del controlador

  public function destroy(Teacher $teacher)
  {
  $teacher->delete();
  return redirect()->route('teachers.index',[
  'page'=>request('page')
  ]);
  //
  }
 

7. Cambiar la cantidad de registros por página

Simplemente cambiando el parámetro de paginate().

1
$teachers = Teacher::paginate(20);

Esto mostrará:

  • 20 registros por página.

Resumen

La paginación en Laravel es muy sencilla:

  1. Obtener registros paginados
1
$teachers = Teacher::paginate(10);
  1. Mostrar registros
1
@foreach($teachers as $teacher)
  1. Mostrar navegación
1
{{$teachers->links()}}
  1. Creaer rutas con el parámetro page en las vistas
1
{{route("teachers.create")??=page={{$page}}

5.- Leer la página en el controlador

1
2
3
4
5
6
7
 $page = request('page');
 // o
 $page = request()->get('page');
// o
 $page = request()->query('page');
//o
 $page = request()->input('page');

Referencias

Fuentes de Información