CheckBoxList, Enums and TextColumn display conundrum

Salut Interesting little problem. I have a Checkbox list on the form that is populated with an Enum. This all fine and works as expected - the labels are displayed and the values are stored correctly:
CheckboxList::make('type')
->label('Type')
->options(OrganisationTypes::class)
->columns(2)
->required(),
CheckboxList::make('type')
->label('Type')
->options(OrganisationTypes::class)
->columns(2)
->required(),
On the table I want to display the the selected values
TextColumn::make('type'),
TextColumn::make('type'),
Which is where the problem arises - the column displays the stored value and not the label. Because this is a multi-value field , stored as JSON in the model I need to cast it to type => 'array' If this were a simple/single value field (e.g CheckBox or Select) then I could cast it to the enum type => OrganisationTypes::class and the correct label would be displayed in the table column. So how do I cast the field to an array and still have the Enum return the correct labels in the table column? Thanks for reading this far! My enum for reference
enum OrganisationTypes: string implements HasLabel
{
case CUSTOMER = 'customer';
case SUPPLIER = 'supplier';
case MANUFACTURER = 'manufacturer';
case WAREHOUSE = 'warehouse';
case LOGISTICS = 'logictics';

public function getLabel(): ?string
{
return match ($this) {
self::CUSTOMER => 'Customer',
self::SUPPLIER => 'Supplier',
self::MANUFACTURER => 'Manufacturer',
self::WAREHOUSE => 'Warehouse',
self::LOGISTICS => 'Logistics',
default => '',
};
}
}
enum OrganisationTypes: string implements HasLabel
{
case CUSTOMER = 'customer';
case SUPPLIER = 'supplier';
case MANUFACTURER = 'manufacturer';
case WAREHOUSE = 'warehouse';
case LOGISTICS = 'logictics';

public function getLabel(): ?string
{
return match ($this) {
self::CUSTOMER => 'Customer',
self::SUPPLIER => 'Supplier',
self::MANUFACTURER => 'Manufacturer',
self::WAREHOUSE => 'Warehouse',
self::LOGISTICS => 'Logistics',
default => '',
};
}
}
4 Replies
Solution
Tieme
Tieme4mo ago
Try https://filamentphp.com/docs/3.x/forms/advanced#field-hydration Something like below should work. not tested code
->formatStateUsing(function (string $state){
$Labels = [];
foreach($state as $EnumValue){
$Labels[] = OrganisationTypes::from($EnumValue)->getLabel()
}
return implode(',',$Labels);
})
->formatStateUsing(function (string $state){
$Labels = [];
foreach($state as $EnumValue){
$Labels[] = OrganisationTypes::from($EnumValue)->getLabel()
}
return implode(',',$Labels);
})
Blackpig
Blackpig4mo ago
Yes, thank you that does the trick nicely. I was hoping that Filament would handle it automagically. For reference this is the solution
TextColumn::make('type')
->formatStateUsing(function (string $state){
$labels = [];
foreach(explode(',', $state) as $enumValue) {
$labels[] = OrganisationTypes::from(trim($enumValue))->getLabel();
}
return implode(', ',$labels);
}),
TextColumn::make('type')
->formatStateUsing(function (string $state){
$labels = [];
foreach(explode(',', $state) as $enumValue) {
$labels[] = OrganisationTypes::from(trim($enumValue))->getLabel();
}
return implode(', ',$labels);
}),
@Tieme karma++
Tieme
Tieme4mo ago
Filament will only do that if the cast is Enum. Can you mark the solution, (see first comment on this thread)
Blackpig
Blackpig4mo ago
Which is where the 'conflict' arose with having to cast to an array. But the solution is good