loicpennamen / sf-shared-repository
This class replaces Symfony4's ServiceEntityRepository to allow powerful search queries in Symfony with Datatables.
1.3.2
2023-02-16 13:20 UTC
This package is auto-updated.
Last update: 2024-10-23 20:02:59 UTC
README
Toolbox to quickly use Datatables with Symfony4 entities.
Config
services.yaml
LoicPennamen\SharedRepository\:
resource: '../vendor/loicpennamen/sf-shared-repository/'
controller example
/**
* @Route("/users", name="app_user_search")
*/
public function search(UserService $userService, DatatableService $datatableService)
{
$this->denyAccessUnlessGranted('searchUsers');
// List of DtColumn objects
$columns = $userService->getColumns();
return $this->render('user/search.html.twig', [
'columns' => $columns,
'datatableService' => $datatableService,
]);
}
/**
* @Route("/api/users", name="app_user_search_api")
*/
public function searchApi(Request $request, EntityManagerInterface $em, UserService $userService, DatatableService $datatableService)
{
$this->denyAccessUnlessGranted('searchUsers');
// Vars
$repo = $em->getRepository(User::class);
// Search
$tableColumns = $userService->getColumns();
$options = $datatableService->getOptionsFromRequest($request, $tableColumns);
$entities = $repo->search($options);
// Formate data
$rows = [];
foreach ($entities as $entity)
$rows[] = $datatableService->getRow($entity, $tableColumns);
// Result container
$results = [
'data' => $rows,
'recordsTotal' => $repo->countSearchTotal($options),
'recordsFiltered' => $repo->countSearch($options),
];
return $this->json( $results );
}
template example
{# @var columns #}
{# @var column \LoicPennamen\SharedRepository\DtColumn #}
{# @var datatableService \LoicPennamen\SharedRepository\DatatableService #}
{% set columns = columns is defined ? columns : [] %}
{% set tableId = tableId is defined ? tableId : 'dataTable' %}
{% set translationFile = translationFile is defined ? translationFile : asset('build/datatables/datatables.fr.json') %}
{% set data = data is defined ? data : [] %}
{% set dataUrl = dataUrl is defined ? dataUrl : null %}
<div class="mt-3 mb-4">
<table class="table table-striped" id="{{ tableId }}">
<thead>
<tr>
{% for column in columns %}
<th>
{{ column.label }}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<script>
$('#{{ tableId }}').DataTable({
"fixedHeader": {
header: true,
// headerOffset: 70
},
"scrollX": true,
"language": {
url: {{ translationFile|json_encode|raw }}
},
"autoWidth": false,
"lengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
"iDisplayLength": 25,
"processing": true,
"order": [],
// SERVER STUFF / AJAX CALL
{% if dataUrl %}
"serverSide": true,
"ajax": {
url: {{ dataUrl|json_encode|raw }},
type: 'POST',
{% if dataUrlParameters is defined and dataUrlParameters is not null %}
data: {{ dataUrlParameters }},
{% endif %}
error: function(e){
if(e.hasOwnProperty('responseJSON')){
if(e.responseJSON.hasOwnProperty('error')){
console.log("Datatable error : " + e.responseJSON.error);
return;
}
}
alert("Unknown error in Datatable, check log");
console.log(e);
}
},
{% endif %}
// Allow string filtering
"bFilter": true,
// Disable sorting on columns
{% if columns | length %}
"columnDefs": [{
sortable: false,
targets: {{ datatableService.getDisabledColumnsAsArray(columns)|json_encode|raw }}
}],
{% endif %}
// No initial load ?
// "iDeferLoading": 0,
// ////////////////
// KEEP DISPLAY ON PAGE QUIT
// Handle Save table state through pages
"stateSave": true,
// Parameters to keep on save
"stateSaveParams": function (settings, data) {
},
// Parameters to load on init
"stateLoadParams": function (settings, data) {
},
});
</script>
Cell design example: /templates/user/cell-infos.html.twig
(Entity is passed to template in its slug name)
{# @var user \App\Entity\User #}
{{ user.creationDate ? user.creationDate|date('d/m/Y H:i') }}