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') }}