Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Datatable Bundle Laravel Package

app-verk/datatable-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require app-verk/datatable-bundle
    

    Enable it in config/bundles.php:

    AppVerk\DatatableBundle\AppVerkDatatableBundle::class => ['all' => true],
    
  2. First Use Case Create a controller method to handle DataTable AJAX requests:

    use AppVerk\DatatableBundle\Controller\DataTableControllerTrait;
    
    class ProductController extends AbstractController
    {
        use DataTableControllerTrait;
    
        public function dataTableAction(Request $request)
        {
            $queryBuilder = $this->createQueryBuilder(); // Your Doctrine QL
            return $this->handleDataTableRequest($request, $queryBuilder);
        }
    
  3. Frontend Integration Use jQuery DataTables with server-side processing:

    $('#products-table').DataTable({
        processing: true,
        serverSide: true,
        ajax: {
            url: '/products/datatable',
            type: 'POST'
        },
        columns: [
            { data: 'id', name: 'p.id' },
            { data: 'name', name: 'p.name' }
        ]
    });
    
  4. Configuration Check config/packages/app_verk_datatable.yaml for default settings (e.g., pagination, sorting).


Implementation Patterns

Core Workflow

  1. Query Builder Integration Extend DataTableControllerTrait to inject your custom query logic:

    protected function createQueryBuilder()
    {
        return $this->getDoctrine()
            ->getRepository(Product::class)
            ->createQueryBuilder('p')
            ->where('p.active = :active')
            ->setParameter('active', true);
    }
    
  2. Dynamic Column Handling Map DataTable column names to Doctrine fields via annotations or YAML:

    # config/packages/app_verk_datatable.yaml
    app_verk_datatable:
        columns:
            Product:
                name: 'p.name'
                price: 'p.price'
                actions: '@app_verk_datatable.action_link'
    
  3. Custom Actions Register action buttons (e.g., edit/delete) in your controller:

    public function getActions(Product $product)
    {
        return [
            'edit' => [
                'route' => 'product_edit',
                'params' => ['id' => $product->getId()],
                'title' => 'Edit'
            ],
            'delete' => [
                'route' => 'product_delete',
                'params' => ['id' => $product->getId()],
                'title' => 'Delete',
                'class' => 'btn-danger'
            ]
        ];
    }
    
  4. Pagination & Sorting Leverage KnpPaginatorBundle integration for advanced features:

    $paginator = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $queryBuilder,
        $request->query->getInt('start') / $request->query->getInt('length') + 1,
        $request->query->getInt('length')
    );
    return $this->handleDataTableResponse($request, $pagination);
    

Advanced Patterns

  • Conditional Logic: Use onDataTableRequest to modify the query dynamically:

    protected function onDataTableRequest(Request $request, QueryBuilder $qb)
    {
        if ($request->query->has('search')) {
            $qb->andWhere('p.name LIKE :search')
               ->setParameter('search', '%'.$request->query->get('search').'%');
        }
    }
    
  • Caching: Cache responses for static data:

    $cache = $this->get('cache.app');
    $cacheKey = 'datatable_products_'.md5($request->query->get('search'));
    if ($cache->has($cacheKey)) {
        return $cache->get($cacheKey);
    }
    
  • Export Integration: Combine with KnpSnappyBundle for PDF/Excel exports:

    public function exportAction(Request $request)
    {
        $queryBuilder = $this->createQueryBuilder();
        $data = $this->handleDataTableRequest($request, $queryBuilder)->getData();
        return $this->get('knp_snappy.pdf')->generateFromHtml($this->renderView('export/grid.html.twig', ['data' => $data]));
    }
    

Gotchas and Tips

Common Pitfalls

  1. Deprecated Dependencies

    • The bundle requires Symfony 4.2/4.4 and Doctrine ORM. Ensure compatibility with your project.
    • jms/serializer-bundle is listed but may not be actively used. Remove if unused to avoid conflicts.
  2. Query Builder Assumptions

    • The bundle expects a Doctrine QueryBuilder. Avoid passing raw Query objects or repositories directly.
    • Fix: Wrap repositories in a createQueryBuilder() call.
  3. Column Mapping Issues

    • If columns are misconfigured in YAML, DataTables may return empty data.
    • Debug: Enable APP_VERBOSE_LOGGING=1 to see raw SQL and column mappings.
  4. CSRF Token Conflicts

    • AJAX requests may fail due to missing CSRF tokens. Exclude the route from CSRF protection in config/packages/security.yaml:
      security:
          access_control:
              - { path: ^/datatable, roles: PUBLIC }
      
  5. Pagination Offsets

    • DataTables uses 0-based indexing for pagination, but KnpPaginator uses 1-based. The bundle handles this, but custom paginators may break it.
    • Workaround: Use the bundle’s handleDataTableResponse() method instead of manual pagination.

Debugging Tips

  • Log Raw Requests:

    use Psr\Log\LoggerInterface;
    
    public function dataTableAction(Request $request, LoggerInterface $logger)
    {
        $logger->debug('DataTable Request:', [
            'query' => $request->query->all(),
            'request' => $request->request->all()
        ]);
        // ...
    }
    
  • Validate JSON Response: Ensure the response matches DataTables’ expected format:

    {
        "draw": 1,
        "recordsTotal": 100,
        "recordsFiltered": 50,
        "data": [...]
    }
    

    Use jsonlint.com to validate output.

  • Check for Deprecation Warnings: The bundle was last updated in 2020. Test with PHP 8.1+ and Symfony 5+ for compatibility issues.

Extension Points

  1. Custom Response Transformers Override AppVerk\DatatableBundle\Response\DataTableResponse to modify the JSON structure:

    class CustomDataTableResponse extends DataTableResponse
    {
        protected function transformData($data)
        {
            return array_map(function ($item) {
                $item['custom_field'] = 'value';
                return $item;
            }, $data);
        }
    }
    

    Register the service in config/services.yaml:

    AppVerk\DatatableBundle\Response\DataTableResponse:
        class: App\CustomDataTableResponse
    
  2. Event Listeners Subscribe to datatable.build.query and datatable.response events:

    use AppVerk\DatatableBundle\Event\DataTableEvents;
    
    $dispatcher->addListener(DataTableEvents::BUILD_QUERY, function ($event) {
        $event->getQueryBuilder()->andWhere('...');
    });
    
  3. Twig Extensions Add custom filters for frontend processing:

    class DatatableExtension extends \Twig\Extension\AbstractExtension
    {
        public function getFilters()
        {
            return [
                new \Twig\TwigFilter('format_datatable_date', [$this, 'formatDate']),
            ];
        }
    }
    

    Use in templates:

    {{ item.createdAt|format_datatable_date }}
    

Performance Tips

  • Selective Field Loading: Explicitly define fields in SELECT to reduce query overhead:

    $qb->select('p.id, p.name, p.price'); // Instead of 'p'
    
  • Indexed Columns: Ensure frequently filtered/sorted columns are indexed in the database.

  • Lazy Loading: For large datasets, use setFetchMode(\Doctrine\ORM\Query\ResultSetMapping::HYDRATE_ARRAY) to avoid hydration overhead.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky