Install the Bundle
Add to composer.json:
"require": {
"thrace/datagrid-bundle": "^1.0"
}
Run composer update.
Enable the Bundle
Add to config/bundles.php:
Thrace\DataGridBundle\ThraceDataGridBundle::class => ['all' => true],
Basic Twig Usage Create a grid definition in a Twig template:
{{ thrace_datagrid({
'source': 'App\Entity\User',
'columns': [
{ 'name': 'id', 'index': 'id', 'width': 50, 'sortable': true },
{ 'name': 'username', 'index': 'username', 'width': 200 }
]
}) }}
First Use Case: Simple CRUD Grid Define a grid in a controller to fetch and display users:
// src/Controller/UserController.php
use Thrace\DataGridBundle\ThraceDataGridBundle;
public function indexAction()
{
return $this->render('user/index.html.twig', [
'grid' => $this->get('thrace.datagrid')->createGrid('user_grid')
]);
}
Grid Definition
Use YAML/XML or PHP arrays to define grids in config/grid.yml:
user_grid:
source: App\Entity\User
columns:
- { name: 'id', index: 'id', width: 50 }
- { name: 'email', index: 'email', width: 200 }
pager: true
rowNum: 10
Dynamic Column Configuration Override columns in Twig:
{{ thrace_datagrid(grid, {
'columns': [
{ 'name': 'actions', 'index': 'actions', 'formatter': 'actions', 'width': 100 }
]
}) }}
Query Building with Search/Filter
Use the search and filter options to build complex queries:
{{ thrace_datagrid(grid, {
'search': true,
'filter': {
'groupOp': 'AND',
'rules': [
{ 'field': 'username', 'op': 'cn', 'data': 'john' }
]
}
}) }}
Inline Editing Enable inline editing for a column:
columns:
- { name: 'email', index: 'email', editable: true, editrules: { required: true } }
Mass Actions Define mass actions in YAML:
mass_actions:
delete:
label: 'Delete'
action: 'user_delete'
confirm: 'Are you sure?'
Dependent Grids Link grids via foreign keys:
dependent_grids:
orders:
source: App\Entity\Order
foreign_key: user_id
Doctrine Integration Use DQL or QueryBuilder for custom queries:
source:
type: dql
query: SELECT u FROM App\Entity\User u WHERE u.active = 1
Custom Formatter Extend the bundle to add custom formatters:
// src/Thrace/DataGridBundle/Formatter/StatusFormatter.php
class StatusFormatter extends AbstractFormatter
{
public function format($cell, $rowData, $colModel, $rowId)
{
return $cell ? '<span class="label label-success">Active</span>' : '<span class="label label-danger">Inactive</span>';
}
}
Event Listeners Subscribe to grid events for pre/post-processing:
// src/EventSubscriber/DataGridSubscriber.php
class DataGridSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
ThraceDataGridEvents::PRE_BUILD_QUERY => 'onPreBuildQuery',
];
}
public function onPreBuildQuery(PreBuildQueryEvent $event)
{
$event->getQueryBuilder()->andWhere('u.deleted_at IS NULL');
}
}
AJAX Handling
Use Symfony’s JsonResponse for custom AJAX endpoints:
public function getGridDataAction(Request $request)
{
$grid = $this->get('thrace.datagrid')->createGrid('user_grid');
$data = $grid->getData($request->query->all());
return new JsonResponse($data);
}
Twig Environment Requirement
render() without Twig) will fail.render() with Twig explicitly:
return $this->render('template.html.twig');
Doctrine Proxy Issues
DISTINCT in queries or initialize proxies:
source:
type: dql
query: SELECT DISTINCT u FROM App\Entity\User u
jqGrid Version Mismatch
Resources/public/js/ for version dependencies and update accordingly.Pagination Conflicts
pager: false
Mass Action Security
public function userDeleteAction(Request $request)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
// Proceed with deletion
}
Column Index vs. Property Name
index (used for sorting/filtering) with name (display name) can lead to broken queries.index matches the database column or DQL alias:
columns:
- { name: 'Full Name', index: 'u.firstname', width: 150 }
Enable Query Logging
Add to config/packages/dev/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
Check logs for generated SQL queries.
Inspect Grid Data Dump grid data in a controller to verify structure:
$grid = $this->get('thrace.datagrid')->createGrid('user_grid');
$data = $grid->getData($request->query->all());
dump($data); // Check for expected structure
Check Browser Console jqGrid errors often appear in the browser’s console. Look for:
Validate YAML Configuration Use Symfony’s validator to check for syntax errors:
php bin/console debug:config thrace_datagrid
Custom Query Builders
Extend Thrace\DataGridBundle\Query\QueryBuilder to support non-Doctrine sources (e.g., Elasticsearch):
class ElasticQueryBuilder extends AbstractQueryBuilder
{
public function buildQuery(array $options)
{
// Custom Elasticsearch logic
}
}
Add Custom Grid Types
Implement Thrace\DataGridBundle\Grid\GridInterface for specialized grids (e.g., read-only grids):
class ReadOnlyGrid implements GridInterface
{
public function render(array $options)
{
// Custom rendering logic
}
}
Override Twig Functions Extend the bundle’s Twig environment to add custom functions:
// src/Thrace/DataGridBundle/DependencyInjection/Compiler/TwigPass.php
public function process(ContainerBuilder $container)
{
$twig = $container->getDefinition('twig');
$twig->addMethodCall('addFunction', [
new Expression('new \Thrace\DataGridBundle\Twig\CustomGridFunction()'),
]);
}
Hook into Grid Events Use events for pre/post
How can I help you explore Laravel packages today?