survos/simple-datatables-bundle
Symfony bundle that integrates the lightweight simple-datatables JavaScript library, helping you render sortable, searchable, paginated HTML tables with minimal configuration. Provides Twig helpers and asset integration for quick table setup.
Reality check first: this is a Symfony bundle (uses Symfony bundles, Twig components, Stimulus controllers, and ImportMap/AssetMapper). It will not install or run as-is in a Laravel app. If you are committed to Laravel, treat this repository as a reference implementation for integrating the vanilla simple-datatables JS library through a Stimulus controller — you would port roughly the controller + Twig template + PHP Column DTO into a Blade/Alpine/Livewire equivalent. If you just need a datatable in Laravel, use yajra/laravel-datatables or Filament tables and skip this.
Assuming you are standing up (or auditing) a Symfony app that consumes it:
README.md top-to-bottom before installing — it contains the current migration guide and the canonical option names. Do not trust older blog posts.composer require survos/simple-datatables-bundle.config/bundles.php (Survos\SimpleDatatablesBundle\SimpleDatatablesBundle::class => ['all' => true]).The registered Stimulus controller identifier is survos--simple-datatables-bundle--table. Anything you write in HTML should match that exactly; legacy identifiers are still supported but new code should use the current one.
Render table markup server-side, enhance client-side. You do not fetch rows from an endpoint. Twig renders <thead>/<tbody> rows, then the Stimulus controller boots simple-datatables over the existing <table> element. This is the opposite of api-grid-bundle's API Platform flow — if you need facets, API pagination, or server-side filtering, you are in the wrong bundle; look at survos/grid-bundle / survos/api-grid-bundle.
Column definitions as PHP objects. Build a list of Column value objects (label, sortable, renderer/callback, class) and pass them into the Twig component. This keeps column config out of template strings and lets you unit-test column behavior. Custom cell rendering (badges, links, formatted dates) is done via the column renderer, not by hand-writing <td> HTML in Twig.
Wrap, don't mount on the table. Mount the Stimulus controller on a stable wrapper element (a <div> or <section> around the table), not on the <table> itself. DataTables reparents and rewrites the <table> node; a controller attached to that node can lose its element on re-render. The AGENTS notes call this out explicitly for the Grid migration path, and the same rule applies here.
Turbo-aware reconnect. If the app uses Turbo, the controller must handle turbo:load / reconnect. On a Turbo navigation the DOM is replaced without a full page load, and a naive controller that only fires on initial connect will leave a stale or duplicate DataTable behind.
Options you pass are DataTable options. pageLength (the new name), searchable, sortable, perPage (legacy — avoid in new code), and any option supported by simple-datatables itself. Do not invent options; the bundle mostly forwards them.
CSS is controller-local. Keep styles scoped to the component; do not add a global DataTables CSS import. The bundle deliberately avoids auto-importing global CSS so multiple table styles (or non-DataTable tables) don't collide.
When API Grid is already present, prefer it. If the app already depends on survos/api-grid-bundle, adding this bundle just to get a small table creates two parallel DataTables setups. The guidance is: reuse Grid for in-memory tables when API Grid is already in the dependency graph; only add simple-datatables to apps that don't already pull in the heavier stack.
Migration pattern (if you are moving off or onto this). Inventory actual usage first: Twig component calls, direct Stimulus mounts (the identifier above), PHP Column objects, custom CSS, and event handlers. Rename perPage → pageLength, remove backend (it no longer exists), and verify every nonstandard option still exists in the target. Migrate one page at a time and keep row links, custom Twig blocks, translation, and scrolling behavior intact.
<table> so DataTables’ DOM surgery detaches your Stimulus element. Wrap the table and mount there.perPage → pageLength. If pagination silently shows the default page size, you are passing the old option name. Same for the removed backend flag — passing it is a no-op or throws depending on version.simple-datatables JS/CSS actually loaded and how large they are. AGENTS explicitly calls out that pin counts don’t measure page weight.<tbody>, a single row, a row with a broken custom cell, links inside cells (must be clickable, not swallowed by DataTables’ row click), and localized column headers.composer why before deleting. If you are removing this bundle or pentiminax from a project, check transitive requirements first. Another backend (or another Survos bundle) may still require the asset package even if this bundle is gone.vendor/. For local development the Survos convention is: install the public package from Packagist/Satis as normal, then run the monorepo link script. A working linked build does not prove the published release is installable — verify against a clean composer install in a fresh checkout.survos--simple-datatables-bundle--table; older README snippets and legacy users may still reference a previous name. If your controller never fires, print document.querySelector('[data-controller]') and compare the data-controller attribute to the identifier the bundle actually registers.api-grid-bundle. This bundle is intentionally the light, in-memory option; forcing it into a server-paginated flow means duplicating what Grid already provides.simple-datatables in an Alpine or Stimulus controller attached to a stable wrapper, (3) keep a "column definition" PHP array/DTO for renderers, (4) scope CSS to the component, (5) test Livewire/Turbo-style re-renders for stale table instances. The Symfony-specific glue (bundle registration, Twig components, ImportMap pins) does not transfer.How can I help you explore Laravel packages today?