Datatables – Tri sur des dates au format FR
Me revoici pour un article sur Datatables. Cette fois-ci, nous allons voir comment effectuer un tri sur une colonne qui contient une date au format français, c’est-à-dire JJ/MM/AAAA.
Juste pour rappel, j’ai écrit 3 articles sur l’utilisation de Datatables :
Aujourd’hui nous allons voir comment trier une colonne qui contient des dates au format français. Eh oui, par défaut Datatables comprend bien qu’il y a des dates dans votre colonne, par contre il ne connaît que des dates au format anglais, donc de la forme MM/JJ/AAAA. Du coup, quand vous triez une colonne, le tri se fait sur les jours, puis les mois et les années. Pas top. Nous allons voir 2 méthodes pour que le tri se fasse correctement.
Méthode 1
C’est la méthode la plus simple. Il suffit d’ajouter un attribut « data-order » sur chaque cellule concernée (chaque <td>), et de lui donner pour valeur un timestamp. Dans mon projet, comme j’utilise le système de templating Twig, j’utilise le filtre « date » pour générer un timestamp à partir de la date. Mon code ressemble à ça :
Ce qui est important, c’est la ligne :
<td data-order="{{ rdv.dateDebut|date('U') }}">
Le « date(‘U’) » va générer un nombre correspondant au nombre de secondes écoulées depuis l’époque Unix (1er janvier 1970 à 0h00). Vous pouvez retrouver les différents formatages de date ici. Même si vous n’utilisez pas Twig, vous pouvez toujours faire la même chose en PHP, avec date_format.
Du coup, Datatables va trier votre colonne sur cette valeur, et donc trier correctement. Au lieu d’avoir des jours, des mois, des années, avec des slash entre tout ça, vous n’avez plus qu’un entier.
Méthode 2
Elle est moins facile à mettre en œuvre (mais ce n’est pas dramatique non plus), mais je trouve intéressant de la mentionner, parce qu’elle peut s’adapter à d’autres situations. Cette fois-ci, cela va se jouer dans le javascript. Il faut d’abord y déclarer les fonctions qui vont être utilisées pour le tri :
$.extend( $.fn.dataTableExt.oSort, {
"extract-date-fr-pre": function(value) {
let elementsDate = value.split('/');
return Date.parse(elementsDate[1] + '/' + elementsDate[0] + '/' + elementsDate[2].substring(0,4))
},
"extract-date-fr-asc": function(a, b) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"extract-date-fr-desc": function(a, b) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
La fonction « -pre » permet de créer un objet Date à partir du contenu de la cellule. Ici on découpe sur le slash, et on récupère les morceaux qui nous intéressent. On fait bien attention à ne prendre que les 4 premiers caractères pour l’année. Cela permet d’avoir du contenu après la date dans la cellule. Dans mon cas, j’ai ce genre de contenu dans la cellule :
- 12/10/2022 (Journée complète)
- 14/08/2021 : de 10h à 12H
En coupant sur les slash, le dernier élément contiendra l’année et tout ce qui suit. Donc on ne prend que les 4 premiers caractères pour n’avoir que l’année.
Une fois ces fonctions déclarées, il faut simplement indiquer à Datatables que le type des colonnes est « extract-date-fr » :
$('.table-datatable-date').dataTable({
// Cible les colonnes N°2 et 3 (1 et 2 avec la numérotation à 0)
columnDefs: [
{ type: "extract-date-fr", targets: [1, 2]}
],
order: [[2, 'desc']]
});
Ici, on indique que les colonnes 2 et 3 (la numérotation commence à zéro) sont de ce type-là. Et on indique aussi que l’ordre de tri par défaut sera sur la colonne 3 (numéro 2 du coup), par ordre descendant.
Et voilà. La 2ème technique peut être adaptée pour trier d’autres formats que les dates françaises.
J’espère que ça pourra vous être utile. Pour ma part, j’ai cherché un moment ces infos quand je me suis rendu compte du problème. Voilà 2 liens qui m’ont aidé :
- https://datatables.net/forums/discussion/41076/how-to-sort-table-by-dd-mm-yyyy
- https://codepen.io/michelgefuni/pen/zqyLgG
@+ !
Michaël