Text Version of the Lesson
Filament Table Builder has dozens of ways how to customize column values. In this lesson, I will touch on the most commonly used ones.
Show as Tags/Badges
Filament has a general concept of a "Badge", I personally call it a "Tag", which is just a visual representation of a text/number surrounded by a border.
Let's take a look at it by just adding ->badge() to two columns in our Products table: status and tags.
return $table ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('price'), Tables\Columns\TextColumn::make('status') ->badge(), Tables\Columns\TextColumn::make('category.name'), Tables\Columns\TextColumn::make('tags.name') ->badge(), ])
Here's the visual result:

As you can see, Filament automatically wraps the text as a "badge". Not only does it work for a simple TextColumn, but also, in the case of the belongsToMany relationship, it shows multiple badges instead of a comma-separated text.
You can also specify different colors for different badge values. In our case, we use Enum class, so we can do it directly in the Enum:
app/Enums/ProductStatusEnum.php:
use Filament\Support\Contracts\HasLabel;use Filament\Support\Contracts\HasColor; enum ProductStatusEnum: string implements HasLabel enum ProductStatusEnum: string implements HasLabel, HasColor { case IN_STOCK = 'In Stock'; case SOLD_OUT = 'Sold Out'; case COMING_SOON = 'Coming Soon'; public function getLabel(): ?string { return $this->value; } public function getColor(): ?string { return match ($this) { self::IN_STOCK => 'primary', self::SOLD_OUT => 'danger', self::COMING_SOON => 'info', }; } }
Here's how it looks now:

You can choose the colors from these...
Hello Povilas, first I would like to thank you for this amazing content. I've followed part of this course, and I've a little problem and you doesn't talk about that and probably you never tested it. I've a file upload at form like this: Forms\Components\FileUpload::make('avatarurl') ->image() ->disk('private') ->visibility('private') ->directory('profile-photos') ->maxSize(1024) ->imageResizeMode('cover') ->getUploadedFileNameForStorageUsing( fn(TemporaryUploadedFile $file): string => (string)str($file->getClientOriginalName()) ->prepend('profile-'), ),
And at table I've this: Tables\Columns\ImageColumn::make('avatarurl')->circular() ->disk('private') ->visibility('private'),
and the final result is I can't show the image on the table. If I've the visibility 'public' everything is ok. Can you help me? Thank You!
Hi Pedro. Well, to me it's pretty obvious, if you want the file to be PRIVATE, it means you're HIDING it from everyone, including the Filament table. What are you actually trying to achieve here? Why private?
For now i was testing with images, but in the future it can be private documents for example. And filament documentation talks about this "Filament can generate temporary URLs to render private images, you may set the visibility() to private" (https://filamentphp.com/docs/3.x/tables/columns/image#managing-the-image-disk).
Another example is, is case of images they are inside a panel, if I've the image url and I'am not logged in, it doesn't make sense to be able to access the image. What is your opinion?
Well it's still a weird scenario to me, personally. I understand that Filament may allow it, but as you can see it doesn't work properly, for some reason, I haven't debugged it, personally.
I probably need to schedule some time on a proper tutorial about private/public file uploads in Filament, it's a deep topic with many use cases. Adding to the (already huge) to-do list.
I was going to search at github filament pull request, some people have this problems with S3.
When I add the URL for the category, and I click the link, show error: Missing required parameter for [Route: filament.admin.resources.categories.edit] [URI: admin/categories/{record}/edit] [Missing parameter: record].
@Zhtekdev I initially got it too, but you can see a note saying: "In our project, we don't have the page for Category Edit, as we generated that resource as --simple, so this was just an illustrative example." That's why you get the error.