Filament PHP v3:如何让Dashboard筛选表单数据供Widget调用
在Filament PHP v3中实现Dashboard筛选条件与Widget的数据共享
步骤1:修改Dashboard传递筛选参数
在Dashboard.php中给日期选择器添加实时更新,并通过getWidgets()方法把筛选条件传递给目标Widget:
<?php namespace App\Filament\Pages; use Filament\Forms\Components\DatePicker; use Filament\Forms\Components\Section; use Filament\Forms\Form; use Filament\Forms\Get; use Filament\Pages\Dashboard as BaseDashboard; class Dashboard extends BaseDashboard { use BaseDashboard\Concerns\HasFiltersForm; public function getColumns(): int | string | array { return 2; } public function filtersForm(Form $form): Form { return $form ->schema([ Section::make() ->schema([ DatePicker::make('startDate') ->maxDate(fn (Get $get) => $get('endDate') ?: now()) ->live(), // 实时同步筛选值 DatePicker::make('endDate') ->minDate(fn (Get $get) => $get('startDate') ?: now()) ->maxDate(now()) ->live(), // 实时同步筛选值 ]) ->columns(2), ]); } // 重写getWidgets传递筛选参数 protected function getWidgets(): array { return [ \App\Filament\Widgets\KeyMetricsOverview::class => [ 'startDate' => $this->filters['startDate'] ?? null, 'endDate' => $this->filters['endDate'] ?? null, ], \App\Filament\Widgets\CustomersChart::class => [ 'startDate' => $this->filters['startDate'] ?? null, 'endDate' => $this->filters['endDate'] ?? null, ], ]; } }
步骤2:修改CustomersChart接收并使用筛选参数
在CustomersChart.php中添加公共属性接收日期参数,在数据查询中应用筛选条件:
<?php namespace App\Filament\Widgets; use Filament\Widgets\ChartWidget; use Carbon\Carbon; use App\Models\Customer; class CustomersChart extends ChartWidget { protected static ?string $heading = 'Customers'; protected static ?int $sort = 3; public ?string $filter = 'today'; // 声明接收筛选条件的公共属性 public ?Carbon $startDate = null; public ?Carbon $endDate = null; protected function getData(): array { // 构建带时间筛选的查询 $query = Customer::query(); if ($this->startDate) { $query->where('created_at', '>=', $this->startDate); } if ($this->endDate) { $query->where('created_at', '<=', $this->endDate->endOfDay()); } // 按月份分组统计客户数量(替换为你的业务逻辑) $monthlyData = $query->selectRaw('MONTH(created_at) as month, COUNT(*) as count') ->groupBy('month') ->orderBy('month') ->pluck('count', 'month') ->toArray(); // 补全12个月的空数据 $labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; $filledData = array_map(fn($month) => $monthlyData[$month] ?? 0, range(1, 12)); return [ 'datasets' => [ [ 'label' => 'Blog posts created', 'data' => $filledData, ], [ 'label' => 'Blog posts created 2', 'data' => $filledData, ], ], 'labels' => $labels, ]; } protected function getType(): string { return 'line'; } protected function getFilters(): ?array { return [ 'today' => 'Today', 'week' => 'Last week', 'month' => 'Last month', 'year' => 'This year', ]; } // 兼容Widget自身筛选逻辑 public function mount(): void { parent::mount(); if (!$this->startDate || !$this->endDate) { switch ($this->filter) { case 'today': $this->startDate = Carbon::today(); $this->endDate = Carbon::today()->endOfDay(); break; case 'week': $this->startDate = Carbon::now()->subWeek(); $this->endDate = Carbon::now(); break; case 'month': $this->startDate = Carbon::now()->subMonth(); $this->endDate = Carbon::now(); break; case 'year': $this->startDate = Carbon::now()->startOfYear(); $this->endDate = Carbon::now(); break; } } } }
步骤3:修改KeyMetricsOverview接收并使用筛选参数
在KeyMetricsOverview.php中添加公共属性,更新统计逻辑:
<?php namespace App\Filament\Widgets; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; use Carbon\Carbon; use App\Models\Customer; class KeyMetricsOverview extends BaseWidget { protected static ?int $sort = 1; // 声明接收筛选条件的公共属性 public ?Carbon $startDate = null; public ?Carbon $endDate = null; protected function getColumns(): int { return 2; } protected function getStats(): array { // 构建带时间筛选的查询 $query = Customer::query(); if ($this->startDate) { $query->where('created_at', '>=', $this->startDate); } if ($this->endDate) { $query->where('created_at', '<=', $this->endDate->endOfDay()); } // 计算客户流失率(替换为你的业务逻辑) $totalCustomers = $query->count(); $churnedCustomers = $query->where('status', 'churned')->count(); $churnRate = $totalCustomers > 0 ? number_format(($churnedCustomers / $totalCustomers) * 100, 2) . '%' : '0%'; // 计算平均客户生命周期(替换为你的业务逻辑) $avgLifetime = $query->avg('lifetime_months') ?? 0; $avgLifetimeFormatted = number_format($avgLifetime, 3) . ' months'; return [ Stat::make('Customer churn', $churnRate) ->description('57.5%') ->descriptionIcon('heroicon-m-arrow-trending-up') ->color('danger'), Stat::make('Avg. customer lifetime', $avgLifetimeFormatted) ->description('-36.51%') ->descriptionIcon('heroicon-m-arrow-trending-up') ->color('danger'), ]; } }
核心说明
->live():让日期选择器的变化实时同步到Dashboard的filters属性,无需手动提交。- 参数传递:通过
getWidgets()中的数组参数,Filament会自动将值赋值给Widget的对应公共属性。 - 逻辑兼容:如果Widget自身有筛选逻辑,可在
mount()方法中处理默认值,优先使用Dashboard传递的筛选条件。
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

