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 :
[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 :
[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’une labelFunction 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>
En lançant l'aperçu, 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" />
Tester à nouveau l'application, le trie s'applique maintenant bien au résultat de la labelFunction.
Infos
Comment trier une colonne qui utilise une labelFunction ? La solution, la compareFunction.
- Niveau : Débutant
- Catégorie : Flex 3
- Publié le : 21 août 2009
- Dernière Mise à jour : 01 décembre 2010
- Notions abordées :