If you need to show a Table column that is not directly from the DB table but calculated from other columns, the best way is to use the Laravel feature of Eloquent Accessor. Let me show you how.
For example, you have columns users.created_at
and users.email_verified_at
, standard in Laravel projects.
And you want to show the third column of time difference between them. In other words, how fast the user verified their email.
Filament State Methods Wouldn't Work
If you try to create this dynamic column with Filament options like ->formatStateUsing()
or ->state()
on the column, it wouldn't work:
app/Filament/Resources/UserResource.php:
public static function table(Table $table): Table{ return $table ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('created_at'), Tables\Columns\TextColumn::make('email_verified_at'), Tables\Columns\TextColumn::make('verified_in_time') // Both of the options above would NOT work ->state(function (User $record) { // return ... }) ->formatStateUsing(function (Model $record) { // return ... }), ])
This is because those "state" options rely on the same column to be modified. And since the column verified_in_time
isn't returned from the Eloquent query, Filament would skip those methods and just show an empty value in the table.
The Solution: Eloquent Accessor
You need to define it as an Attribute in the Eloquent Model and calculate it there. Then, Filament would recognize it as a column without any additional modifier methods.
app/Models/User.php:
class User extends Authenticatable{ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } public function getVerifiedInTimeAttribute() { return $this->email_verified_at?->diffForHumans($this->created_at); }}
And then you can use it as a "regular" column in the Filament table:
app/Filament/Resources/UserResource.php:
public static function table(Table $table): Table{ return $table ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('created_at'), Tables\Columns\TextColumn::make('email_verified_at'), Tables\Columns\TextColumn::make('verified_in_time'), ])
Remember that for this particular example with datetime columns, you must also perform casts()
in the Eloquent Model for the email_verified_at
to calculate the difference this way, with the Carbon library under the hood. By default, the column created_at
is cast to datetime automatically by Laravel for every model.
If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.
hallo admin, can we make custom table ? for make complex table, if it can, can you make the tutorial,
Hi, we are unsure what you mean by "make complex table". Can you give an example?
like this one sir https://www.nysed.gov/file/complex-tablegif