DataTables : Tri et filtre personnalisés des données

Posté par seiyar81 le 7 avril 2012 | Laisser un commentaire (2)

Un petit moment que je n’ai pas posté de tutoriel ou tout du moins d’articles plus techniques, mais l’occasion s’est présentée lorsque je suis tombé sur un problème avec la librairie DataTables.

Je dis volontairement librairie car aujourd’hui le plugin pour jQuery a tellement évolué qu’on peut le considérer comme une librairie à part entière.

Une des fonctionnalités très pratique et intéressante de DataTables est de permettre l’ajout de de fonctions personnalisées de tri et de filtrage sur les donénes des tableaux.

L’intérêt d’une telle pratique est de pouvoir offrir aux utilisateurs des fonctionnalités avancées de manipulation des données.

Pour commencer voici un exemple tiré permettant d’ajouter un filtrage pour des adresses IP : 

function ip2long (IP) {
 IP = IP.match(/^([1-9]\d*|0[0-7]*|0x[\da-f]+)(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?$/i); // Verify IP format.
 if (!IP) {        return false;
 }
 IP[0] = 0;
 for (i = 1; i < 5; i += 1) {        IP[0] += !! ((IP[i] || '').length);
     IP[i] = parseInt(IP[i]) || 0;
 }
 IP[4 + IP[0]] *= Math.pow(256, 4 - IP[0]);
 if (IP[1] >= IP[5] || IP[2] >= IP[6] || IP[3] >= IP[7] || IP[4] >= IP[8]) {
     return false;    }
 return IP[1] * (IP[0] === 1 || 16777216) + IP[2] * (IP[0] <= 2 || 65536) + IP[3] * (IP[0] <= 3 || 256) + IP[4] * 1;
}

$.fn.dataTableExt.oSort['ip_address-asc'] = function(a, b) {
	var ipA = ip2long(a);
	var ipB = ip2long(b);
	return ((ipA < ipB) ? -1 : ((ipA > ipB) ?  1 : 0));
};

$.fn.dataTableExt.oSort['ip_address-desc'] = function(a, b) {
	var ipA = ip2long(a);
	var ipB = ip2long(b);
	return ((ipA < ipB) ? 1 : ((ipA > ipB) ?  -1 : 0));
};

On a tout d’abord une fonction pour transformer une adresse IP en entier puis deux fonctions pour comparer deux adresses et les trier par ordre ascendant ou descendant.

Une fois ces fonctions ajoutées, il suffit de spécifier le type de données de la colonne lors de la déclaration du tableau :

$('#example').dataTable( {
        "aoColumns": [
             null,
             null,
             null,
             { "sType": "ip_address" },
             null
         ]
} );

Il est donc très simple d’ajouter des fonctions de tri si nos tableaux utilisent des données d’un format un peu exotique.
Plusieurs fonctions sont d’ailleurs disponibles dans la documentation de la librairie.

Si ces fonctions nous permettent d’améliorer le tri des données, on peut également ajouter des fonctionnalités de filtrage.
Imaginons l’exemple suivant : vous disposez d’un tableau listant des factures avec leur état et vous souhaitez filtrer ce tableau en fonction d’une liste de checkbox représentant chacune un état.
A chaque changement d’état d’une de ces checkbox vous souhaitez donc filtrer le tableau.


var etatsCheckbox = new Array("filtre_etat_1", "filtre_etat_2", "filtre_etat_3", "filtre_etat_4", "filtre_etat_5", "filtre_etat_6"); 

var etatsGlobal = null;

$("#filter_etat input").click(function(){
    if($(this).attr("id") != "no_filter_etat") {
	 if(!$(this).is(":checked")) {
               if(getEtatsFiltres().length == 0)
                      $("#no_filter_etat").attr('checked', 'checked');
               }
	       else
		   $("#no_filter_etat").removeAttr('checked');
	 } else if($(this).attr("id") == "no_filter_etat") {
               if(!$(this).is(":checked")) {
                      $("#filtre_etat_1").attr('checked', 'checked');
               } else {
		      for(var i = 0; i < etatsCheckbox .length; i++) {
			$("input[name="+etatsCheckbox [i]+"]").removeAttr("checked");
		      }
               }
         }
	 etatsGlobal = getEtatFiltres();
	 oTable.fnDraw();
});

function getEtatFiltres() {
	var f = new Array();
	if($("#no_filter_etat").is(":checked"))
           return null;
	else {
	   for(var i = 0; i < etatsCheckbox .length; i++) {
		if($("input[name="+etatsCheckbox [i]+"]").is(":checked"))
		      f.push($("input[name="+etatsCk[i]+"]").attr("value"));
	   }
	   return f;
	}
};

On a tout d'abord un tableau avec les id de nos checkbox, un tableau global qui sera utilisé pour le tri, puis une fonction qui a chaque clic va relancer le filtrage du tableau en effectuant quelques contrôles avant (si on coche "no_filter_etat" décocher les autres checkbox ou bien cocher "filtre_etat_1" par défaut) et enfin une fonction pour récupérer les attributs value des checkbox cochées.

Maintenant il ne nous reste plus qu'à ajouter notre fonction à l'API de DataTables :


$.fn.dataTableExt.afnFiltering.push(
	function( oSettings, aData, iDataIndex ) {
		var iColumn = 2; // Numéro de la colonne dans votre tableau
			
		if(etats === null)
			return true;
		
		var iEtat = aData[iColumn];
			
		if(iEtat) {
			if(iEtat.length == 0)
				return false;
			else if(etatsGlobal.indexOf(iEtat) >= 0) {
				return true;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
);

Petite explication : si la colonne ou est définie l'état de la facture est contenue dans notre tableau global etatsGlobal, elle sera affichée, sinon cachée.

C'est donc très simple et à la portée de tout le monde d'ajouter des fonctions de tri et de filtrage, à vos claviers !

Catégorie: Développement Web, Javascript | Laisser un commentaire (2)


2 commentaires pour “DataTables : Tri et filtre personnalisés des données”

Laissez un commentaire