Icones et DataGrid, rafraichissement de données

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

1 problème s'est posé à moi dernièrement :

J'ai une grille de données affichant un jour du mois, par exemple le lundi. la grille est composée des données suivantes :
Name, info, studentid, startdate, onlyRE, status0, replace0, status1, replace1, status2, replace2, ...

les 2 valeurs status et replace qu'on retrouve plusieurs fois correspondent en fait au statut et à la valeur de remplacement pour chaque lundi du mois... donc par exemple si le premier lundi est le 1 jour du mois, on trouvera ensuite le 8, le 15, le 22 et le 29 (si ce n'est pas en février d'une année non-bissextile).
Donc je vais avoir 5 statuts et 5 valeurs de remplacements.

Maintenant, ma grille n'affiche que certaines valeurs, qui correspondent au nom, à l'information, ainsi que les statuts. Les autres valeurs sont supprimées.
Lorsqu'on veut initialiser une grille pour n'afficher que les valeurs qu'on veut, et labeliser les en-têtes, affecter une largeur précise, utiliser un cellRenderer, etc... il est intéressant de créer une méthode "setupGrid ()" qui va nous permettre de faire ce qu'on veut...

Si je reprend mon exemple, avec mon DataSet. Vous avez pu voir les en-têtes. Je vais maintenant dévoiler la méthode. Vous n'en aurez qu'une version statique et basique, car celle que j'utilise vraiment est relativement complexe... :

function setupGrid (dg:mx.controls.DataGrid)
	{
	// force redraw of last column
	dg.size ();
	// set height of rows
	dg.setRowHeight (25);
 
	// declare DataGridColumn variable
	var c:mx.controls.gridclasses.DataGridColumn;
 
	// width of DataGrid : for example, 600px, -20px => scrollBar
	// "name" column
	c = dg.getColumnAt (0);
	c.headerText = "Nom : ";
	c.alignText = "center";
	c.width = 150;
 
	c = dg.getColumnAt (1);
	c.headerText = "Info";
	c.width = 30;
	c.cellRenderer = "IconCellRenderer";
	c ["iconFunction"] = infoIconFunction;
 
	// remove "studentId" column
	dg.removeColumnAt (2);
	// remove "startdate" column
	dg.removeColumnAt (2);
	// remove "onlyRE" column
	dg.removeColumnAt (2);
 
	// vous avez peut-être remarqué que je supprime toujours à l'index 2, et non pas en suivant. 
	// quand vous supprimez une colonne, l'ordre des colonnes est recalculé.
 
	// nbJoursParMois = 4 ou 5... par exemple 4 lundi le mois de septembre 2004
	for (var i:Number = 0; i < nbJoursParMois; i++)
		{
		// formatage de la colonne ("status" + i)
		c = dg.getColumnAt (i + 2);
		c.headerText = "[date du jour du mois]";
		c.width = 400 / nbJoursParMois
		c.cellRenderer = "IconCellRenderer";
		c ["iconFunction"] = statusIconFunction;
 
		// suppression de la colonne ("replace" + i)
		dg.removeColumnAt (i + 3);
		}
	}
 
function statusIconFunction (item:Object, columnName:String):String
	{
	// si c'est les lignes vides du fond, on ressort
	if (item == undefined || columnName == undefined)
		return null;
 
	if (substring (columnName, 0, columnName.length - 1) == "status")
		{
		var status:Number = item [columnName];
		return "iconStatus" + i;
		}
	else
		return null;
	}

Voilà. vous avez un exemple complet avec iconCellRenderer. Il existe d'autres "Rendu de cellule" dont un natif qui est le "labelFunction", et qui permet de formater une valeur selon le contenu.

Pour faire fonctionner le "iconCellRenderer", vous pouvez vous rendre sur le site de phil qui présente de très bon tutoriaux sur l'utilisation des dataGrid, et en français s'il vous plait Smile
Donc vous trouverez chez lui la classe IconCellRenderer et des exemples d'utilisation complets. L'utilisation d'IconCellRenderer pour des rendus sur DataGrid nécessite un clip vide situé dans la bibliothèque et linké vers la classe AS2. Regardez les exemples Wink

Donc, pour en revenir à mon problème du début, je dois donner la possibilité de presser sur un status pour le modifier, et par la même occasion, que le contenu change. d'une icone de couleur X, je passe à une icone de couleur Y. J'ai tout d'abord essayé de passer par le DataSet, histoire de travailler sur un modèle de type pseudo MVC en considérant que le DataSet est le modèle. Alors je m'en vais changer les valeurs dans mon dataSet. La, la valeur est effectivement changée, mais aucun résultat sur la grille...
Je passe ma souris sur la grille, et vla qu'il me la rafraichit (normal me direz vous, les fonction icon, label, redraw et invalidate sont appelées) et cette fois, il m'affiche le contenu correct, en changeant l'icone pour la bonne couleur...
Bon, j'ai bien passé 2 bonnes heures à chercher, pas moyen d'affecter la couleur automatiquement en passant par le DataSet... on dirait que l'event modelChanged n'est pas envoyé à la grille... Qu'importe, j'essaie alors de passer directement par l'édition de l'item de la grille. cette fois, ça fonctionne, la grille est modifiée automatiquement, et mon DataSet également.

Maintenant, il se peut que lorsque je débute un processus d'ajout, ma grille soit vide. J'ajoute donc mon élément, mais là, ma grille est ré-initialisée au format standard, c'est à dire sans icones, avec toutes les colonnes...
Je réfléchis donc à l'implémentation de ma grille, et au final, j'ai du tester, pour chaque phase d'ajout d'un élément, si après l'ajout, le nombre d'items de la grille est égal à 1. Si c'est le cas, c'est que j'ai ajouté un premier élément sur une grille non formatée. je dois donc appeler ma méthode "setupGrid" afin qu'elle soit formatée correctement...

Cette grille est vraiment laborieuse à utiliser... Je vais me pencher rapidement sur les composants de Grant et son équipe, quand ils seront sortis. J'espère néanmoins que mon apprentissage et mes tickets sur le controle DataGrid vous servent également Smile