File: docs/03-columns/01-getting-started.md
title: 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')Available columns
Filament ships with two main types of columns - static and editable.
Static columns display data to the user:
Editable columns allow the user to update data in the database without leaving the table:
You may also create your own custom columns to display data however you wish.
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')Optionally, you can have the label automatically translated by using the translateLabel() method:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')->translateLabel() // Equivalent to `label(__('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);
})If a column is sortable(), you may choose to sort it by default using the getDefaultTableSortColumn() and getDefaultTableSortDirection() methods:
protected function getDefaultTableSortColumn(): ?string
{
return 'full_name';
}
protected function getDefaultTableSortDirection(): ?string
{
return 'asc';
}Persist sort in session
To persist the sort in the user's session, override the shouldPersistTableSortInSession() method on the Livewire component:
protected function shouldPersistTableSortInSession(): bool
{
return true;
}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}%");
})Searching individually
You can choose to enable a per-column search input using the isIndividual parameter:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')->searchable(isIndividual: true)If you use the isIndividual parameter, you may still search that column using the main "global" search input for the entire table.
To disable that functionality while still preserving the individual search functionality, you need the isGlobal parameter:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')->searchable(isIndividual: true, isGlobal: false)You may optionally persist the searches in the query string:
protected $queryString = [
// ...
'tableColumnSearchQueries',
];Persist search in session
To persist the table or individual column search in the user's session, override the shouldPersistTableSearchInSession() or shouldPersistTableColumnSearchInSession() method on the Livewire component:
protected function shouldPersistTableSearchInSession(): bool
{
return true;
}
protected function shouldPersistTableColumnSearchInSession(): bool
{
return true;
}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(),
]);
})Action modals
You may open action modals by passing in an Action object to the action() method:
use Filament\Tables\Actions\Action;
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')
->action(
Action::make('select')
->requiresConfirmation()
->action(function (Post $record): void {
$this->dispatchBrowserEvent('select-post', [
'post' => $record->getKey(),
]);
}),
)Action objects passed into the action() method must have a unique name to distinguish it from other actions within the table.
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())
// or
TextColumn::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)Calculated state
Sometimes you need to calculate the state of a column, instead of directly reading it from a database column.
By passing a callback function to the getStateUsing() method, you can customize the returned state for that column based on the $record:
Tables\Columns\TextColumn::make('amount_including_vat')
->getStateUsing(function (Model $record): float {
return $record->amount * (1 + $record->vat_rate);
})Tooltips
If you want to use tooltips outside of the admin panel, make sure you have
@ryangjchandler/alpine-tooltipinstalled in your app, includingtippy.css. You'll also need to installtippy.cssif 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 `` 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\TextColumn;
TextColumn::configureUsing(function (TextColumn $column): void {
$column
->toggleable()
->sortable();
});Of course, you are still able to overwrite this on each column individually:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('name')->toggleable(false)File: docs/03-columns/02-text.md
title: Text column
Text columns display simple text from your database:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')Displaying a description
Descriptions may be used to easily render additional text above or below the column contents.
You can display a description below the contents of a text column using the description() method:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')
->description(fn (Post $record): string => $record->description)By default, the description is displayed below the main text, but you can move it above using the second parameter:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')
->description(fn (Post $record): string => $record->description, position: 'above')Date formatting
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()Currency formatting
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')Alternatively, you can set the default currency through the environment variable DEFAULT_CURRENCY.
Limiting text length
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;
})Limiting word count
You may limit the number of words() displayed in the cell:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')->words(10)Wrapping content
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()Rendering HTML
If your column value is HTML, you may render it using html():
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')->html()Enum formatting
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',
])Displaying the row index
You may want a column to contain the number of the current row in the table:
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Contracts\HasTable;
TextColumn::make('index')->getStateUsing(
static function (stdClass $rowLoop, HasTable $livewire): string {
return (string) (
$rowLoop->iteration +
($livewire->tableRecordsPerPage * (
$livewire->getPage() - 1
))
);
}
),As $rowLoop is Laravel Blade's $loop object, you can reference all other $loop properties.
Custom formatting
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}"))Adding a placeholder if the cell is empty
Sometimes you may want to display a placeholder if the cell's value is empty:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('updated_at')
->placeholder('Never')Customizing the color
You may set a color for the text, either primary, secondary, success, warning or danger:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('status')
->color('primary')Adding an icon
Text columns may also have an icon:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->icon('heroicon-s-mail')You may set the position of an icon using iconPosition():
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->icon('heroicon-s-mail')
->iconPosition('after') // `before` or `after`Customizing the text size
You may make the text smaller using size('sm'):
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->size('sm')Or you can make it larger using size('lg'):
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')
->size('lg')Customizing the font weight
Text columns have regular font weight by default but you may change this to any of the the following options: thin, extralight, light, medium, semibold, bold, extrabold or black.
For instance, you may make the font bold using weight('bold'):
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->weight('bold')Customizing the font family
You can change the text font family to any of the following options: sans, serif or mono.
For instance, you may make the font mono using fontFamily('mono'):
use Filament\Tables\Columns\TextColumn;
TextColumn::make('text')
->fontFamily('mono')Allowing the text to be copied to the clipboard
You may make the text copyable, such that clicking on the cell copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->copyable()
->copyMessage('Email address copied')
->copyMessageDuration(1500)Filament uses tooltips to display the copy message in the admin panel. If you want to use the copyable feature outside of the admin panel, make sure you have
@ryangjchandler/alpine-tooltipinstalled in your app.
Customizing the text that is copied to the clipboard
You can customize the text that gets copied to the clipboard using the `copyableState() method:
use Filament\Tables\Columns\TextColumn;
TextColumn::make('url')
->copyable()
->copyableState(fn (string $state): string => "URL: {$state}")In this function, you can access the whole table row with $record:
use App\Models\Post;
use Filament\Tables\Columns\TextColumn;
TextColumn::make('url')
->copyable()
->copyableState(fn (Post $record): string => "URL: {$record->url}")File: docs/03-columns/03-icon.md
title: 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 and $record:
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->options([
'heroicon-o-x-circle',
'heroicon-o-pencil' => fn ($state, $record): bool => $record->status === 2,
'heroicon-o-clock' => fn ($state): bool => $state === 'reviewing',
'heroicon-o-check-circle' => fn ($state): bool => $state === 'published',
])Customizing the color
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',
])Customizing the size
The default icon size is lg, but you may customize the size to be either xs, sm, md, lg or xl:
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->options([
'heroicon-s-x-circle',
'heroicon-s-pencil' => 'draft',
'heroicon-s-clock' => 'reviewing',
'heroicon-s-check-circle' => 'published',
])
->size('md')Handling booleans
Icon columns can display a check or cross icon based on the contents of the database column, either true or false, using the boolean() method:
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean()Customizing the boolean icons
You may customize the icon representing each state. Icons are the name of a Blade component present. By default, Heroicons v1 are installed:
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean()
->trueIcon('heroicon-o-badge-check')
->falseIcon('heroicon-o-x-circle')Customizing the boolean colors
You may customize the icon color representing each state. These may be either primary, secondary, success, warning or danger:
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean()
->trueColor('primary')
->falseColor('warning')File: docs/03-columns/04-image.md
title: Image column
Images can be easily displayed within your table:
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('header_image')The column in the database must contain the path to the image, relative to the root directory of its storage disk.
Managing the image disk
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')Square image
You may display the image using a 1:1 aspect ratio:
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('author.avatar')->square()Circular image
You may make the image fully rounded, which is useful for rendering avatars:
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('author.avatar')->circular()Customizing the size
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)Adding a default image URL
You can display a placeholder image if one doesn't exist yet, by passing a URL to the defaultImageUrl() method:
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
->defaultImageUrl(url('/images/placeholder.png'))Custom attributes
You may customize the extra HTML attributes of the image using extraImgAttributes():
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('logo')
->extraImgAttributes(['title' => 'Company logo']),File: docs/03-columns/05-badge.md
title: Badge column
Badge columns render a colored badge with the cell's contents:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('status')
->enum([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])Customizing the color
Badges may have a color. It may be either primary, secondary, success, warning or danger:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('status')
->colors([
'primary',
'secondary' => 'draft',
'warning' => 'reviewing',
'success' => 'published',
'danger' => 'rejected',
])You may instead activate a color using a callback, accepting the cell's $state:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('status')
->colors([
'primary',
'secondary' => static fn ($state): bool => $state === 'draft',
'warning' => static fn ($state): bool => $state === 'reviewing',
'success' => static fn ($state): bool => $state === 'published',
'danger' => static fn ($state): bool => $state === 'rejected',
])Or dynamically calculate the color based on the $record and / or $state:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('status')
->color(static function ($state): string {
if ($state === 'published') {
return 'success';
}
return 'secondary';
})Adding an icon
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' => static fn ($state): bool => $state === 'draft',
'heroicon-o-refresh' => static fn ($state): bool => $state === 'reviewing',
'heroicon-o-truck' => static fn ($state): bool => $state === 'published',
])Or dynamically calculate the icon based on the $record and / or $state:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('status')
->icon(static function ($state): string {
if ($state === 'published') {
return 'heroicon-o-truck';
}
return 'heroicon-o-x';
})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`Formatting the text
All formatting options available for text columns are also available for badge columns.
Allowing the text to be copied to the clipboard
You may make the text copyable, such that clicking on the cell copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('email')
->copyable()
->copyMessage('Email address copied')
->copyMessageDuration(1500)Filament uses tooltips to display the copy message in the admin panel. If you want to use the copyable feature outside of the admin panel, make sure you have
@ryangjchandler/alpine-tooltipinstalled in your app.
Customizing the text that is copied to the clipboard
You can customize the text that gets copied to the clipboard using the `copyableState() method:
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('name')
->copyable()
->copyableState(fn (string $state): string => "Name: {$state}")In this function, you can access the whole table row with $record:
use App\Models\User;
use Filament\Tables\Columns\BadgeColumn;
BadgeColumn::make('name')
->copyable()
->copyableState(fn (User $record): string => "Name: {$record->name}")File: docs/03-columns/06-tags.md
title: 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 Post extends Model
{
protected $casts = [
'tags' => 'array',
];
// ...
}Using a separator
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(',')File: docs/03-columns/07-color.md
title: Color column
The color column allows you to show the color preview from a CSS color definition, typically entered using the color picker field, in one of the supported formats (HEX, HSL, RGB, RGBA).
use Filament\Tables\Columns\ColorColumn;
ColorColumn::make('color')Allowing the color to be copied to the clipboard
You may make the color copyable, such that clicking on the preview copies the CSS value to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
use Filament\Tables\Columns\ColorColumn;
ColorColumn::make('color')
->copyable()
->copyMessage('Color code copied')
->copyMessageDuration(1500)Customizing the text that is copied to the clipboard
You can customize the text that gets copied to the clipboard using the `copyableState() method:
use Filament\Tables\Columns\ColorColumn;
ColorColumn::make('color')
->copyable()
->copyableState(fn (string $state): string => "Color: {$state}")In this function, you can access the whole table row with $record:
use App\Models\Post;
use Filament\Tables\Columns\ColorColumn;
ColorColumn::make('color')
->copyable()
->copyableState(fn (Post $record): string => "Color: {$record->color}")File: docs/03-columns/08-select.md
title: Select column
The select column allows you to render a select field inside the table, which can be used to update that database record without needing to open a new page or a modal.
You must pass options to the column:
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])Validation
You can validate the input by passing any Laravel validation rules in an array:
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->rules(['required'])Disabling placeholder selection
You can prevent the placeholder from being selected using the disablePlaceholderSelection() method:
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->disablePlaceholderSelection()File: docs/03-columns/09-toggle.md
title: Toggle column
The toggle column allows you to render a toggle button inside the table, which can be used to update that database record without needing to open a new page or a modal:
use Filament\Tables\Columns\ToggleColumn;
ToggleColumn::make('is_admin')