Columns
- Getting started
- Displaying data from relationships
- Text column
- Boolean column
- Image column
- Icon column
- Badge column
- Tags column
- View column
- Building custom columns
Getting started
Column classes can be found in the Filament\Tables\Columns
namespace.
If you're using the columns in a Livewire component, you can put them in the getTableColumns()
method:
protected function getTableColumns(): array{ return [ // ... ];}
If you're using them in admin panel resources or relation managers, you must put them in the $table->columns()
method:
public static function table(Table $table): Table{ return $table ->columns([ // ... ]);}
Columns may be created using the static make()
method, passing its name. The name of the column should correspond to a column or accessor on your model. You may use "dot syntax" to access columns within relationships.
use Filament\Tables\Columns\TextColumn; TextColumn::make('title') TextColumn::make('author.name')
Setting a label
By default, the label of the column, which is displayed in the header of the table, is generated from the name of the column. You may customize this using the label()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title')->label('Post title')
Sorting
Columns may be sortable, by clicking on the column label. To make a column sortable, you must use the sortable()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title')->sortable()
If you're using an accessor column, you may pass sortable()
an array of database columns to sort by:
use Filament\Tables\Columns\TextColumn; TextColumn::make('full_name')->sortable(['first_name', 'last_name'])
You may customize how the sorting is applied to the Eloquent query using a callback:
use Filament\Tables\Columns\TextColumn;use Illuminate\Database\Eloquent\Builder; TextColumn::make('full_name') ->sortable(query: function (Builder $query, string $direction): Builder { return $query ->orderBy('last_name', $direction) ->orderBy('first_name', $direction); })
Searching
Columns may be searchable, by using the text input in the top right of the table. To make a column searchable, you must use the searchable()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title')->searchable()
If you're using an accessor column, you may pass searchable()
an array of database columns to search within:
use Filament\Tables\Columns\TextColumn; TextColumn::make('full_name')->searchable(['first_name', 'last_name'])
You may customize how the search is applied to the Eloquent query using a callback:
use Filament\Tables\Columns\TextColumn;use Illuminate\Database\Eloquent\Builder; TextColumn::make('full_name') ->searchable(query: function (Builder $query, string $search): Builder { return $query ->where('first_name', 'like', "%{$search}%") ->where('last_name', 'like', "%{$search}%"); })
Cell actions and URLs
When a cell is clicked, you may run an "action", or open a URL.
Running actions
To run an action, you may use the action()
method, passing a callback or the name of a Livewire method to run. Each method accepts a $record
parameter which you may use to customize the behaviour of the action:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->action(function (Post $record): void { $this->dispatchBrowserEvent('open-post-edit-modal', [ 'post' => $record->getKey(), ]); })
Opening URLs
To open a URL, you may use the url()
method, passing a callback or static URL to open. Callbacks accept a $record
parameter which you may use to customize the URL:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
You may also choose to open the URL in a new tab:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->url(fn (Post $record): string => route('posts.edit', ['post' => $record])) ->openUrlInNewTab()
Setting a default value
To set a default value for fields with a null
state, you may use the default()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title')->default('Untitled')
Hiding columns
To hide a column conditionally, you may use the hidden()
and visible()
methods, whichever you prefer:
use Filament\Tables\Columns\TextColumn; TextColumn::make('role')->hidden(! auth()->user()->isAdmin())// orTextColumn::make('role')->visible(auth()->user()->isAdmin())
Toggling column visibility
Users may hide or show columns themselves in the table. To make a column toggleable, use the toggleable()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('id')->toggleable()
By default, toggleable columns are visible. To make them hidden instead:
use Filament\Tables\Columns\TextColumn; TextColumn::make('id')->toggleable(isToggledHiddenByDefault: true)
Responsive layouts
You may choose to show and hide columns based on the responsive breakpoint of the browser. To do this, you may use a visibleFrom()
or hiddenFrom()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('slug')->visibleFrom('md')
Tooltips
If you want to use tooltips outside of the admin panel, make sure you have
@ryangjchandler/alpine-tooltip
installed in your app, includingtippy.css
. You'll also need to installtippy.css
if you're using a custom admin theme.
You may specify a tooltip to display when you hover over a cell:
use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->tooltip('Title')
This method also accepts a closure that can access the current table record:
use Filament\Tables\Columns\TextColumn;use Illuminate\Database\Eloquent\Model; TextColumn::make('title') ->tooltip(fn (Model $record): string => "By {$record->author->name}")
Custom attributes
The HTML of columns can be customized, by passing an array of extraAttributes()
:
use Filament\Tables\Columns\TextColumn; TextColumn::make('slug')->extraAttributes(['class' => 'bg-gray-200'])
These get merged onto the outer <div>
element of each cell in that column.
Global settings
If you wish to change the default behaviour of all columns globally, then you can call the static configureUsing()
method inside a service provider's boot()
method, to which you pass a Closure to modify the columns using. For example, if you wish to make all columns sortable()
and toggleable()
, you can do it like so:
use Filament\Tables\Columns\Column; Column::configureUsing(function (Column $column): void { $column ->toggleable() ->sortable();});
Additionally, you can call this code on specific column types as well:
use Filament\Tables\Columns\BooleanColumn; BooleanColumn::configureUsing(function (BooleanColumn $column): void { $column ->toggleable() ->sortable();});
Of course, you are still able to overwrite this on each column individually:
use Filament\Tables\Columns\BooleanColumn; BooleanColumn::make('is_admin')->toggleable(false)
Displaying data from relationships
You may use "dot syntax" to access columns within relationships. The name of the relationship comes first, followed by a period, followed by the name of the column to display:
use Filament\Tables\Columns\TextColumn; TextColumn::make('author.name')
Counting relationships
If you wish to count the number of related records in a column, you may use the counts()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('users_count')->counts('users')
In this example, users
is the name of the relationship to count from. The name of the column must be users_count
, as this is the convention that Laravel uses for storing the result.
Determining relationship existence
If you simply wish to indicate whether related records exist in a column, you may use the exists()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('users_exists')->exists('users')
In this example, users
is the name of the relationship to check for existence. The name of the column must be users_exists
, as this is the convention that Laravel uses for storing the result.
Aggregating relationships
Filament provides several methods for aggregating a relationship field, including avg()
, max()
, min()
and sum()
. For instance, if you you wish to show the average of a field on all related records in a column, you may use the avg()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('users_avg_age')->avg('users', 'age')
In this example, users
is the name of the relationship, while age
is the field that is being averaged. The name of the column must be users_avg_age
, as this is the convention that Laravel uses for storing the result.
Text column
You may use the date()
and dateTime()
methods to format the column's state using PHP date formatting tokens:
use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at')->dateTime()
You may use the since()
method to format the column's state using Carbon's diffForHumans()
:
use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at')->since()
The money()
method allows you to easily format monetary values, in any currency. This functionality uses akaunting/laravel-money
internally:
use Filament\Tables\Columns\TextColumn; TextColumn::make('price')->money('eur')
You may limit()
the length of the cell's value:
use Filament\Tables\Columns\TextColumn; TextColumn::make('description')->limit(50)
You may also reuse the value that is being passed to limit()
:
use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->limit(50) ->tooltip(function (TextColumn $column): ?string { $state = $column->getState(); if (strlen($state) <= $column->getLimit()) { return null; } // Only render the tooltip if the column contents exceeds the length limit. return $state; })
If your column value is HTML, you may render it using html()
:
use Filament\Tables\Columns\TextColumn; TextColumn::make('description')->html()
You may also transform a set of known cell values using the enum()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('status')->enum([ 'draft' => 'Draft', 'reviewing' => 'Reviewing', 'published' => 'Published',])
You may instead pass a custom formatting callback to formatStateUsing()
, which accepts the $state
of the cell, and optionally its $record
:
use Filament\Tables\Columns\TextColumn; TextColumn::make('status') ->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))
If you'd like your column's content to wrap if it's too long, you may use the wrap()
method:
use Filament\Tables\Columns\TextColumn; TextColumn::make('description')->wrap()
Boolean column
Boolean columns render a check or cross icon representing their state:
use Filament\Tables\Columns\BooleanColumn; BooleanColumn::make('is_featured')
You may customize the icon representing each state. Icons are the name of a Blade component present. By default, Heroicons are installed:
use Filament\Tables\Columns\BooleanColumn; BooleanColumn::make('is_featured') ->trueIcon('heroicon-o-badge-check') ->falseIcon('heroicon-o-x-circle')
You may customize the icon color representing each state. These may be either primary
, secondary
, success
, warning
or danger
:
use Filament\Tables\Columns\BooleanColumn; BooleanColumn::make('is_featured') ->trueColor('primary') ->falseColor('warning')
Image column
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image')
You may make the image fully rounded()
, which is useful for rendering avatars:
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('author.avatar')->rounded()
You may customize the image size by passing a width()
and height()
, or both with size()
:
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image')->width(200) ImageColumn::make('header_image')->height(50) ImageColumn::make('author.avatar')->size(40)
By default, the public
disk will be used to retrieve images. You may pass a custom disk name to the disk()
method:
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image')->disk('s3')
Private images
Filament can generate temporary URLs to render private images, you may set the visibility()
to private
:
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image')->visibility('private')
You may customize the extra HTML attributes of the image using extraImgAttributes()
:
use Filament\Tables\Columns\ImageColumn; ImageColumn::make('logo') ->extraImgAttributes(['title' => 'Company logo']),
Icon column
Icon columns render a Blade icon component representing their contents:
use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->options([ 'heroicon-o-x-circle', 'heroicon-o-pencil' => 'draft', 'heroicon-o-clock' => 'reviewing', 'heroicon-o-check-circle' => 'published', ])
You may also pass a callback to activate an option, accepting the cell's $state
:
use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->options([ 'heroicon-o-x-circle', 'heroicon-o-pencil' => fn ($state): bool => $state === 'draft', 'heroicon-o-clock' => fn ($state): bool => $state === 'reviewing', 'heroicon-o-check-circle' => fn ($state): bool => $state === 'published', ])
Icon columns may also have a set of icon colors, using the same syntax. They may be either primary
, secondary
, success
, warning
or danger
:
use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->options([ 'heroicon-o-x-circle', 'heroicon-o-pencil' => 'draft', 'heroicon-o-clock' => 'reviewing', 'heroicon-o-check-circle' => 'published', ]) ->colors([ 'secondary', 'danger' => 'draft', 'warning' => 'reviewing', 'success' => 'published', ])
Badge column
Badge columns render a colored badge with the cell's contents. You may use the same formatting methods as for text columns:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->enum([ 'draft' => 'Draft', 'reviewing' => 'Reviewing', 'published' => 'Published', ])
Badges may have a color. It may be either primary
, success
, warning
or danger
:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->colors([ 'primary', 'danger' => 'draft', 'warning' => 'reviewing', 'success' => 'published', ])
You may instead activate a color using a callback, accepting the cell's $state
:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->colors([ 'primary', 'danger' => fn ($state): bool => $state === 'draft', 'warning' => fn ($state): bool => $state === 'reviewing', 'success' => fn ($state): bool => $state === 'published', ])
Badges may also have an icon:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->icons([ 'heroicon-o-x', 'heroicon-o-document' => 'draft', 'heroicon-o-refresh' => 'reviewing', 'heroicon-o-truck' => 'published', ])
Alternatively, you may conditionally display an icon using a closure:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->icons([ 'heroicon-o-x', 'heroicon-o-document' => fn ($state): bool => $state === 'draft', 'heroicon-o-refresh' => fn ($state): bool => $state === 'reviewing', 'heroicon-o-truck' => fn ($state): bool => $state === 'published', ])
You may set the position of an icon using iconPosition()
:
use Filament\Tables\Columns\BadgeColumn; BadgeColumn::make('status') ->icons([ 'heroicon-o-x', 'heroicon-o-document' => 'draft', 'heroicon-o-refresh' => 'reviewing', 'heroicon-o-truck' => 'published', ]) ->iconPosition('after') // `before` or `after`
Tags column
Tags columns render a list of tags from an array:
use Filament\Tables\Columns\TagsColumn; TagsColumn::make('tags')
Be sure to add an array
cast to the model property:
use Illuminate\Database\Eloquent\Model; class BlogPost extends Model{ protected $casts = [ 'tags' => 'array', ]; // ...}
Instead of using an array, you may use a separated string by passing the separator into separator()
:
use Filament\Tables\Columns\TagsColumn; TagsColumn::make('tags')->separator(',')
View column
You may render a custom view for a cell using the view()
method:
use Filament\Tables\Columns\ViewColumn; ViewColumn::make('status')->view('filament.tables.columns.status-switcher')
Inside your view, you may retrieve the state of the cell using the $getState()
method:
<div> {{ $getState() }}</div>
Building custom columns
You may create your own custom column classes and cell views, which you can reuse across your project, and even release as a plugin to the community.
If you're just creating a simple custom column to use once, you could instead use a view column to render any custom Blade file.
To create a custom column class and view, you may use the following command:
php artisan make:table-column StatusSwitcher
This will create the following column class:
use Filament\Tables\Columns\Column; class StatusSwitcher extends Column{ protected string $view = 'filament.tables.columns.status-switcher';}
Inside your view, you may retrieve the state of the cell using the $getState()
method:
<div> {{ $getState() }}</div>
Still need help? Join our Discord community or open a GitHub discussion