Skip to content

Latest commit

 

History

History
163 lines (120 loc) · 4.72 KB

File metadata and controls

163 lines (120 loc) · 4.72 KB

Quick Start

This guide creates a complete page backed by the in-memory array provider. It assumes every step in the Installation Guide is complete.

1. Create the datatable

Create src/Datatable/DemoUserDatatable.php:

<?php

declare(strict_types=1);

namespace App\Datatable;

use Zhortein\DatatableBundle\Attribute\AsDatatable;
use Zhortein\DatatableBundle\Contract\DatatableInterface;
use Zhortein\DatatableBundle\Definition\DatatableDefinition;
use Zhortein\DatatableBundle\Provider\ArrayDataProvider;

#[AsDatatable(name: 'demo-users', provider: 'array')]
final class DemoUserDatatable implements DatatableInterface
{
    public function buildDatatable(DatatableDefinition $definition): void
    {
        $definition
            ->setOption(ArrayDataProvider::OPTION_ROWS, [
                ['id' => 1, 'email' => 'admin@example.test', 'role' => 'ROLE_ADMIN'],
                ['id' => 2, 'email' => 'user@example.test', 'role' => 'ROLE_USER'],
            ])
            ->addColumn('id', visible: false)
            ->addColumn('email', label: 'Email')
            ->addColumn(
                name: 'role',
                label: 'Role',
                template: 'demo/cell/role.html.twig',
            )
        ;
    }
}

The #[AsDatatable] attribute registers the service under the demo-users name and explicitly selects the array provider.

Create templates/demo/cell/role.html.twig:

<span class="badge text-bg-secondary">
    {{ value }}
</span>
<small class="text-body-secondary">
    #{{ row_identifier }} · {{ datatable.name }}
</small>

The historical value variable remains available. Rich templates can also use the normalized row, provider source, row_identifier, datatable definition and explicit server-side context. See Cell Context and Computed Values for the complete contract and named PHP resolvers.

2. Create a page controller

Create src/Controller/DemoUserController.php:

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class DemoUserController extends AbstractController
{
    #[Route('/demo/users', name: 'app_demo_users', methods: ['GET'])]
    public function __invoke(): Response
    {
        return $this->render('demo/users.html.twig');
    }
}

3. Create the Twig template

Create templates/demo/users.html.twig:

{% extends 'base.html.twig' %}

{% block title %}Demo users{% endblock %}

{% block body %}
    <main class="container py-4">
        <h1>Demo users</h1>

        {{ zhortein_datatable('demo-users', {
            search: true
        }) }}
    </main>
{% endblock %}

4. Verify registration and routes

Run:

php bin/console debug:container --tag=zhortein_datatable.datatable
php bin/console debug:router app_demo_users
php bin/console debug:router zhortein_datatable_fragments
php bin/console debug:router zhortein_datatable_export

The datatable service and all three routes must be present before opening the page.

If labels are translation keys, set the application catalog once on the definition with setTranslationDomain('your_domain'). Columns, filters, actions, confirmations, Search Builder labels and export headers will then use the current request locale for the initial page, Ajax fragments and CSV/XLSX files. See declarative translations.

5. Open the page

Start the application with your usual local server and open:

/demo/users

The initial response renders the table shell. The lazy Stimulus controller then requests:

/_zhortein/datatable/demo-users/fragments

The final table contains the two email addresses, search, sortable headers, pagination and CSV export. The hidden id column is not displayed or exported by default.

If the shell renders but the rows never appear, use the frontend checks in the installation troubleshooting section.

6. Move to Doctrine

For an entity-backed table:

  • declare provider: 'doctrine';
  • call $definition->setEntityClass(YourEntity::class);
  • prefix fields from the root entity with e..

Continue with the Doctrine Provider Guide for joins, filters, searching, sorting and performance guidance.

Next steps