Tutoriaux /

Trier une colonne avec labelFunction

Niveau : Novice

Les labelFunction permettent de formatter l’affichage d’une donnée dans une DataGridColumn, mais le trie par defaut d’un colonne s’effectue sur le dataField, et pas sur le retour de la labelFunction. Pour effectuer ce trie, vous allez devoir utiliser une compareFunction.

Nous allons commencer par mettre en place une DataGrid affichant une liste de créateurs

1
2
3
4
5
6
7
8
9
10
11
12
[Bindable] 
public var createurs:ArrayCollection = new ArrayCollection([
	{nom:"Cézanne", prenom:"Paul", surnom:null, anneeNaiss:1839, anneeMort:1906, mainAct:"Peinture", nationalites:"fr"},
	{nom:"Picasso", prenom:"Pablo", surnom:null, anneeNaiss:1881, anneeMort:1973, mainAct:"Peinture", nationalites:"fr"},
	{nom:"Duchamp", prenom:"Marcel", surnom:null, anneeNaiss:1887, anneeMort:1968, mainAct:"Artiste", nationalites:"fr"},
	{nom:"Breton", prenom:"André", surnom:null, anneeNaiss:1896, anneeMort:1966, mainAct:"Poéte", nationalites:"fr"},
	{nom:"Calaferte", prenom:"Louis", surnom:null, anneeNaiss:1928, anneeMort:1994, mainAct:"Ecrivain", nationalites:"fr"},
	{nom:"Selby", prenom:"Hubert", surnom:null, anneeNaiss:1928, anneeMort:2004, mainAct:"Ecrivain", nationalites:"us"},
	{nom:"Easton Ellis", prenom:"Bret", surnom:null, anneeNaiss:1964, anneeMort:null, mainAct:"Ecrivain", nationalites:"us"},
	{nom:"Beckett", prenom:"Samuel", surnom:null, anneeNaiss:1906, anneeMort:1989, mainAct:"Dramaturge", nationalites:"ir"},
	{nom:"Joyce", prenom:"James", surnom:null, anneeNaiss:1882, anneeMort:1941, mainAct:"Romancier", nationalites:"ir"}
]);

Comme vous pouvez le voir, la nationalités du créateur se présente sous la forme d’un tag pays : fr, ir, us. Une seconde source de donnée établie une correspondance entre le tag pays, le le pays en toutes lettres

17
18
19
20
21
[Bindable] 
public var nationalites:ArrayCollection = new ArrayCollection([
	{tag:"fr", pays:"France"},
	{tag:"us", pays:"Etats-Unis"}
]);

La colonne d’affichage de notre DataGrid disposera donc d’un label function pour afficher le pays.

/** Recherche dans l'ArrayCollection 'nationalites' un pays
 * ayant une propriétés 'tag' qui correspond à la valeur 
 * présente dans la donnée.
 * @return	String	Pays en toute lettre (ou 'pays inconnue');
 * @param	o:Object	donnée en cours de rendu
 * @param	col:DatagridColumn	Colonne de la DG
 */
private function renduNationalites(o:Object, col:DataGridColumn) :String {
	var dtSource:Array = nationalites.source;
	for each ( var nat:Object in dtSource ){
		if( nat.tag == o[col.dataField] ){
			return nat.pays;
		}
	}
	return "pays inconnu";
}

La DataGrid ressemble à ça pour le moment :

<mx:DataGrid dataProvider="{createurs}" width="100%" height="100%">
	<mx:columns>
		<mx:DataGridColumn headerText="Nom" dataField="nom" />
		<mx:DataGridColumn headerText="Prénom" dataField="nom" />
		<mx:DataGridColumn headerText="Activités" dataField="nom" />
		<mx:DataGridColumn
			headerText="Nationalités" dataField="nationalites" 
			labelFunction="renduNationalites"
		/>
	</mx:columns>
</mx:DataGrid>

Si vous testez la DataGrid, vous pouvez constaté le problème qui se présente pour l’utilisateur en triant la colonne « nationalités », le trie s’applique au datafield… Nous allons donc avoir recourt à une compareFunction

compareFunction

La DataGridColumn dispose d’un propriété de type Function : sortCompareFunction, voici ce que nous dit la documentation : Flex3 reference : sortCompareFunction.

Sa signature est la suivante : mySortCompareFunction(obj1:Object, obj2:Object):int

Dans notre cas, les 2 objets correspondent à un auteur à comparer avec un autre. Dans cette fonction, nous devrons donc appliquer la labelFunction à la donnée avant de faire le test.

/** Force la comparaison sur la chaine retournée par la label function et pas
 * sur la dataField.
 * @return	in	-1,0,1 (voir documentation : 'compareFunction')
 * @param	obj1:object	Données de compraison 1
 * @param	obj2:object	Données de comparaison 2
 */
private function compareNationalites(obj1:Object, obj2:Object) :int {
	var value1:String = colonneNationnalite.labelFunction(obj1, colonneNationnalite);
	var value2:String = colonneNationnalite.labelFunction(obj2, colonneNationnalite);
	if( value1 == value2 ){
		return 0;
	} else if ( value1 > value2 ) {
		return 1;
	} else {
		return -1;
	}
}

Dans l’exemple, notez que j’ai renseigné un ID à la colonne afin d’accéder à la labelFunction via la colonne. Ca facilite ma maintenance du code par la suite.

Il ne reste plus qu’a indiquer à la colonne la sortCompareFunction :

<mx:DataGridColumn id="colonneNationnalite" 
	headerText="Nationalités" dataField="nationalites" 
	labelFunction="renduNationalites"
	sortCompareFunction="compareNationalites"
/>

Ce qui nous donne :

Voilà, j’espère que cet article vous sera utile, cordialement

Pas de commentaire »

Pas encore de commentaire.

Flux RSS des commentaires de cet article. TrackBack URL

Laisser un commentaire