brown298/data-tables-generator-bundle
Installation
Add the bundle to your composer.json:
composer require brown298/data-tables-generator-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Brown298\DataTablesGeneratorBundle\Brown298DataTablesGeneratorBundle::class => ['all' => true],
];
Basic Configuration
Publish the default config (if needed) and adjust in config/packages/brown298_data_tables_generator.yaml:
brown298_data_tables_generator:
default_options: ~ # Override defaults here
First Use Case: Rendering a Table
Use the DataTablesGenerator service in a controller:
use Brown298\DataTablesGeneratorBundle\DataTablesGenerator;
public function index(DataTablesGenerator $generator)
{
$data = [
['id' => 1, 'name' => 'John', 'email' => 'john@example.com'],
['id' => 2, 'name' => 'Jane', 'email' => 'jane@example.com'],
];
return $generator->generate($data, [
'columns' => [
['data' => 'id', 'title' => 'ID'],
['data' => 'name', 'title' => 'Name'],
['data' => 'email', 'title' => 'Email'],
],
]);
}
Twig Integration Render the output in a Twig template:
{{ include('Brown298DataTablesGeneratorBundle::table.html.twig', {
table: table
}) }}
Use generate() with serverSide: true for large datasets:
$generator->generate($data, [
'serverSide' => true,
'columns' => [...],
'ajax' => [
'url' => $this->generateUrl('api_datatable'),
'type' => 'POST',
],
]);
Fetch columns from a Doctrine entity or DTO:
$columns = [];
foreach ($entity->getMetadata()->getFieldNames() as $field) {
$columns[] = ['data' => $field, 'title' => ucfirst($field)];
}
Override Twig templates by copying from:
vendor/brown298/data-tables-generator-bundle/Resources/views/
to:
templates/bundles/brown298datatablesgenerator/
Combine with Symfony Forms for editable tables:
$formFactory = $this->get('form.factory');
$form = $formFactory->createBuilder()
->add('name', TextType::class)
->add('email', EmailType::class)
->getForm();
$generator->generate($data, [
'columns' => [
['data' => 'id', 'title' => 'ID'],
['data' => 'name', 'title' => 'Name', 'render' => function($value, $row) use ($formFactory) {
return $formFactory->createNamed('edit_name', TextType::class, $row['name'])->render();
}],
],
]);
Use generate() with ajax options for SPAs:
return $generator->generate($data, [
'ajax' => [
'url' => '/api/table-data',
'dataSrc' => '',
],
'processing' => true,
]);
Listen to datatables.generator.init to modify options globally:
$eventDispatcher->addListener('datatables.generator.init', function($event) {
$event->setOptions(array_merge($event->getOptions(), [
'language' => ['url' => '/locales/datatables.json'],
]));
});
Use Brown298\DataTablesGeneratorBundle\QueryBuilder\DataTablesQueryBuilder for server-side filtering/sorting:
$qb = $this->createQueryBuilder('u');
$generator->applyDataTables($qb, $request);
$data = $qb->getQuery()->getResult();
Extend Brown298\DataTablesGeneratorBundle\DataTablesGenerator:
class CustomGenerator extends DataTablesGenerator
{
public function generateCustom($data, array $options)
{
// Custom logic
return parent::generate($data, $options);
}
}
Register as a service:
services:
custom.datatables.generator:
class: App\CustomGenerator
tags: ['datatables.generator']
Server-Side vs. Client-Side
serverSide: true causes all data to load client-side, breaking pagination/sorting for large datasets.Column Data Mismatch
data in columns must match keys in your data array/object.array_keys($data[0]) or get_class_methods($entity).Twig Template Overrides
templates/bundles/brown298datatablesgenerator/ and named exactly (e.g., table.html.twig).CORS for AJAX
$response->headers->set('Access-Control-Allow-Origin', '*');
Doctrine Lazy Loading
QueryBuilder throws LazyLoadingException if entities aren’t fully loaded.DISTINCT or fetch related entities eagerly:
$qb->select('DISTINCT u');
$qb->leftJoin('u.profile', 'p')->addSelect('p');
Dump Options Log the final options to debug:
$options = $generator->getOptions($request, $defaultOptions);
\Symfony\Component\Debug\Debug::dump($options);
Check Request Data For server-side processing, inspect the incoming request:
$requestData = json_decode($request->getContent(), true);
\Symfony\Component\Debug\Debug::dump($requestData);
Validate JSON Output Ensure the generator returns valid JSON for AJAX:
$response = new JsonResponse($generator->generate(...));
$response->setEncodingOptions($response->getEncodingOptions() | JSON_PRETTY_PRINT);
Default Options
config/packages/brown298_data_tables_generator.yaml:
brown298_data_tables_generator:
default_options:
serverSide: true
processing: true
language:
url: '/locales/datatables.json'
Language Files
public/locales/ and reference:
'language' => ['url' => '/locales/datatables_custom.json']
Column Callbacks
render for custom cell rendering, but ensure callbacks are serializable if used in AJAX:
'columns' => [
['data' => 'status', 'render' => function($value) {
return $value === 'active' ? '<span class="label label-success">Active</span>' : 'Inactive';
}],
]
Custom DataTables Version Override the included DataTables JS/CSS by extending the bundle’s assets:
# config/packages/twig.yaml
twig:
paths:
'%kernel.project_dir%/templates/bundles/brown298datatablesgenerator/assets':
prefix: 'bundles/brown298datatablesgenerator/assets'
Event Listeners
Subscribe to datatables.generator.post_generate to modify the final output:
$eventDispatcher->addListener('datatables.generator.post_generate', function($event) {
$event->setTableData(array_map(function($row) {
$row['custom_field'] = 'added_via_listener';
return $row;
}, $event->getTable
How can I help you explore Laravel packages today?