Installation:
composer require sg/datatablesbundle
Register the bundle in config/bundles.php:
return [
// ...
Stwe\DatatablesBundle\StweDatatablesBundle::class => ['all' => true],
];
Basic Controller Integration:
use Stwe\DatatablesBundle\DataTablesController;
use Stwe\DatatablesBundle\DataTablesFactory;
class UserController extends DataTablesController
{
public function userTableAction(DataTablesFactory $factory)
{
return $this->createDataTableResponse($factory->create()
->add('id', 'column')
->add('name', 'column')
->add('email', 'column')
->setDataSource($this->getDoctrine()->getRepository('App:User')->findAll())
);
}
}
First Use Case: Render a table in a Twig template:
{{ render(controller('App\Controller\UserController::userTableAction')) }}
Repository Integration: Use Doctrine repositories as data sources:
$factory->create()
->setDataSource($this->getDoctrine()->getRepository('App:User')->findAll())
->add('username', 'column', ['title' => 'Username']);
Column Customization:
$this->columnBuilder->add('id', 'column', ['title' => 'ID']);
$this->columnBuilder->add('actions', 'action', [
'title' => 'Actions',
'actions' => [
'edit' => ['route' => 'edit_user', 'params' => ['id' => 'id']],
'delete' => ['route' => 'delete_user', 'params' => ['id' => 'id']],
],
]);
Server-Side Processing: Enable server-side processing for large datasets:
$factory->create()
->setServerSide(true)
->setDataSource($this->getDoctrine()->getRepository('App:User')->findAll());
Pagination and Sorting: Leverage built-in support:
$factory->create()
->setDefaultSort(['column' => 'name', 'dir' => 'asc'])
->setDefaultLength(10);
Twig Integration:
Use render in templates or embed via:
{% datatables_table table %}
# config/routes.yaml
user_table:
path: /user/table
controller: App\Controller\UserController::userTableAction
{{ encore_entry_link_tags('app') }}
{{ encore_entry_script_tags('app') }}
vendor/stwe/datatables-bundle/Resources/views/.CORS Issues: If using AJAX with server-side processing, ensure CORS headers are configured for cross-origin requests.
// In a controller or event subscriber
$response->headers->set('Access-Control-Allow-Origin', '*');
Doctrine QueryBuilder Limitation:
Server-side processing may fail if the underlying query doesn’t support COUNT(*) or LIMIT/OFFSET. Use raw SQL or hydrate to arrays if needed:
$queryBuilder->select('u.id, u.name, u.email');
Column Naming Conflicts:
Avoid column names that conflict with DataTables reserved keywords (e.g., order, search).
Pagination Overhead:
Server-side processing with large datasets can be resource-intensive. Optimize queries with indexes and avoid SELECT *.
Enable Debug Mode:
Set debug: true in config/packages/stwe_datatables.yaml to log DataTables requests:
stwe_datatables:
debug: true
Check Network Requests: Use browser dev tools to inspect AJAX payloads and responses for misconfigurations.
Validate JSON Responses: Ensure responses match DataTables expected format:
{
"draw": 1,
"recordsTotal": 100,
"recordsFiltered": 100,
"data": [...]
}
Custom Columns: Extend the bundle by creating custom column types:
namespace App\DataTables\Column;
use Stwe\DatatablesBundle\Column\AbstractColumn;
class CustomColumn extends AbstractColumn
{
public function render($row)
{
return '<span class="custom-class">' . $row['value'] . '</span>';
}
}
Register in services.yaml:
services:
App\DataTables\Column\CustomColumn:
tags: ['stwe.datatables.column_type']
Event Listeners:
Subscribe to DataTables events (e.g., datatables.build.query) to modify queries dynamically:
use Stwe\DatatablesBundle\Event\BuildQueryEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class DataTablesSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
BuildQueryEvent::NAME => 'onBuildQuery',
];
}
public function onBuildQuery(BuildQueryEvent $event)
{
$event->getQueryBuilder()->andWhere('u.active = 1');
}
}
Configuration Overrides:
Override default settings in config/packages/stwe_datatables.yaml:
stwe_datatables:
default_options:
processing: true
server_side: true
ajax:
url: '/api/datatables'
How can I help you explore Laravel packages today?