How to set badge color from relation

How to set badge color from relation many to many
No description
No description
19 Replies
karimakrane
karimakrane5mo ago
Tables\Columns\TextColumn::make('schools.commercial_name')
->label('Schools')
->badge()
->color(function (?Model $record) {
$schools = $record->schools;
logger()->info('Current School ID: ' . $record->current_school_id);
logger()->info('All School IDs: ' . $schools->pluck('id')->implode(','));
return $schools->contains($record->currentSchool) ? 'success' : 'primary';
})
Tables\Columns\TextColumn::make('schools.commercial_name')
->label('Schools')
->badge()
->color(function (?Model $record) {
$schools = $record->schools;
logger()->info('Current School ID: ' . $record->current_school_id);
logger()->info('All School IDs: ' . $schools->pluck('id')->implode(','));
return $schools->contains($record->currentSchool) ? 'success' : 'primary';
})
` always return success
justlasse
justlasse5mo ago
What does dd($schools->contains(…)) give you? Perhaps the logic isn’t returning what you expect?
karimakrane
karimakrane5mo ago
@justlasse return true
public function currentSchool(): BelongsTo
{
return $this->belongsTo(School::class, 'current_school_id');
}
public function currentSchool(): BelongsTo
{
return $this->belongsTo(School::class, 'current_school_id');
}
i need that the badge of the current school be success else primary
justlasse
justlasse5mo ago
If it returns true then the code is working correctly. But if you expect it to return false then something else is wrong Try to manually manipulate the data so that the statement returns false for the contains and see if that works
karimakrane
karimakrane5mo ago
@justlasse I think it applies the first return on all elements not element by element
No description
justlasse
justlasse5mo ago
Ah you have multiple badges yes then i believe it’s a different approach
karimakrane
karimakrane5mo ago
how can i do that ??
justlasse
justlasse5mo ago
I think you need a different type of column Since the textcolumn assumes 1 value
karimakrane
karimakrane5mo ago
ok I will think of another approach perhaps with ->state() thanks
justlasse
justlasse5mo ago
You could use the badge component in a custom column perhaps?
@if ($isBadge)
<x-filament::badge
:color="$color"
:icon="$icon"
:icon-position="$iconPosition"
>
{{ $formattedState }}
</x-filament::badge>
@else
@if ($isBadge)
<x-filament::badge
:color="$color"
:icon="$icon"
:icon-position="$iconPosition"
>
{{ $formattedState }}
</x-filament::badge>
@else
Here is the problem that you're up against in the textcolumn.... You can inject $state in the color function that returns the current badge "school" in your instance So perhaps if you format the state and use commercial_name, but use the actual schools relation in the make, you'd have access to the current school object
justlasse
justlasse5mo ago
No description
justlasse
justlasse5mo ago
This actually worked in the textcolumn, no custom column needed
TextColumn::make('authoredStories')->badge()->formatStateUsing(fn($state) => $state->name)->color(fn(User $record, $state) => $state->completed ? 'success': 'primary'),
TextColumn::make('authoredStories')->badge()->formatStateUsing(fn($state) => $state->name)->color(fn(User $record, $state) => $state->completed ? 'success': 'primary'),
karimakrane
karimakrane5mo ago
@justlasse thanks a lot it's work
Tables\Columns\TextColumn::make('schools')
->badge()
->formatStateUsing(fn($state) => $state->commercial_name)
->color(fn(User $record, $state) => ($state->id == $record->current_school_id) ? 'success': 'primary')
->separator(',')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('schools')
->badge()
->formatStateUsing(fn($state) => $state->commercial_name)
->color(fn(User $record, $state) => ($state->id == $record->current_school_id) ? 'success': 'primary')
->separator(',')
->sortable()
->searchable(),
justlasse
justlasse5mo ago
NICE! If you want more colors you can just make it a match statement to return multiple results and a default.
justlasse
justlasse5mo ago
No description
justlasse
justlasse5mo ago
->icon(fn($state) => match($state->status){
StoryStatusEnum::Accepted => 'heroicon-s-heart',
StoryStatusEnum::Completed => 'heroicon-m-fire',
StoryStatusEnum::FactReview, StoryStatusEnum::AccuracyReview => 'heroicon-m-chat-bubble-bottom-center',
default => 'heroicon-s-currency-dollar'
})
->icon(fn($state) => match($state->status){
StoryStatusEnum::Accepted => 'heroicon-s-heart',
StoryStatusEnum::Completed => 'heroicon-m-fire',
StoryStatusEnum::FactReview, StoryStatusEnum::AccuracyReview => 'heroicon-m-chat-bubble-bottom-center',
default => 'heroicon-s-currency-dollar'
})
for example You can inject a model in my instance Story to the function, but you have to call it $state or it doesn't seem to work.
->icon(fn(Story $state) => match($state->status){
StoryStatusEnum::Accepted => 'heroicon-s-heart',
StoryStatusEnum::Completed => 'heroicon-m-fire',
StoryStatusEnum::FactReview, StoryStatusEnum::AccuracyReview => 'heroicon-m-chat-bubble-bottom-center',
default => 'heroicon-s-currency-dollar'
})
->icon(fn(Story $state) => match($state->status){
StoryStatusEnum::Accepted => 'heroicon-s-heart',
StoryStatusEnum::Completed => 'heroicon-m-fire',
StoryStatusEnum::FactReview, StoryStatusEnum::AccuracyReview => 'heroicon-m-chat-bubble-bottom-center',
default => 'heroicon-s-currency-dollar'
})
justlasse
justlasse5mo ago
Even better! Thanks for adding that
karimakrane
karimakrane5mo ago
done thank you