Search code examples
phpreactivelaravel-filament

How to make table columns reactive in Laravel Filament?


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!


Solution

  • As Tom mentioned in his comment: "Filament caches most of the properties, which normally aren't refreshed. So you will probably have to call some sort of refresh function for the table columns." Using the link he provided I solved my problem by reseting table columns cache after month select is changed:

    Select::make('month')
        ->options($months)
        ->reactive()
        ->afterStateUpdated(function() {
    
            // This does the job:
            $this->cachedTableColumns = [];
            $this->cacheTableColumns();
    
        }),