phil / data-table-bundle
Data tables for Symfony as a Live Component: sorting, filters, pagination, row and bulk actions, inline editing, a stacked list on narrow screens, and the same state in the address for a link, a reload or a browser without JavaScript
Package info
github.com/parler-haut-interagir-librement/data-table-bundle
Type:symfony-bundle
pkg:composer/phil/data-table-bundle
Requires
- php: >=8.5
- ext-intl: *
- ext-mbstring: *
- psr/container: ^2.0
- psr/log: ^3.0
- symfony/config: ^8.2
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
- symfony/http-kernel: ^8.2
- symfony/property-access: ^8.2
- symfony/routing: ^8.2
- symfony/security-csrf: ^8.2
- symfony/translation: ^8.2
- symfony/translation-contracts: ^3.6
- symfony/ux-live-component: ^3.7
- symfony/ux-twig-component: ^3.7
- symfony/validator: ^8.2
- twig/twig: ^3.30
Requires (Dev)
- ext-dom: *
- doctrine/dbal: ^4.5
- doctrine/orm: ^3.7
- phil/data-table-export: ^0.1@dev
- phil/settings-bundle: ^0.1@dev
- phil/ux-kit: >=0.5.0-alpha <1.0
- php-webdriver/webdriver: ^1.16
- phpunit/phpunit: ^13.4
- symfony/asset-mapper: ^8.2
- symfony/browser-kit: ^8.2
- symfony/cache: ^8.2
- symfony/clock: ^8.2
- symfony/css-selector: ^8.2
- symfony/dom-crawler: ^8.1
- symfony/event-dispatcher: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/panther: ^2.4
- symfony/security-core: ^8.2
- symfony/stimulus-bundle: ^3.7
- symfony/twig-bundle: ^8.2
- symfony/yaml: ^8.2
Suggests
- doctrine/orm: For DoctrineDataSource, a table read from a QueryBuilder
- phil/data-table-export: For the export of a table, filtered and sorted, as CSV or XLSX
- phil/settings-bundle: For the column visibility and the page size each user chooses, kept among their settings
- phil/ux-kit: For the Button recipe the templates draw, and the tokens the stylesheet reads, through the Symfony UX Toolkit
- symfony/asset-mapper: For the stylesheet and the Stimulus controller without a build step
- symfony/security-core: For the voter attributes of the actions and of the editable columns
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-15 03:41:19 UTC
README
Data tables that sort, filter, page, act and edit in place, with or without JavaScript.
phil/data-table-bundle draws a table of records as a Symfony UX Live Component. A table is declared in PHP: its columns, filters, actions, default sort and page sizes. It offers sorting, text, enum, date range and boolean filters, pagination, actions on a row or on a selection, and editing a cell in place. On a narrow screen its rows become a stacked list.
It is for a back office or a catalogue page that lists records and lets people work on them. Reach for it when the
table's state must survive a link or a reload, and when the changes must be checked on the server every time. It is not
a client-side grid. With phil/data-table-export, a table exports its filtered and sorted rows as CSV or XLSX.
The state of a table is in the address, so a link, a reload or a browser without JavaScript shows the same table. Every
control is a plain link or a plain form that the component takes over when it can. Rows come from the DataSource port,
with an in-memory adapter and a Doctrine QueryBuilder adapter. Sort and filter fields only come from what the table
declares. Actions and edits ask a voter attribute at every call and pass a stateless CSRF check.
The bundle builds on Symfony UX Live Component, Twig Component, Validator and CSRF. Its buttons are the Button recipe of
the PHIL UX kit — or of the Shadcn kit —, installed in the application by the Symfony UX Toolkit. Doctrine ORM, Symfony
Security, AssetMapper, phil/settings-bundle and phil/data-table-export are optional, and each is used when it is
installed. The stylesheet reads the tokens of PHIL UX and has values of its own without it.
Status
| Part | State |
|---|---|
Declaring a table: TableBuilder, Column, Filter, Action, Editing |
Implemented and tested |
Block cells through the application's cell themes, by Twig\BlockChain |
Implemented and tested |
DataSource, InMemoryDataSource, DoctrineDataSource |
Implemented and tested |
| The state checked against the declaration, the links of each state | Implemented and tested |
The component PhilDataTable:Table, its templates, stylesheet and Stimulus controller |
Implemented and tested |
| Row and bulk actions, inline editing, the routes of plain forms | Implemented and tested |
Column visibility and page size per user: TablePreferences, SettingsTablePreferences, a refusal logged |
Implemented and tested |
The question of an action in a native <dialog>, shown in the page without JavaScript |
Implemented and tested |
| A notice when the row being edited leaves the page | Implemented and tested |
| The buttons drawn with the Button recipe of the kit | Implemented and tested |
The export as CSV or XLSX, with phil/data-table-export |
Implemented and tested |
| The browser suite: filters, columns, focus and the dialog in Chrome | Implemented and tested |
| The Flex recipe: the bundle, its configuration and its routes | Written in recipe/0.1, for the recipes repository of PHIL |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, registering, the recipe, routes, assets, configuration. |
| Tables | Declaring columns, filters, sorts and page sizes; the component. |
| Data sources | The port, the adapters, paging and its bounds. |
| Actions and editing | Row and bulk actions, inline editing, what is checked and when. |
| Export | The export of a table as CSV or XLSX, its route, its checks and its limits. |
| State in the address | The parameters, several tables on a page, the fallback without JavaScript. |
| Accessibility | What the markup says, the keyboard, the stacked list. |
| Extension points | What an application implements, configures, replaces or relies on. |
| Testing | How the bundle is tested. |
| Reference | Every type of the bundle. |
Quick start
composer require phil/data-table-bundle
final readonly class BooksTable implements DataTable { public function __construct(private EntityManagerInterface $entities) { } public static function name(): string { return 'books'; } public function configure(TableBuilder $table): void { $table->caption('books.caption') ->column(Column::text('title', 'books.title')->sortable()) ->column(Column::date('published', 'books.published')->sortable()) ->filter(Filter::text('q', 'books.search', ['title'])) ->sortBy('title'); } public function source(array $context): DataSource { return new DoctrineDataSource( $this->entities->createQueryBuilder()->select('b')->from(Book::class, 'b'), ['id' => 'b.id', 'title' => 'b.title', 'published' => 'b.published'], ); } }
<twig:PhilDataTable:Table name="books" />
Requirements
PHP 8.5 or later with ext-intl and ext-mbstring; Symfony 8.2's config, dependency injection, HTTP foundation, HTTP
kernel, property access, routing, CSRF, translation and validator; Symfony UX Live Component and Twig Component 3.7; Twig
3.29; the Button recipe of the PHIL UX kit, or of the Shadcn kit. Doctrine ORM, Symfony Security, AssetMapper,
phil/settings-bundle and phil/data-table-export are optional.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.