Columns

Each column in a DataTable is represented by a Column class that configures rendering, sorting, searching, and export behavior.

Creating Columns

Use the static new() method on the column type:

use Pentiminax\UX\DataTables\Column\TextColumn;
use Pentiminax\UX\DataTables\Column\NumberColumn;
use Pentiminax\UX\DataTables\Column\BooleanColumn;

$nameColumn = TextColumn::new('firstName', 'First Name');
$ageColumn = NumberColumn::new('age', 'Age');
$activeColumn = BooleanColumn::new('active', 'Active');

The first argument is the data key (maps to your JSON/array key), and the second is the display title.

Column Types

TextColumn

For text content:

TextColumn::new('name', 'Name');

NumberColumn

For numeric values with proper sorting:

NumberColumn::new('price', 'Price');
NumberColumn::new('quantity', 'Qty');

DateColumn

For date values:

use Pentiminax\UX\DataTables\Column\DateColumn;

DateColumn::new('createdAt', 'Created');

BooleanColumn

For boolean values (true/false, 1/0) rendered as Bootstrap switches:

use Pentiminax\UX\DataTables\Column\BooleanColumn;

BooleanColumn::new('active', 'Status')

The switch sends an AJAX request with entity, id, field, and value to update the boolean property.

If your table uses #[AsDataTable(Entity::class)], entity is injected automatically into the BooleanColumn. Otherwise, you can set it manually:

BooleanColumn::new('active')
    ->setToggleEntityClass(App\Entity\User::class);

Add this route import in your Symfony project:

// config/routes/ux_datatables.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return static function (RoutingConfigurator $routes): void {
    $routes->import('@DataTablesBundle/config/routes.php');
};

Configuration Methods

All columns inherit these methods from AbstractColumn:

Display Options

$column = TextColumn::new('name', 'Name')
    ->setTitle('Full Name')           // Change header title
    ->setClassName('text-primary')    // CSS class for cells
    ->setWidth('200px')               // Column width
    ->setVisible(true)                // Show/hide column
    ->setDefaultContent('N/A');       // Fallback for null values

Data Options

$column = TextColumn::new('user', 'User')
    ->setData('user.name');  // Nested data path

Sorting & Searching

$column = TextColumn::new('name', 'Name')
    ->setOrderable(true)      // Enable sorting
    ->setSearchable(true);    // Enable searching

Cell Type

$column = TextColumn::new('header', 'Header')
    ->setCellType('th');  // Use <th> instead of <td>

Custom Rendering

Define a JavaScript render function:

$column = TextColumn::new('email', 'Email')
    ->setRender('function(data, type, row) {
        return "<a href=\"mailto:" + data + "\">" + data + "</a>";
    }');

TemplateColumn (Twig)

Use TemplateColumn when you want to render server-side HTML with Twig:

use Pentiminax\UX\DataTables\Column\TemplateColumn;

TemplateColumn::new('status_display', 'Status')
    ->setField('status')
    ->setTemplate('datatable/columns/user_status.html.twig');

Template context:

  • entity: the mapped row/entity object
  • data: the resolved field value
  • column: serialized column configuration
  • row: the original row array

Example template:

{# templates/datatable/columns/user_status.html.twig #}
<span class="badge bg-{{ value == 'active' ? 'success' : 'danger' }}">
    {{ value|capitalize }}
</span>

TemplateColumn works with both server-side responses and client-side inline data (->data([...])).

Export Control

$column = TextColumn::new('actions', 'Actions')
    ->setExportable(false);  // Exclude from exports

Non-exportable columns automatically receive the not-exportable CSS class.

Edit Form Control

Exclude a column from the inline edit modal:

$column = TextColumn::new('createdAt', 'Created')
    ->hideWhenUpdating();  // Not shown in edit form

Complete Example

use Pentiminax\UX\DataTables\Builder\DataTableBuilderInterface;
use Pentiminax\UX\DataTables\Column\NumberColumn;
use Pentiminax\UX\DataTables\Column\TextColumn;

class ProductTableService
{
    public function __construct(
        private DataTableBuilderInterface $builder,
    ) {}

    public function createTable(): DataTable
    {
        $idColumn = NumberColumn::new('id', 'ID')
            ->setWidth('60px')
            ->setClassName('text-center');

        $nameColumn = TextColumn::new('name', 'Product Name')
            ->setClassName('fw-bold')
            ->setOrderable(true)
            ->setSearchable(true);

        $priceColumn = NumberColumn::new('price', 'Price')
            ->setWidth('100px')
            ->setOrderable(true)
            ->setRender('function(data) {
                return "$" + data.toFixed(2);
            }');

        $statusColumn = TextColumn::new('status', 'Status')
            ->setWidth('100px')
            ->setRender('function(data) {
                var badge = data === "active" ? "success" : "secondary";
                return "<span class=\"badge bg-" + badge + "\">" + data + "</span>";
            }');

        return $this->builder
            ->createDataTable('products')
            ->columns([$idColumn, $nameColumn, $priceColumn, $statusColumn]);
    }
}

Translating Column Titles

When using AbstractDataTable, the Symfony translator is available:

use Pentiminax\UX\DataTables\Column\TextColumn;
use Pentiminax\UX\DataTables\Model\AbstractDataTable;

final class UsersDataTable extends AbstractDataTable
{
    public function configureColumns(): iterable
    {
        yield TextColumn::new('name')
            ->setTitle($this->translator->trans('datatable.columns.name'));

        yield TextColumn::new('email')
            ->setTitle($this->translator->trans('datatable.columns.email'));
    }
}

Column Type Enum

The ColumnType enum controls DataTables’ internal sorting and search algorithms:

Type Description
DATEDate values
HTMLHTML content
HTML_NUMNumeric values extracted from HTML content
HTML_NUM_FMTFormatted numeric values extracted from HTML content
HTML_UTF8HTML content with UTF-8 aware text sorting
NUMNumeric values (also used by BooleanColumn for sorting)
NUM_FMTFormatted numbers ($1,000)
STRINGText content (default)
STRING_UTF8UTF-8 aware text sorting

Serialization

Get the DataTables configuration array:

$config = $column->jsonSerialize();
// Returns: ['data' => 'name', 'title' => 'Name', 'orderable' => true, ...]