webinarium / DataTablesBundle

Symfony bundle for DataTables plugin.
MIT License
16 stars 9 forks source link

How to get Rooter for generate link on response AjaX Symfony 5.1 #14

Closed aniskasmi closed 4 years ago

aniskasmi commented 4 years ago

Hi, on my Datatable i want to send link on first column how to get the router on Symfony 5.1 ouside the controller on ****DataTables.php ?

$results->data[] = [ '<a href="***here***"><h6>'.$user->getLastname().'</h6></a>', '<h6>'.$user->getIdentity().'</h6>', $user->getPhone(), $user->getCity(), $user->getPack( true ), $user->getCertificationPhyto(), $technician, '<h6>'.$user->getPhone().'</h6>', '<h6>'.$user->getPhone().'</h6>' ];

Thx

webinarium commented 4 years ago

Hi,

As it's a Symfony project, you can inject any service you need, for example:

class UsersDataTable implements DataTableHandlerInterface
{
    protected $doctrine;
    protected $router;

    public function __construct(RegistryInterface $doctrine, RouterInterface $router)
    {
        $this->doctrine = $doctrine;
        $this->router   = $router;
    }

    public function handle(DataTableQuery $request): DataTableResults
    {
        ...

        $url = $this->router->generate('route_name', [/* route parameters */], UrlGeneratorInterface::ABSOLUTE_URL);

        $results->data[] = [

            '<a href="'.$url.'"><h6>'.$user->getLastname().'</h6></a>',
            '<h6>'.$user->getIdentity().'</h6>',
            $user->getPhone(),
            $user->getCity(),
            $user->getPack( true ),
            $user->getCertificationPhyto(),
            $technician,
            '<h6>'.$user->getPhone().'</h6>'
        ];

        ...
    }
}
webinarium commented 4 years ago

BTW, while mixing HTML and data works well, it may be not a good idea from the business logic and project maintenance points of view. I would recommend to return clean data and wrap it into tags (or whatever else) on the frontend (e.g. using columns.render).

For example, if some of my users can be "admins" and I want to show an "Admin" column with "yes"/"no" text, while my PHP class has corresponding isAdmin() function, I would return booleans:

$results->data[] = [
    ...
    $user->isAdmin(),
    ...
];

and transform the boolean values into text on the frontend (assuming 5 is a zero-based index of the column):

$('#users').DataTable({
    serverSide: true,
    ajax: '{{ path('users') }}',
    columnsDefs: [
        {
            targets: 5,
            render: function (data) {
                return data ? 'Yes' : 'No';
            },
        }
    ]
});

More complicated example is when you need one column to be based on data from others. Again, the backend returns only clean data:

$results->data[] = [
    $this->router->generate('route_name', [/* route parameters */], UrlGeneratorInterface::ABSOLUTE_URL),
    $user->getLastname(),
    ...
];

and the frontend transforms the data into a link:

$('#users').DataTable({
    serverSide: true,
    ajax: '{{ path('users') }}',
    columnsDefs: [
        {
            targets: 5,
            render: function (data, type, row) {
                return '<a href="' + row[0] + '"><h6>' + row[1] + '</h6></a>';
            },
        }
    ]
});