Anna
May 4, 2025, 2:51pm
1
I am using Filament admin panel in Laravel. Filament v3.3.14, Laravel 12x
I have found this great little function to alternate my icons depending on the value (0 or 1).
Tables\Columns\IconColumn::make('paid')
->icon(fn (string $state): string => match ($state) {
'1' => 'heroicon-o-check-circle',
'0' => 'heroicon-o-x-circle',
})
I would like to use it on a different function with text values as below:
Tables\Columns\IconColumn::make('test_value')
->icon(fn (string $state): string => match ($state) {
'high' => 'heroicon-o-check-circle',
'medium' => 'heroicon-o-x-circle',
'low' => 'heroicon-o-x-circle',
'extreme' => 'heroicon-o-x-circle',
})
But the test_value will often end up with values like “Medium (12)” or “Extreme (25)”.
Is there a way to loosen up the string match? Similar to a LIKE or CONTAINS?
I cannot locate any direction out in the wide yonder internet. Would greatly appreciate if you have any suggestions.
Yes, you’re on the right track — but match()
in PHP is strict and doesn’t support partial matches like contains
, LIKE
, or regex. Since your values like "Medium (12)"
or "Extreme (25)"
are variable but follow a pattern, you’ll want to use str_contains()
or str_starts_with()
in your closure instead of match()
.
Solution: Use str_contains()
Instead of match()
use Filament\Tables\Columns\IconColumn;
use Illuminate\Support\Str; // Optional if using Laravel helpers
IconColumn::make('test_value')
->icon(function (string $state): string {
$lowerState = strtolower($state);
if (str_contains($lowerState, 'high')) {
return 'heroicon-o-check-circle';
} elseif (str_contains($lowerState, 'medium')) {
return 'heroicon-o-x-circle';
} elseif (str_contains($lowerState, 'low')) {
return 'heroicon-o-x-circle';
} elseif (str_contains($lowerState, 'extreme')) {
return 'heroicon-o-x-circle';
}
return 'heroicon-o-question-mark-circle'; // fallback icon
})
Why This Works
str_contains()
is case-sensitive by default, but you can normalize with strtolower()
or use Laravel’s Str::contains()
which is case-insensitive.
This is more flexible than match()
when working with dynamic or partial strings like "Medium (12)"
.
Bonus: Case-Insensitive Version with Laravel’s Str
Helper
use Illuminate\Support\Str;
IconColumn::make('test_value')
->icon(fn (string $state): string => match (true) {
Str::contains($state, 'high') => 'heroicon-o-check-circle',
Str::contains($state, 'medium') => 'heroicon-o-x-circle',
Str::contains($state, 'low') => 'heroicon-o-x-circle',
Str::contains($state, 'extreme') => 'heroicon-o-x-circle',
default => 'heroicon-o-question-mark-circle',
})