Introduccion
Bienvenido a esta serie de filamentPHP V4, en esta primera parte, vamos a explorar como integrar tabs en una tabla dentro de una pagina customizada de filamentPHP
¿Que son los tabs en una tabla de filament?
Los tabs son componentes situados como encabezados, que nos permiten hacer filtros masivos y rapidos sobre el contenido que tenemos en nuestra tabla.
trait HasTabs
{
public ?string $activeTab = null;
protected array $cachedTabs;
protected function loadDefaultActiveTab(): void
{
if (filled($this->activeTab)) {
return;
}
$this->activeTab = $this->getDefaultActiveTab();
}
...
}Filament trae el trait HasTabs que permite integrar tabs en cualquier tipo de paginas.
Metodos y funciones del componente
Estos son algunos de los metodos y funciones mas importantes, si deceas revisar a detalle el componente puedes seguir al codigo oficial en filamentPHP HasTabs
| Metodo o Funcion | Propósito |
|---|---|
| loadDefaultActiveTab() | Carga el tab activo |
| getDefaultActiveTab() | Devuelve el tab por defecto como activo |
| getTabs() | Retorna una lista de tabs |
¿Entonces como integramos en una pagina?
Usualmente cuando se crea una pagina con el comando php artisan make:filament-page NombrePagina ocurre que nos crea un archivo con el siguiente contenido basico.
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class CustomPageWithTabs extends Page
{
protected string $view = 'filament.pages.custom-page-with-tabs';
}y entonces que ocurre con esto?, absolutamente todo si es que queremos agregar tabs sobre nuestra tabla, cuando hacemos referencias a una vista $view filament vincula todo el contenido, funciones, metodos a ella. ejemplo si quisieramos agregar una tabla tendriamos que implementar el trait HasTables y configurar la vista de la siguiente manera.
<x-filament-panels::page>
{{ $this->table }}
</x-filament-panels::page>Removiendo la referencia a una vista
Para eliminar la referencia es tan sencillo como eliminar la linea en donde se menciona $view.
class PagosPendientes extends Page implements HasTable
{
use InteractsWithTable;
use HasTabs;
protected static string|BackedEnum|null $navigationIcon = Heroicon::CurrencyDollar;
protected static ?string $navigationLabel = 'Pagos Pendientes';
protected static ?string $title = 'Lista de pagos pendientes';
protected ?string $subheading = 'Lista de todas las cuotas que aun faltan.';
}entonces la pagina se preguntara, ¿donde deberia renderizar entonces?, en este caso se debe tambien de integrar las funciones y metodos
public function mount(): void
{
$this->loadDefaultActiveTab();
// ⬆ esto cargara el tab por defecto que siempre es el que esta en la posicion 0 del array ⬆
}
public function content(Schema $schema): Schema
// ⬆ este metodo es el que hace de reemplazo a $view ⬆
{
return $schema
->components([
$this->getTabsContentComponent(),
// ⬆ esto renderizara la lisa de tabs dentro de la pagina ⬆
EmbeddedTable::make(),
// ⬆ esto renderizara la tabla que se integra por la implementacion HasTable ⬆
]);
}Funciones y metodos de HasTabs y HasTable
Luego de aver preparado los metodos para no usar una vista blade, debera agregar y configurar los metodos de HasTabs y HasTable para obtenere los datos
| Metodo o Funcion | Propósito | Propiedad |
|---|---|---|
| getTableQuery() | Usado para obtener datos de la DB | HasTable |
| table(Table $table) | Usado para definir, filtros, columnas, actions | HasTable |
| getTabs() | Retorna una lista de tabs | HasTabs |
getTableQuery - HasTable
protected function getTableQuery(): Builder|Relation|null
{
return EstudiantePlanPago::query()->conCuotasPendientes();
// EstudiantePlanPago es el modelo de donde se obtendran los datos
}table - HasTable
public function table(Table $table): Table
{
return $table
->poll('10s')
->deferLoading(true)
->modifyQueryUsing($this->modifyQueryWithActiveTab(...))
// ⬆ este metodo es obligatorio, caso contrario los tabs no funcionaran ⬆
->columns([
// Columnas de la tabla
])
->filters([
// Filtros de la tabla
]);
}getTabs - HasTabs
// esto corresponde a su propia necesidad
public function getTabs(): array
{
return [
'todos' => Tab::make()
->label('Todos')
->badge(EstudiantePlanPago::conCuotasPendientes()->count()),
'pendientes' => Tab::make()
->label('Pendientes')
->badge(function () {
$count = EstudiantePlanPago::conCuotasPendientes()
->whereHas('estado', fn ($q) => $q->where('nombre', 'LIKE', '%pendiente%'))
->count();
return $count;
})
->modifyQueryUsing(function (Builder $query) {
return $query->whereHas('estado', fn ($q) =>
$q->where('nombre', 'LIKE', '%pendiente%')
);
}),
];
}Entonces su pagina customizada tendra tabs para poder filtrar y moverse con mas facilidad

© 2026 Krypton612. Todos los derechos reservados.