One datepicker filter for multiple chart widgets in Admin dashboard

How do I make one date picker to filter multiple chart widgets on the admin dashboard when the value changes? I'm using a custom Widget for the datepicker and would like to know what's the best practice for other widgets to interact after a DOM event is dispatched.
2 Replies
albertosemesale
albertosemesale4mo ago
Code for the datepicker Filter custom widget
<?php

namespace App\Filament\Widgets;

use Livewire\Livewire;
use Filament\Forms\Form;
use Filament\Widgets\Widget;
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;

public $selectedDate;

protected static string $view = 'filament.widgets.filters';

protected int | string | array $columnSpan = 'full';

protected static ?int $sort = 1;

public ?array $data = [];
public $dateFrom="";
public $dateTo="";

public function dateFromSelected($data){
$this->dateFrom = $data;

logger($this->dateFrom." ".$this->dateTo);

}
public function dateToSelected($data){
$this->dateTo= $data;

logger($this->dateFrom." ".$this->dateTo);

}

}
<?php

namespace App\Filament\Widgets;

use Livewire\Livewire;
use Filament\Forms\Form;
use Filament\Widgets\Widget;
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;

public $selectedDate;

protected static string $view = 'filament.widgets.filters';

protected int | string | array $columnSpan = 'full';

protected static ?int $sort = 1;

public ?array $data = [];
public $dateFrom="";
public $dateTo="";

public function dateFromSelected($data){
$this->dateFrom = $data;

logger($this->dateFrom." ".$this->dateTo);

}
public function dateToSelected($data){
$this->dateTo= $data;

logger($this->dateFrom." ".$this->dateTo);

}

}
Code for the chart filter
<?php

namespace App\Filament\Widgets;

use App\Models\punto;
use Flowframe\Trend\Trend;

use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;

class NewPuntoChart extends ChartWidget
{


protected static ?string $heading = 'Puntos Noroeste';

protected static ?int $sort = 2;

public $chartData;

protected $listeners = ["fromFilterChanged"];

public function fromFilterChanged($newFilter){
$this->chartData = $newFilter;
logger("Received");
logger($this->chartData);
}

protected function getFilters(): ?array
{
return [
'today' => 'Today',
'week' => 'Last week',
'month' => 'Last month',
'year' => 'This year',
];
}

protected function getData(): array
{


$trend = Trend::model(punto::class)
->dateColumn('date')->between(
start: now()->startOfYear(),
end: now()->endOfYear(),
)
->perMonth()
->count();


return [
'datasets' => [
[
'label' => 'Puntos',
'data' => $trend->map(fn(TrendValue $value) => $value->aggregate),
],
],
'labels' => $trend->map(fn(TrendValue $value) =>$value->date)
];
}

protected function getType(): string
{
return 'bar';
}
}
<?php

namespace App\Filament\Widgets;

use App\Models\punto;
use Flowframe\Trend\Trend;

use Flowframe\Trend\TrendValue;
use Filament\Widgets\ChartWidget;

class NewPuntoChart extends ChartWidget
{


protected static ?string $heading = 'Puntos Noroeste';

protected static ?int $sort = 2;

public $chartData;

protected $listeners = ["fromFilterChanged"];

public function fromFilterChanged($newFilter){
$this->chartData = $newFilter;
logger("Received");
logger($this->chartData);
}

protected function getFilters(): ?array
{
return [
'today' => 'Today',
'week' => 'Last week',
'month' => 'Last month',
'year' => 'This year',
];
}

protected function getData(): array
{


$trend = Trend::model(punto::class)
->dateColumn('date')->between(
start: now()->startOfYear(),
end: now()->endOfYear(),
)
->perMonth()
->count();


return [
'datasets' => [
[
'label' => 'Puntos',
'data' => $trend->map(fn(TrendValue $value) => $value->aggregate),
],
],
'labels' => $trend->map(fn(TrendValue $value) =>$value->date)
];
}

protected function getType(): string
{
return 'bar';
}
}
bump bunp bump
awcodes
awcodes4mo ago
Just dispatch to the browser when it changes. And add listeners to your other widgets that can update their state when it’s heard. It’s standard livewire events and listeners. Check the livewire docs.