Installation:
composer require azraelir/datatablesbundle
Enable the bundle in config/bundles.php:
return [
// ...
Azraelir\DatatablesBundle\AzraelirDatatablesBundle::class => ['all' => true],
];
Basic Configuration:
Add to config/packages/azraelir_datatables.yaml:
azraelir_datatables:
entities:
App\Entity\YourEntity: ~
First Use Case: Create a controller method to handle DataTables requests:
use Azraelir\DatatablesBundle\Annotation\DataTables;
use Azraelir\DatatablesBundle\Annotation\DataColumn;
/**
* @DataTables(
* entity="App\Entity\YourEntity",
* columns={
* @DataColumn(property="id", title="ID"),
* @DataColumn(property="name", title="Name")
* }
* )
*/
public function yourEntityAction(Request $request)
{
return $this->get('azraelir_datatables.datatable')->handleRequest($request);
}
Template Integration: Include DataTables CSS/JS in your Twig template:
{{ azraelir_datatables_js() }}
{{ azraelir_datatables_css() }}
Render the table:
{{ azraelir_datatables_table({
'entity': 'App\Entity\YourEntity',
'columns': [
{ 'property': 'id', 'title': 'ID' },
{ 'property': 'name', 'title': 'Name' }
]
}) }}
Entity-Based Tables: Use annotations or YAML config to define tables for Doctrine entities:
# config/packages/azraelir_datatables.yaml
azraelir_datatables:
entities:
App\Entity\User:
columns:
- { property: 'username', title: 'Username' }
- { property: 'email', title: 'Email' }
- { property: 'roles', title: 'Roles' }
Custom Query Handling: Override the default query builder for complex logic:
use Azraelir\DatatablesBundle\Event\DataTablesEvent;
public function onBuildQuery(DataTablesEvent $event)
{
$event->getQueryBuilder()
->andWhere('u.active = :active')
->setParameter('active', true);
}
Register the listener in a service:
services:
App\EventListener\CustomDataTablesListener:
tags:
- { name: kernel.event_listener, event: azraelir.datatables.build_query, method: onBuildQuery }
Dynamic Columns: Use Twig to render dynamic columns:
{% for column in columns %}
{{ azraelir_datatables_column({
'property': column.property,
'title': column.title,
'render': 'App\\Controller\\YourController::renderCustomColumn'
}) }}
{% endfor %}
Server-Side Processing: Enable server-side processing in config:
azraelir_datatables:
server_side_processing: true
Integration with Forms: Use DataTables with Symfony Forms for inline editing:
{{ form_row(form.name, {
'attr': {
'data-dt-column': 'name',
'class': 'editable'
}
}) }}
Routing:
Use friendsofsymfony/jsrouting-bundle for AJAX routes:
# config/routes.yaml
azraelir_datatables:
resource: "@AzraelirDatatablesBundle/Resources/config/routing.yml"
prefix: "/datatables"
Asset Management:
Override default assets in config/packages/azraelir_datatables.yaml:
azraelir_datatables:
assets:
css: ['/bundles/azraelirdatatables/css/custom.css']
js: ['/bundles/azraelirdatatables/js/custom.js']
Localization: Configure translations for column titles:
# config/packages/azraelir_datatables.yaml
azraelir_datatables:
translations:
App\Entity\User:
username: 'utilisateur'
email: 'e-mail'
Pagination: Customize pagination settings:
$datatable->setOptions([
'paging' => true,
'pageLength' => 25,
'lengthMenu' => [[10, 25, 50, -1], [10, 25, 50, "All"]],
]);
PostgreSQL Limitation: The bundle is not tested or supported for PostgreSQL. Use MySQL or SQLite for production.
Annotation Caching: Clear cache after adding new annotations:
php bin/console cache:clear
Case-Sensitive Properties: Ensure property names in annotations match Doctrine entity properties exactly (including case).
Lazy-Loaded Associations:
Eager-load associations to avoid NULL values in columns:
$event->getQueryBuilder()
->leftJoin('u.roles', 'r')
->addSelect('r');
Memory Issues:
Large datasets may cause memory exhaustion. Use server-side processing (server_side_processing: true) and pagination.
Query Logging: Enable Doctrine query logging to debug SQL:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Request Dumping: Dump DataTables request data in development:
public function yourEntityAction(Request $request)
{
dump($request->request->all());
// ...
}
Event Listener Debugging: Log events to trace execution:
public function onBuildQuery(DataTablesEvent $event)
{
\Log::debug('Query built:', [
'query' => $event->getQueryBuilder()->getSQL(),
'params' => $event->getQueryBuilder()->getParameters()
]);
}
Reusable Config: Extract entity configurations to a separate YAML file and import them:
# config/packages/azraelir_datatables.yaml
imports:
- { resource: ../datatables/config.yaml }
Custom Rendering: Use Twig functions for custom cell rendering:
{{ azraelir_datatables_column({
'property': 'status',
'render': 'App\\Twig\\Extension\\DataTablesExtension::renderStatus'
}) }}
Performance: Add indexes to frequently filtered/sorted columns in your database.
Testing: Mock the DataTables service in PHPUnit:
$this->container->set('azraelir_datatables.datatable', $this->createMock(DataTables::class));
Extensions: Extend the bundle by creating custom column types or event subscribers. Example:
use Azraelir\DatatablesBundle\Column\ColumnInterface;
class CustomColumn implements ColumnInterface
{
public function render($value, array $rowData)
{
return '<span class="label label-' . $value . '">' . $value . '</span>';
}
}
Register it in services:
services:
App\Column\CustomColumn:
tags:
- { name: azraelir_datatables.column_type, type: 'custom' }
How can I help you explore Laravel packages today?