-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array source #63
Comments
Hey. For now, only Doctrine ORM queries are supported, although I want it to be supported by default as well. Creating an array adapter would require adding a ProxyQuery class accepting arrays and handling pagination and sorting. |
Ok, I'll wait. Thanks! |
I'm trying to achieve same goal. Hope can this steps can help you @easis In my case, I have a custom Doctrine query (from // Controller
public function customDatatableAction(Request $request, WorkOrderResultRepository $wor): Response
{
$data = $wor->batchAnalysis();
/**
[
[
"batchCode" => "2416",
"totalWorkstationSeconds" => "815448"
],
[...]
]
*/
$batchAnalysisArrayProxyQuery = new ArrayProxyQuery(
data: $data,
page: $request->query->has('page_batch_analysis') ? (int) $request->query->get('page_batch_analysis') : 1
);
$dataTable = $this->createDataTable(BatchAnalysisDataTableType::class, $batchAnalysisArrayProxyQuery);
$dataTable->handleRequest($request);
if ($dataTable->isExporting()) {
return $this->file($dataTable->export());
}
return $this->render('@App/admin/reports/batch_analysis.html.twig', [
'batchAnalysisTable' => $dataTable->createView(),
]);
} Then I've created a custom <?php
namespace App\Datatable\Query;
use App\Doctrine\Enum\SortOrderEnum;
use Kreyu\Bundle\DataTableBundle\Filter\Filter;
use Kreyu\Bundle\DataTableBundle\Filter\FilterData;
use Kreyu\Bundle\DataTableBundle\Pagination\PaginationData;
use Kreyu\Bundle\DataTableBundle\Query\ResultSet;
use Kreyu\Bundle\DataTableBundle\Sorting\SortingData;
use Kreyu\Bundle\DataTableBundle\Query\ProxyQueryInterface;
use Kreyu\Bundle\DataTableBundle\Query\ResultSetInterface;
final class ArrayProxyQuery implements ProxyQueryInterface
{
public function __construct(
private array $data,
private readonly int $page = 1,
) {
}
public function sort(SortingData $sortingData): void
{
foreach ($sortingData->getColumns() as $column) {
usort($this->data, function ($a, $b) use ($column) {
if ($column->getDirection() === strtolower(SortOrderEnum::ASC->value)) {
return ($a[$column->getName()] < $b[$column->getName()]) ? -1 : 1;
} else {
return ($a[$column->getName()] > $b[$column->getName()]) ? -1 : 1;
}
});
}
}
public function paginate(PaginationData $paginationData): void
{
if ($this->page > 1) {
$total = count($this->data);
$limit = $paginationData->getPerPage();
$totalPages = ceil($total / $limit);
$page = max($this->page, 1);
$page = min($page, $totalPages);
$offset = ($page - 1) * $limit;
if( $offset < 0 ) {
$offset = 0;
}
$this->data = array_slice($this->data, $offset, $limit);
}
}
public function getResult(): ResultSetInterface
{
return new ResultSet(
iterator: new \ArrayIterator(iterator_to_array($this->data)),
currentPageItemCount: $this->page,
totalItemCount: count($this->data),
);
}
public function filterDataBy(FilterData $filterData, Filter $filter): void
{
$this->data = array_filter($this->data, function ($item) use ($filterData, $filter) {
return $item[$filter->getConfig()->getName()] === $filterData->getValue();
});
}
} Finally, I've implemented my own <?php
namespace App\Datatable\Type;
use App\Datatable\Query\ArrayProxyQuery;
use App\Doctrine\Enum\SortOrderEnum;
use Kreyu\Bundle\DataTableBundle\Filter\FilterData;
use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface;
use Kreyu\Bundle\DataTableBundle\Filter\Operator;
use Kreyu\Bundle\DataTableBundle\Filter\Type\CallbackFilterType;
use Kreyu\Bundle\DataTableBundle\Bridge\PhpSpreadsheet\Exporter\Type\CsvExporterType;
use Kreyu\Bundle\DataTableBundle\Bridge\PhpSpreadsheet\Exporter\Type\XlsxExporterType;
use Kreyu\Bundle\DataTableBundle\Column\Type\NumberColumnType;
use Kreyu\Bundle\DataTableBundle\Column\Type\TextColumnType;
use Kreyu\Bundle\DataTableBundle\Pagination\PaginationData;
use Kreyu\Bundle\DataTableBundle\Sorting\SortingData;
use Kreyu\Bundle\DataTableBundle\Type\AbstractDataTableType;
use Kreyu\Bundle\DataTableBundle\DataTableBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class BatchAnalysisDataTableType extends AbstractDataTableType
{
public function buildDataTable(DataTableBuilderInterface $builder, array $options): void
{
$builder
->addColumn(
'batchCode',
TextColumnType::class,
[
'label' => 'batchCode',
'property_path' => '[batchCode]',
'sort' => true,
'export' => true,
]
)
->addColumn(
'totalWorkstationSeconds',
NumberColumnType::class,
[
'label' => 'totalWorkstationSeconds',
'property_path' => '[totalWorkstationSeconds]',
'sort' => true,
'export' => true,
]
)
->addFilter(
'batchCode',
CallbackFilterType::class,
[
'default_operator' => Operator::Equals,
'callback' => function (ArrayProxyQuery $query, FilterData $data, FilterInterface $filter): void {
$query->filterDataBy($data, $filter);
},
]
)
->addFilter(
'totalWorkstationSeconds',
CallbackFilterType::class,
[
'default_operator' => Operator::Equals,
'callback' => function (ArrayProxyQuery $query, FilterData $data, FilterInterface $filter): void {
$query->filterDataBy($data, $filter);
},
]
)
->addExporter('csv', CsvExporterType::class)
->addExporter('xlsx', XlsxExporterType::class)
->setDefaultSortingData(SortingData::fromArray([
'batchCode' => strtolower(SortOrderEnum::ASC->value),
]))
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'filtration_enabled' => true,
]);
}
} |
At last, a simple |
Hi! I'm trying to build a datatable with an array as a source. My goal is to allow the users to filter some values (select one or more employees from a list, date rangee and some other checkboxes) and perform some queries to gather data, do some business logic and present the results in the datatable.
I did not find any example in the docs about how to this and actually don't know if this is possible.
The text was updated successfully, but these errors were encountered: