debricked/datatablesbundle
Symfony bundle that integrates jQuery DataTables with Doctrine, providing server-side processing, configurable columns/filters/sorting, and reusable datatable definitions. Includes v1.0 documentation and examples to quickly add data grids to your app.
Installation:
composer require debricked/datatablesbundle
Enable the bundle in config/bundles.php:
return [
// ...
Debricked\DatatablesBundle\DatatablesBundle::class => ['all' => true],
];
Basic Twig Usage:
Include the bundle’s assets in your webpack.config.js (if using Webpack Encore):
Encore
.addEntry('datatables', './vendor/debricked/datatablesbundle/Resources/public/js/datatables.js')
.enableSassLoader()
.copyFiles({
from: './vendor/debricked/datatablesbundle/Resources/public/css',
to: 'css/[name].css'
});
Then, in your Twig template:
{{ encore_entry_link_tags('datatables') }}
First Controller Integration: Create a controller method to return JSON data for DataTables:
use Debricked\DatatablesBundle\DataTables\DataTables;
use Debricked\DatatablesBundle\DataTables\Column;
public function getData(Request $request)
{
$dataTables = new DataTables();
$dataTables->setDataSource($this->getUserRepository()->findAll());
$dataTables->addColumn(new Column('id', 'ID', 'id'));
$dataTables->addColumn(new Column('name', 'Name', 'name'));
return $dataTables->render();
}
Frontend Integration: Use the bundle’s Twig helpers to render the table:
{{ render_datatables_table({
'dataSource': path('app_datatables_data', {'controller': 'UserController'}),
'columns': [
{'data': 'id', 'title': 'ID'},
{'data': 'name', 'title': 'Name'}
]
}) }}
Dynamic Column Handling:
Use Column objects to define columns dynamically based on user roles or permissions:
$columns = [];
if ($user->hasRole('ADMIN')) {
$columns[] = new Column('created_at', 'Created At', 'created_at');
}
$dataTables->addColumns($columns);
Server-Side Processing: Leverage the bundle’s built-in server-side processing for large datasets:
$dataTables->setServerSide(true);
$dataTables->setDataSource(function() {
return $this->getUserRepository()->createQueryBuilder('u')
->getQuery()
->getResult();
});
Custom Actions:
Add action buttons (e.g., edit, delete) using the Action class:
use Debricked\DatatablesBundle\DataTables\Action;
$dataTables->addColumn(new Column('actions', 'Actions', 'actions', [
new Action('Edit', 'edit', ['id' => 'id']),
new Action('Delete', 'delete', ['id' => 'id'])
]));
Webpack Encore Integration:
Extend the bundle’s default assets in webpack.config.js:
Encore
.addEntry('custom_datatables', './assets/js/datatables.js')
.addDependency('datatables') // Ensure base bundle is loaded
.copyFiles({
from: './node_modules/datatables.net-dt/js',
to: 'js/[name].js'
});
Twig Extensions:
Override or extend Twig helpers in your bundle’s Resources/config/services.yaml:
services:
App\Twig\Extension\CustomDatatablesExtension:
tags: ['twig.extension']
Symfony Forms + DataTables:
Use the bundle’s FormColumn to bind DataTables columns to Symfony forms:
use Debricked\DatatablesBundle\DataTables\FormColumn;
$formColumn = new FormColumn('name', $this->createFormBuilder()->getForm());
$dataTables->addColumn($formColumn);
API-Driven Tables: For API-driven apps, return DataTables-compatible JSON from a separate route:
public function apiData(Request $request)
{
$dataTables = new DataTables();
$dataTables->setDataSource($this->getApiService()->fetchUsers());
return $dataTables->render();
}
Localization:
Override the bundle’s translations in config/packages/debricked_datatables.yaml:
debricked_datatables:
translations:
emptyTable: "No data available in {language}"
Event Listeners: Attach listeners to modify DataTables behavior globally:
// src/EventListener/DatatablesListener.php
public function onDatatablesBuild(DataTablesEvent $event) {
$event->getDataTables()->addColumn(new Column('custom', 'Custom', 'custom'));
}
Register in services.yaml:
services:
App\EventListener\DatatablesListener:
tags:
- { name: kernel.event_listener, event: debricked.datatables.build, method: onDatatablesBuild }
Webpack Encore Mismatch:
datatables entry is added after bootstrap in webpack.config.js:
Encore.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
.enableSassLoader()
.enableReactPreset()
.copyFiles({
from: './vendor/debricked/datatablesbundle/Resources/public',
to: 'bundles/datatables/[path][name].[ext]'
});
Server-Side Processing Overhead:
DQL or query builder optimizations:
$qb = $this->getUserRepository()->createQueryBuilder('u');
$qb->select(['u.id', 'u.name']); // Only select needed columns
$dataTables->setDataSource($qb->getQuery()->getResult());
Column Naming Conflicts:
id or name may conflict with DataTables’ internal properties.$dataTables->addColumn(new Column('user_id', 'ID', 'id', ['alias' => 'user_id']));
Twig Cache Invalidation:
render_datatables_table) may not reflect due to caching.php bin/console cache:clear
Deprecated jQuery DataTables:
Encore.addEntry('datatables', [
'./node_modules/datatables.net/js/jquery.dataTables.js',
'./node_modules/datatables.net-dt/css/jquery.dataTables.css'
]);
Check Raw Data: Log the raw data source before rendering:
$data = $this->getUserRepository()->findAll();
\Log::debug('DataTables Data:', ['data' => $data]);
$dataTables->setDataSource($data);
Validate JSON Output: Use a tool like JSONLint to validate the bundle’s JSON response. Common issues:
draw, recordsTotal, or data keys.Browser Console Errors:
publicPath and asset paths.{{ encore_entry_script_tags('jquery') }}
{{ encore_entry_script_tags('datatables') }}
Symfony Profiler: Use the profiler to inspect DataTables events:
// In a controller
$event = new DataTablesEvent($dataTables);
$this->get('event_dispatcher')->dispatch($event, 'debricked.datatables.build');
Debricked\DatatablesBundle\DataTables\DataProviderInterface for nonHow can I help you explore Laravel packages today?