Choice Column
Map finite value sets (enums, statuses) to human-readable labels with optional badge rendering
The ChoiceColumn maps a field’s raw value to a human-readable label. It optionally renders the label as a colored badge with a per-value semantic variant. PHP 8.1 BackedEnum classes are supported natively.
Badge markup is produced by a frontend column style adapter: Bootstrap 5 classes when a Bootstrap DataTables stylesheet is detected, Tailwind utilities otherwise (including the default dt theme).
Basic Usage
use Pentiminax\UX\DataTables\Column\ChoiceColumn;
ChoiceColumn::new('status', 'Status')
->setChoices([
'active' => 'Active',
'inactive' => 'Inactive',
'pending' => 'Pending',
]);
Using a BackedEnum
Pass a BackedEnum class directly, or pass ::cases(). The mapping is auto-generated from case->value => case->name.
enum Status: string
{
case Active = 'active';
case Inactive = 'inactive';
case Pending = 'pending';
}
ChoiceColumn::new('status', 'Status')
->setChoices(Status::cases());
// Generates: ['active' => 'Active', 'inactive' => 'Inactive', 'pending' => 'Pending']
Translating Labels
Cases of an enum that implements Symfony’s TranslatableInterface are translated when the table renders, in the locale of the current request. The ChoiceFilter does the same, so the column and its filter stay in sync:
use Symfony\Contracts\Translation\TranslatableInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
enum Status: string implements TranslatableInterface
{
case Active = 'active';
case Inactive = 'inactive';
public function trans(TranslatorInterface $translator, ?string $locale = null): string
{
return $translator->trans('status.'.$this->value, [], null, $locale);
}
}
ChoiceColumn::new('status', 'Status')
->setChoices(Status::class);
Rendering as Badges
Use renderAsBadges() to wrap each label in a badge. Map individual values to semantic color variants (success, danger, warning, info, primary, secondary, light, dark), and provide a fallback for unmapped values.
ChoiceColumn::new('status', 'Status')
->setChoices(Status::cases())
->renderAsBadges(
badgeSelector: [
'active' => 'success',
'inactive' => 'danger',
'pending' => 'warning',
],
defaultVariant: 'secondary',
);
The same PHP configuration works with Bootstrap 5 and Tailwind — only the generated HTML classes change based on the detected DataTables CSS framework.
Default Badge Variant
When renderAsBadges() is called without a badgeSelector map (or for values not present in the map), the defaultVariant is used. It defaults to 'secondary'.
ChoiceColumn::new('category', 'Category')
->setChoices(['foo' => 'Foo', 'bar' => 'Bar'])
->renderAsBadges(); // all values use 'secondary' variant
API Reference
| Method | Description |
|---|---|
ChoiceColumn::new(string $name, string $title = '') | Creates a new ChoiceColumn (type: html) |
setChoices(array|string $choices) | Accepts a value => label array, a BackedEnum class-string, or a BackedEnum::cases() list |
renderAsBadges(array|bool $badgeSelector = [], string $defaultVariant = 'secondary') | Enables badge rendering with per-value semantic color variants |
Complete Example
use Pentiminax\UX\DataTables\Attribute\AsDataTable;
use Pentiminax\UX\DataTables\Column\ChoiceColumn;
use Pentiminax\UX\DataTables\Column\NumberColumn;
use Pentiminax\UX\DataTables\Column\TextColumn;
use Pentiminax\UX\DataTables\Model\AbstractDataTable;
enum OrderStatus: string
{
case Draft = 'draft';
case Confirmed = 'confirmed';
case Shipped = 'shipped';
case Cancelled = 'cancelled';
}
#[AsDataTable(Order::class)]
final class OrdersDataTable extends AbstractDataTable
{
public function configureColumns(): iterable
{
yield NumberColumn::new('id', 'ID');
yield TextColumn::new('reference', 'Reference');
yield ChoiceColumn::new('status', 'Status')
->setChoices(OrderStatus::class)
->renderAsBadges([
'draft' => 'secondary',
'confirmed' => 'primary',
'shipped' => 'success',
'cancelled' => 'danger',
]);
}
protected function mapRow(mixed $row): array
{
return [
'id' => $row->getId(),
'reference' => $row->getReference(),
'status' => $row->getStatus()->value,
];
}
}