lundi 20 juin 2011

CGridView : formater les cellules

Dans un précédent post, nous avons vu comment il est possible de définir ce qui sera affiché dans les colonnes du widget CGridView. Le principe consistait à décrire sous la forme d'un tableau associatif, ce que Yii allait devoir afficher dans une colonne donnée. La valeur du paramètres 'value' en particulier, est évalué par Yii et c'est le résultat de cette évaluation qui est affiché dans la colonne.
C'est bien....
C'est bien mais ça peut devenir vite rébarbatif à écrire surtout si la valeur de la colonne est le résultat d'une expression complexe.. on s’emmêle vite les pinceaux entre les guillemets simples, doubles ... bref, c'est pas la joie. Dans un tel cas, le CGridView permet au développeur de définir une classe spécifique, dédié à la création du contenu d'une colonne, et ça, c'est plus que bien ! La classe CDataColumn (oui, c'est son nom), est utilisée par le CGridView, pour produire les chaînes de caractères qui viendront peupler ses colonnes. Cette classe accepte différents paramètres comme par exemple :

  • header : le titre de la colonne
  • footer : le pied de colonne
  • name : le nom de l'attribut associé à une colonne
  • type : pilote la façon dont le contenu de la colonne sera créé
  • value : une expression PHP dont l'évaluation sera interprétée comme le contenu de la colonne
  • etc ....
Nous avons déjà rencontré ces paramètres, et dans la plupart des cas, nous nous en accommoderons sans problème, mais pour ceux qui en veulent plus, ils ne sont pas suffisant. La solution consiste alors à définir notre propre classe, héritant de CDataColumn, puis d'indiquer au CGridView que c'est cette classe (la notre) qu'il devra utiliser plutôt que la classe de base CDataColumn.

Dans l'exemple suivant, nous avons donc créé notre propre classe afin de prendre en charge la création du contenu d'une colonne, dont le rôle est d'afficher une petite image d'enveloppe ouverte (pour les messages lus) ou fermée (pour les messages non lus) ... oui, il s'agit d'un exemple de boîte à lettres.

<?php
Yii::import('zii.widgets.grid.CDataColumn');

class MessageStatusColumn extends CDataColumn {

   // nous surchargons cette méthode qui est invoquée par le CGridView
   // chaque fois que le contenu d'une cellule doit être créé
   // L'argument $data représente l'instance affichée sur la ligne
   // correspondante.

   public function renderDataCellContent($row,$data)
   {
      $imgPath=Yii::app()->theme->baseUrl.'/images';

      // Bon, c'est juste un exemple, mais en gros le but est de générer
      // un tag image (IMG) en fonction de la valeur renvoyée par la
      // méthode hasBeenReadByUser() .. disponible au niveau du modèle
      // Message (le type de la variable $data)

      echo CHtml::image(
         $imgPath.'/'.($data->hasBeenReadByUser()?
            'email_read.png':
            'email_unread.png'),
         ($data->hasBeenReadByUser()?'':'*'),
         array(
            'title' => ($data->hasBeenReadByUser()?
               'message read':
               'message not read')
         )
      );
   }    
}
?>

D'autre méthodes de la classe CDataColum pourraient aussi être surchargées, mais pour les besoins de cet exemple, restons simples. Maintenant il ne reste plus qu'à déclarer notre CGridView, en précisant bien que c'est notre propre classe (MessageStatusColumn) qu'il convient d'utiliser pour l'affichage de la première colonne.

<?php 

$this->widget('zii.widgets.grid.CGridView', array(
   'id'=>'message-grid',
   'dataProvider'=>$model->search(),
   'columns'=>array(    
       array(
         
         // Ici on défini la classe à utiliser pour
         // afficher cette colonne
         
          'class'=> 'MessageStatusColumn',
          'name' => 'flags',
       ),
   // etc ...


Et le tour est joué !
Pour aller plus loin, les habituels liens :

Aucun commentaire:

Enregistrer un commentaire