Filament v4 introduced a new table feature custom data where you can show data in a table not from a SQL query, but, for example, from an API. But what if in this custom data table you need a summary? Out of the box, it isn't available, but I can show you a workaround.
If you try to use the Sum
summarizer on the field, you would get a TypeError Exception.
TextColumn::make('price') ->money() ->summarize(Sum::make()->money())
This is because the summary expects an Eloquent query. For a workaround, you can pass whatever model as a query.
public function table(Table $table): Table{ return $table ->query(User::query()) ->records(fn (): array => Http::baseUrl('https://dummyjson.com') ->get('products', ['limit' => 5]) ->collect() ->get('products', []) ) ->columns([ TextColumn::make('title'), TextColumn::make('category'), TextColumn::make('price') ->money() ->summarize(Sum::make()->money())}
However, you will now receive a Query Exception because Filament will attempt to create a query to calculate a summary.
Instead, you need to add a custom summary and do the calculation manually in it.
public function table(Table $table): Table{ return $table ->query(User::query()) ->records(fn (): array => Http::baseUrl('https://dummyjson.com') ->get('products', ['limit' => 5]) ->collect() ->get('products', []) ) ->columns([ TextColumn::make('title'), TextColumn::make('category'), TextColumn::make('price') ->money() ->summarize(Sum::make()->money()) ->summarize(Summarizer::make('sum') ->money() ->using(function (self $livewire): int { return $livewire->getTableRecords()->sum('price'); }) ), ]);}
Because custom data can be used only on the custom page, and every page is a Livewire component, we can inject this page and retrieve all the table records, which are returned as a collection. Then we can use the sum()
method to add all the prices together.
This tutorial's code comes from our Project Example Hotel Bookings and Hotel Management
A few of our Premium Examples: