F
Filament13mo ago
Rahul

Execution Order Change Causing Filter Value Mismatch in Filament-v3 Widget

I have designed a filter inside a widget that extends from TableWidget. Within this widget, I have implemented two functions: getTableQuery() and getTableFilters(). Now, I am in the process of upgrading this widget from Filament-v2 to Filament-v3. In Filament-v2, getTableFilters() is executed first, and based on its output, getTableQuery() is subsequently executed. However, in Filament-v3, the order of execution has changed. It now directly executes getTableQuery, and this change is causing issues, as when I select a value from the filter, the data is not fetched correctly. Is there any alternative method or solution available that would allow me to access the current filter value? in the v2 it is written like this $month_selected = $this->getTableFilterState("attendance_month")["value"]; while getTableFilterState() is not working in v3 so in the v3 i write like this $month_selected = $this->tableFilters['attendance_month']['value']; Initially, when I dump $month_selected in version 3, it returns a null value. However, after selecting another month, such as April, and then dumping $month_selected, it displays the previously selected month, in this case, October. and also when i dd($this->tableFilters) it returns a null value. In Filament-v2, getTableFilters() executes first, and then getTableQuery(), which works perfectly. In Filament-v3, getTableQuery() executes first, causing this issue. Any insights on how to address this problem would be greatly appreciated.
12 Replies
Rahul
RahulOP13mo ago
How to Solve it ??
Skjena
Skjena13mo ago
I've also been facing the same issue. Has there been a change in the order of execution in Filament-v3 compared to Filament-v2? In Filament-v2, the getTableFilters method was called first, followed by the getTableQuery method. However, in Filament-v3, it seems that the getTableQuery method is called first, and then the getTableFilters method is called. Can someone confirm if this order change is intentional and provide insights on how to work with it effectively ?
toeknee
toeknee13mo ago
@danharrin If you have a minute can you advise on this execution order issue.
Dan Harrin
Dan Harrin13mo ago
the change is intentional. please send code and what you are trying to do
Skjena
Skjena13mo ago
Thanks for your response. I've created a custom table widget, which extends from TableWidget, I'm using the following methods: getTableQuery() for designing the table query, getTableFilters() for setting up the table filter, and getTableColumns() for configuring the table columns. My goal is to access the current filter value within the getTableQuery() method to customize my query value based on the filter selection and also determine the number of columns the table should return.
Dan Harrin
Dan Harrin13mo ago
the query() method of the filter is used to access the $data and modify the $query so i dont follow
Skjena
Skjena13mo ago
Here is the getTableFilters code
protected function getTableFilters(): array
{
$today = Carbon::parse(DB::select(DB::raw('
SELECT NOW() AS ctime'))[0]->ctime);
$months_list = [];
$day = now();
for ($i = 0; $i < 12; $i++) {
$months_list[$day->format('Y-m-01')] = $day->format('F Y');
$day->subMonth(1);
}
return [

Filter::make('month')
->form([
Select::make('value')
->disablePlaceholderSelection()
->options($months_list)
->default($today->format('Y-m-01'))
->extraAttributes([
'class'=>'month-filter'
]),
])
];
}

protected function getTableFilters(): array
{
$today = Carbon::parse(DB::select(DB::raw('
SELECT NOW() AS ctime'))[0]->ctime);
$months_list = [];
$day = now();
for ($i = 0; $i < 12; $i++) {
$months_list[$day->format('Y-m-01')] = $day->format('F Y');
$day->subMonth(1);
}
return [

Filter::make('month')
->form([
Select::make('value')
->disablePlaceholderSelection()
->options($months_list)
->default($today->format('Y-m-01'))
->extraAttributes([
'class'=>'month-filter'
]),
])
];
}

and Here is the getTableQuery code
protected function getTableQuery(): Builder
{
$columns = [DB::raw("employee_id AS id"), "employee_id"];

$month_selected = $this->tableFilters["month"]["value"];
$month_dates = $this->getMonthDates($month_selected);

foreach ($month_dates as $month_date) {
$date = explode("-", $month_date);
$date = end($date);
$columns[] = DB::raw("
CONCAT(
'{$month_date} = ',
CAST(ROUND(
SUM(
CASE
WHEN DATE_FORMAT(day, '%Y-%m-%d') = '{$month_date}' THEN worked_hours
ELSE 0
END
)
, 2) AS CHAR)
) AS `{$date}`
");
}

return ModelName::query()
->select($columns);
}
protected function getTableQuery(): Builder
{
$columns = [DB::raw("employee_id AS id"), "employee_id"];

$month_selected = $this->tableFilters["month"]["value"];
$month_dates = $this->getMonthDates($month_selected);

foreach ($month_dates as $month_date) {
$date = explode("-", $month_date);
$date = end($date);
$columns[] = DB::raw("
CONCAT(
'{$month_date} = ',
CAST(ROUND(
SUM(
CASE
WHEN DATE_FORMAT(day, '%Y-%m-%d') = '{$month_date}' THEN worked_hours
ELSE 0
END
)
, 2) AS CHAR)
) AS `{$date}`
");
}

return ModelName::query()
->select($columns);
}
Dan Harrin
Dan Harrin13mo ago
so what is this doing im sure you can refactor this to use query() or baseQuery() on the filter object
Skjena
Skjena13mo ago
In V2 i used

$month_selected = $this->getTableFilterState("attendance_month")["value"]; //V2

$month_selected = $this->getTableFilterState("attendance_month")["value"]; //V2
able to get the current filter value. but in V3 $month_selected = $this->tableFilters["month"]["value"]; returns null
Dan Harrin
Dan Harrin13mo ago
i know its different but im trying to suggest the alternative because this really isn't how it was designed to be used, even in v2
Skjena
Skjena13mo ago
Is there an alternative method to obtain the filter value within the getTableQuery() function, given that my table query builder relies on the filter value to determine both the query and the number of columns to return, making it impractical to handle using query() within the filter? I am unable to utilize the suggested approach as advised by others also like
Filter::make('month')
->form([
Select::make('value')
->disablePlaceholderSelection()
->options($months_list)
->default($today->format('Y-m-01')),
])
->query(function (Builder $query, array $data): Builder {
//code
})
Filter::make('month')
->form([
Select::make('value')
->disablePlaceholderSelection()
->options($months_list)
->default($today->format('Y-m-01')),
])
->query(function (Builder $query, array $data): Builder {
//code
})
because my objective is a bit different.
Dan Harrin
Dan Harrin13mo ago
i dont understand, what is stopping you for using this on the query? for hiding/showing columns, that is still possible ->hidden(fn () => $this->getTableFilterState(...))
Want results from more Discord servers?
Add your server