Table: Common Filters as Buttons Above Table

2024-10-24

Filament table can have many filters. What if you could add the most common filters as a BUTTON, like shortcuts to apply them? Let's see how to add it.


In this example I have a simple ternary filter for showing published and not published yet products based on the current date.

TernaryFilter::make('published_at')
->label('Published')
->queries(
true: fn (Builder $query) => $query->where('published_at', '<=', now()),
false: fn (Builder $query) => $query->where('published_at', '>=', now()),
blank: fn (Builder $query) => $query,
),

To add buttons above the table, we must use render hook to render a View file. This render hook is scoped to one particular list page class.

app/Providers/AppServiceProvider.php:

use Illuminate\View\View;
use Filament\View\PanelsRenderHook;
use Illuminate\Support\ServiceProvider;
use Filament\Support\Facades\FilamentView;
use App\Filament\Resources\ProductResource\Pages\ListProducts;
 
class AppServiceProvider extends ServiceProvider
{
// ...
 
public function boot(): void
{
FilamentView::registerRenderHook(
PanelsRenderHook::RESOURCE_PAGES_LIST_RECORDS_TABLE_BEFORE,
fn (): View => view('filament.hooks.table-filters'),
scopes: [
ListProducts::class,
]
);
}
}

In the View file, we will add three buttons: one for removing the filters and two for applying them. When the button is pressed, the tableFilters property must be set. We can set it using Alpine.js x-on:click directive. To reset filters, Filament has a removeTableFilters() method.

resources/views/filament/hooks/table-filters.blade.php:

<div class="flex justify-end">
<x-filament::button color="gray" outlined x-on:click="$wire.call('removeTableFilters')">
All
</x-filament::button>
 
<x-filament::button color="gray" outlined x-on:click="$wire.set('tableFilters', {'published_at': {'value': '1'}})">
Published
</x-filament::button>
 
<x-filament::button color="gray" outlined x-on:click="$wire.set('tableFilters', {'published_at': {'value': '0'}})">
Not published
</x-filament::button>
</div>

When the button is clicked, the filter is applied.

A few of our Premium Examples: