Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Grepy's avatar
Level 1

getTableColumns() is not fully reactive

I have created custom page in filament with filter form and report table.

Filter form has month field, where user can choose for which month (and year) he wants to display the report.

The report table has all workers (users) as rows, all days in selected month as columns and in the cells it shows whether given worker was present on given day.

I made month select reactive so whenever user changes the month, new data is loaded instantly - for selected month.

It works fine with getTableQuery() function - in it's body, I call $this->form->getState(); and according to selected month I compose correct query.

But I want also the number of columns to change dynamically. I defined my getTableColumns function like this:

protected function getTableColumns(): array
    {
        $columns = [
            TextColumn::make('name')
        ];

        // Get current filter values and current month/year combination from it
        $filter = $this->form->getState();
        list($month, $year) = explode('/', $filter['month']);
        $date = new DateTime("$year-$month-01");

		// Get number of days in selected month
        $monthDays = (int) $date->format('t');
		
		// Make column for each day of month
        for ($i = 1; $i <= $monthDays; $i++) {
            $columns[] = TextColumn::make('day' . $i);
        }

        return $columns;
    }

But when I change the month nothing happens, only after second change table columns refresh, but with previously selected month and not the current one. Values in the table are fetched correctly.

Is this a bug or am I missing something? Do you suggest different approach for what I want to achieve?

Thanks!

0 likes
1 reply
Grepy's avatar
Grepy
OP
Best Answer
Level 1

Tom on stackoverflow helped me to solve my issue:

He pointed out that Filament caches most of the properties, which normally aren't refreshed. So I will have to call some sort of refresh function for the table columns.

Solution was to refresh the table columns cache when month in filter was updated:

Select::make('month')
    ->options($months)
    ->reactive()
    ->afterStateUpdated(function() {

        // This does the job:
        $this->cachedTableColumns = [];
        $this->cacheTableColumns();

    }),

Please or to participate in this conversation.