Closed Shotman closed 11 months ago
Hello,
What is the Symfony version used ?
I'm using symfony v6.3.3
Have you got override the getCSVExporter() method in App\Provider\MyDataTableProvider
class ?
You must have the following lines :
/**
* {@inheritDoc}
*/
public function getCSVExporter(): ?DataTablesCSVExporterInterface {
return $this;
}
Here is my complete provider
<?php
namespace App\Provider;
use App\Entity\App\MyEntity;
use Symfony\Component\HttpClient\HttpClient;
use WBW\Bundle\JQuery\DataTablesBundle\Api\{DataTablesColumnInterface,
DataTablesOptionsInterface,
DataTablesResponseInterface};
use WBW\Bundle\JQuery\DataTablesBundle\Factory\DataTablesFactory;
use WBW\Bundle\JQuery\DataTablesBundle\Helper\DataTablesWrapperHelper;
use WBW\Bundle\JQuery\DataTablesBundle\Provider\{DataTablesCSVExporterInterface,
DataTablesEditorInterface,
DataTablesProviderInterface};
class MyEntityProvider implements DataTablesProviderInterface, DataTablesCSVExporterInterface
{
/**
* @inheritDoc
*/
public function getColumns(): array
{
$dtColumns = [];
$dtColumns[] = DataTablesFactory::newColumn("name", "Name");
$dtColumns[] = DataTablesFactory::newColumn("code", "Code")
->setOrderable(true)
->setSearchable(true);
// Returns the columns.
return $dtColumns;
}
/**
* @inheritDoc
*/
public function getEntity()
{
return MyEntity::class;
}
/**
* @inheritDoc
*/
public function getMethod(): ?string
{
return "GET";
}
/**
* @inheritDoc
*/
public function getName(): string
{
return "my_entity";
}
/**
* @inheritDoc
*/
public function getOptions(): ?DataTablesOptionsInterface
{
$dtOptions = DataTablesFactory::newOptions();
$dtOptions->addOption("language", ["url" => DataTablesWrapperHelper::getLanguageUrl("French")]);
return $dtOptions;
}
/**
* @inheritDoc
*/
public function getPrefix(): string
{
return "jf";
}
/**
* @inheritDoc
*/
public function getView(): ?string
{
return null;
}
/**
* @inheritDoc
*/
public function renderColumn(DataTablesColumnInterface $dtColumn, $entity): ?string
{
$output = null;
// Switch into column data.
switch ($dtColumn->getData()) {
case "name":
$output = $entity->getName();
break;
case "code":
$output = $entity->getCode();
break;
}
// Return the output.
return $output;
}
/**
* @inheritDoc
*/
public function renderRow(string $dtRow, $entity, int $rowNumber)
{
$output = null;
// Switch into column data.
switch ($dtRow) {
case DataTablesResponseInterface::DATATABLES_ROW_ATTR:
break;
case DataTablesResponseInterface::DATATABLES_ROW_CLASS:
$output = (0 === $rowNumber % 2 ? "even" : "odd");
break;
case DataTablesResponseInterface::DATATABLES_ROW_DATA:
$output = ["pkey" => $entity->getUid()];
break;
case DataTablesResponseInterface::DATATABLES_ROW_ID:
$output = "jf_" . $entity->getUid();
break;
}
// Return the output.
return $output;
}
public function exportColumns(): array
{
$output = [];
$output[] = 'Name';
$output[] = 'Code';
return $output;
}
public function exportRow($entity): array
{
$output = [];
$output[] = $entity->getName();
$output[] = $entity->getCode();
// Return the output.
return $output;
}
public function getCSVExporter(): ?DataTablesCSVExporterInterface
{
return $this;
}
public function getEditor(): ?DataTablesEditorInterface
{
return null;
}
}
And the command wbw:jquery:datatables:provider:list
result :
------------------ -------------------------------------- --------- -------- ------ -----
Name Service/Entity Columns Prefix View CSV
------------------ -------------------------------------- --------- -------- ------ -----
2 jf OK MyEntityProvider
└ App\Entity\App\MyEntity
------------------ -------------------------------------- --------- -------- ------ -----
The name
parameter in the route is equal at the provider name.
Each name
argument in PHP must match with the name returned by your provider.
In provider, you return 'my_entity', so the URI must be /datatables/my_entity/export and a controller must call :
// [....]
$this->getDataTablesProvider("my_entity");
// [....]
Also, your controller doesn't must extends DataTablesController or any controller provided by this bundle. The implementation must be detached of code provided except the interfaces DataTablesProviderInterface and the DataTablesFactory
Take a look the Tests directory of the bundle, you have a complete implementation of the bundle :
If I don't extend DataTablesController
the method getDataTablesProvider
isn't available anymore in my controller so how can I put a datatable inside my app views with custom routes ?
Like I want to have a route : /dashboard/users
with the users datatable and other things in its view and that route is managed by DashboardController::users()
handling, many other things other than the datatable, that's what I want to acheive
Yes, it's possible to make similar things with a different approach.
Make a simple controller like this :
class UserController extends AbstractController {
// [...]
public function indexAction(): Response {
return $this->forward(DataTablesController::class . "::indexAction", [
"name" => 'my_entity',
]);
}
// [...]
}
Update your provider:
class MyEntityProvider implements DataTablesProviderInterface, DataTablesCSVExporterInterface {
// [...]
/**
* @inheritDoc
*/
public function getView(): ?string {
return 'home/datatable.html.twig';
}
// [...]
}
Yes, it's possible to make similar things with a different approach.
Make a simple controller like this :
class UserController extends AbstractController { // [...] public function indexAction(): Response { return $this->forward(DataTablesController::class . "::indexAction", [ "name" => 'my_entity', ]); } // [...] }
Update your provider:
class MyEntityProvider implements DataTablesProviderInterface, DataTablesCSVExporterInterface { // [...] /** * @inheritDoc */ public function getView(): ?string { return 'home/datatable.html.twig'; } // [...] }
Works like a charm ! I have my data and the bootstrap theme working great ! Everything seems to be happening server side, now time to play with plugins etc Thanks
You can also use the routes (wbw_jquery_datatables_options/wbw_jquery_datatables_render) with JS and append DataTables on every page you want with the DataTables server side mechanism provided by this bundle.
Don't forget that DataTables providers are services and can be used as you want from each Twig template by calling dtWrapper.provider.myCustomMethod()
Best regards
Hello, I've installed the bundle successfully created my provider and extended my repository and when I got to the route "datatables/[name]/export" I do get a CSV with all the data, right columns etc but I can't get to have the web version of the datatable I get an error saying :
get_class(): Argument #1 ($object) must be of type object, null given
on\vendor\webeweb\jquery-datatables-bundle\Controller\AbstractController.php:291
and all I'm doing in the controller is :
services.yaml looks like :
The view looks like this :
So what seem to be the problem ?