Filament: One Filter for Multiple Widgets with Livewire Events

In Filament, adding a filter to dashboard widgets is pretty straightforward. But what if you want to have a filter that would update MULTIPLE widgets at once, similar to Google Analytics? We need to use events and Livewire properties for this. Let's take a look.

filtered two charts


Widgets

First, let's create the widgets. We will need three widgets:

  • Form with date filters
  • Chart with orders
  • Chart with Users
php artisan make:filament-widget Filters
php artisan make:filament-widget OrdersChart --chart
php artisan make:filament-widget UsersChart --chart

For the charts, I will be using the bar type.

Now, let's show date inputs in the Filters widget with Filament Forms. Also, the Filters widget needs to be full width and have the $sort = 1 to be on top.

app/Filament/Widgets/Filters.php:

use Filament\Forms\Form;
use Filament\Forms\Components\Grid;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
 
class Filters extends Widget implements HasForms
{
use InteractsWithForms;
 
protected static string $view = 'filament.widgets.filters';
 
protected int | string | array $columnSpan = 'full';
 
protected static ?int $sort = 1;
 
public ?array $data = [];
 
public function form(Form $form): Form
{
return $form
->statePath('data')
->schema([
Grid::make()
->schema([
DatePicker::make('from'),
DatePicker::make('to'),
]),
]);
}
}

In the dashboard, we now have a widget with two date inputs.

filters widget

For the other two widgets, we will show a chart of two models, User and Order. These charts will show how many new records are created daily.

For passing data to the chart, we will use the package recommended by Filament flowframe/laravel-trend.

composer require flowframe/laravel-trend

And for the charts.

app/Filament/Widgets/OrdersChart.php:

use App\Models\Order;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;
 
class OrdersChart extends ChartWidget
{
protected static ?string $heading = 'Orders Chart';
 
protected static ?int $sort = 2;
 
protected function getData(): array
{
$data = Trend::model(Order::class)
->between(
start: now()->subWeek(),
end: now(),
)
->perDay()
->count();
 
return [
'datasets' => [
[
'label' => 'Orders',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
 
protected function getType(): string
{
return 'bar';
}
}

app/Filament/Widgets/UsersChart.php:

use App\Models\User;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;
 
class UsersChart extends ChartWidget
{
protected static ?string $heading = 'Users Chart';
 
protected static ?int $sort = 3;
 
protected function getData(): array
{
$data = Trend::model(User::class)
->between(
start: now()->subWeek(),
end: now(),
)
->perDay()
->count();
 
return [
'datasets' => [
[
'label' => 'Users',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
 
protected function getType(): string
{
return 'bar';
}
}

We also have two charts in the dashboard showing data from the week to now.

all widgets


Updating Charts

So now, let's update the charts when a filter is selected. To achieve this, we will need to...

The full tutorial [6 mins, 1042 words] is only for Premium Members

Login Or Become a Premium Member for $129/year or $29/month
What else you will get:
  • 68 courses (1188 lessons, total 43 h 18 min)
  • 90 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent New Courses