Paginación en laravel
La paginación es muy útil cuando se tiene que mostrar muchos resultados, ya sean post, artículos, datos en tablas, etc.
En Laravel es muy sencillo, solamente obteniendo la colección de datos a través del modelo, y utilizar el método links(). Por ejemplo una colección de posts
{{$posts->links()}}
Paginación dinámica
Por defecto la paginación se hace a través de una carga de la página, es decir, cada vez que se da a un número de paginación, la página se recarga.
Para hacer que la paginación sea dinámica y evitar esa llamada al servidor, se puede utilizar la clase WithPagination.
Entonces en el controlador o componente se importa la clase y también se usa dentro.
use Livewire\WithPagination;
use WithPagination
;
De esta forma al hacer clic en cada número de paginación, no recarga la página por completo.
Error de paginación badmethodcallexception
Puede que al utilizar el método links() de un error, y es porque la colección obtenida con get() necesita ser paginada.
BadMethodCallExceptionMethod Illuminate\Database\Eloquent\Collection::links does not exist.
(View: resources\views\livewire\component.blade.php)
Para solucionarlo hay que utilizar en el código donde se solicita la colección, el método paginate(). También se le puede pasar por parámetro al método, el número de registros por página.
Un ejemplo para obtener una colección de posts paginado de 10 en 10 sería:
$posts= Post::where('title', 'LIKE', '%' . $this->search . '%')->paginate(10);
Ocultar paginación si no hay resultados
Para mejorar la experiencia de usuario, es mejor que no se visualize la paginación en caso de haber menos de dos registros.
Esto se puede lograr con el método hasPages().
Un ejemplo para que se oculte es poniendo la paginación en una etiqueta div, y con una condicional utilizar el método hasPages.
@if ($posts->hasPages())
<div class="px-6 py-3">
{{$posts->links()}}
</div>
@endif
Refrescar paginación al buscar
Hay un problema que surge al utilizar un buscador, y es que al filtrar por el buscador un registro, también se va filtrando la paginación, dando lugar a que:
- La paginación filtrado a solo una página
- Que se indique que no existe el resultado para dicha página
Un ejemplo para aclararlo.
Hay 5 páginas, y se hace clic en la página 4. Entonces se busca texto coincidente de esta página 4, y el buscador de forma dinámica filtrando los resultados, y la paginación se queda en 1.
Como el filtro deja paginación en 1 y el texto buscado están en la página 4, muestra que no hay resultados.
Para solucionar esto se utiliza los ciclos de vida de livewire
Ciclos de vida de livewire
Se pueden ejecutar distintos métodos a lo largo de todo el ciclo de vida del componente.
Métodos de ciclos de vida
Los métodos más comunes que se utilizan en los ciclos de vida de un componente livewire son:
- Método mount: es el primer método que se ejecuta al cargar el componente.
- Método updating: cada vez que se cambia el valor de alguna propiedad del componente.
- Método updating mas Nombrepropiedad: cada vez que se cambia la propiedad con nombre que va justo después de updating. La primera letra de la propiedad en mayúscula.
Por ejemplo:
En el componente está la propiedad $search
Y se crea la función updatingSearch()
Solución a paginación dinámica
Visto que utilizando los método de ciclos de vida se puede actuar directamente en el resultado que el usuario desea obtener, es suficiente con colocar en el método updatingNombrecomponente el método resetPage(), que resetea a página 1. Con esto cada acción del usuario muestre la página real de lo que se visualice.
public function updatingSearch(){
$this->resetPage();
}
Laravel query string
También se puede poner una paginación con una cantidad variable de registros y que el usuario pueda elegir.
Para ello se puede añadir un componete select con al número de registros a visualizar, y en el componente/controlador actualizar este dato.
Query string en el componente/controlador
En el componente/controlador crear una propiedad que guarde la cantidad a visualizar. Aunque sea numerico se pone como cadena porque el componente selector envía texto, y así no dará error en el controlador.
public $cant = '10';
Y también declarar la propiedad protected queryString, para que la información vaya en la URL. De esta forma al copiar y pegar la url generada, guardará las preferencias de filtrado y ordenado por parte del usuario en un determinado momento.
A la propiedad queryString se le pasa un array con los valores a incluir, además de las excepciones.
En este ejemplo se guarda en la url los valores de cantidad, el orden, la dirección ascendente o descendente y la palabra de búsqueda. Pero no van en la url los valores por defecto 10, id, desc y cadena de búsqueda vacía.
protected $queryString = [
'cant' => ['except' => '10'],
'sort' => ['except' => 'id'],
'direction' => ['except' => 'desc'],
'search' => ['except' => '']
];
Query string URL generada
Este tipo de configuración genera una URL donde se visualiza cada opción de filtrado y ordenado de registros. Después de la ruta se añade automáticamente una interrogación ? y después cada campo igualado al valor deseado.
http://midominio.test/dashboard?sort=content&search=autem&cant=25&direction=asc
Esta url se puede enviar y compartir con terceras personas, que al pegarla en el navegador obtendrá el mismo resultado de registros.
Query string en la vista
En la vista se muestra un selector o combo que indica la cantidad a registro a visualizar, y se vincula con la propiedad de cantidad cant del componente/controlador.
<select wire:model="cant" class="mx-2">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
Wire no renderiza cambios
En el caso de que wire: no muestre los cambios en la vista, seguramente es porque no está todo el componente que al que se llama, dentro de la misma etiqueta div.
Por ejemplo, una barra de botones filtra los resultados mostrados en una tabla grid.
Coloca todo el código de botones y tabla grid en el mismo div, y seguramente funcinará.
<div>
..
.codigo donde se llama a wire:
</div>
Espero te sirva de ayuda!!
Deja una respuesta