samedi 25 juin 2011

CGridView : effacement de lignes par lot

Décidément, le composant CGridView est à la mode. Après la mise en forme des colonnes et celle des cellules, voici un nouvel article sur ce composant bien utile fourni en standard par le framework Yii.
Aujourd'hui, nous allons voir comment faire pour effacer les lignes que nous aurons coché, puis comment rafraîchir le CGridView sans recharger l'ensemble de la page.

La première étape consiste à initialiser notre CGridView de façon à ce que la première colonne de chaque ligne soit occupée par par une case à cocher....ainsi nous pourrons sélectionner les lignes à effacer. Par chance Yii permet de mettre en place cette configuration très facilement. Deux points sont à retenir :

  1. selectableRows : indique combien de lignes peuvent être sélectionnées. Par défaut cette valeur est à 0 (aucune ligne sélectionnable). A 1, une seule ligne est sélectionnable, et sinon, plusieurs lignes sont sélectionnables.
  2. CCheckBoxColumn : cette classe permet de définir le contenu d'une colonne comme devant être une case à cocher (juste ce qu'il nous faut)
Dans l'exemple suivant nous déclarons donc notre CGridView avec une première colonne contenant notre belle case à cocher. Ce n'est pas suffisant, mais c'est un bon début.

<?php 
   $this->widget('zii.widgets.grid.CGridView', array(
      
      // cet identifiant est important car c'est grâce à lui que
      // nous allons faire référence au CGridView plus tard, depuis
      // les fonctions javascript getSelection() et update()
     
      'id'=>'data-grid',
      'dataProvider'=>$model->search(),

      // ici, on indique que une ou plusieurs colonnes
      // pourront être sélectionnées. La valeur par défaut est 0
      // ce qui indique qu'aucune ligne n'est sélectionnable   

      'selectableRows'=>2,
      'columns'=>array(
          
          // La première colonne est utilisé pour afficher la case à
          // cocher
          
          array(
            'class'=>'CCheckBoxColumn',
          ),
        
          // enfin, les colonnes suivantes contiendront les attributs
          // de notre modèle
  
          'name',
          'address'
      ),
   )); 
?>

La deuxième étape concerne l'effacement à proprement parlé, ainsi que la mise à jour du CGridView. Bien sûr, tout autre traitement par lot est envisageable, mais pour cet exemple, l'utilisateur pourra :

  1. sélectionner une ou plusieurs colonnes
  2. cliquer sur un hyperlien (ajaxLink) pour effacer les colonnes sélectionnées

Lorsque l'utilisateur cliquera sur le lien d'effacement, nous allons collecter toutes les valeurs des cases cochées (qui sont en fait les id des instances affichées), et les envoyer (ajax - POST) vers une action Yii qui sera chargée de les supprimer de la base de données. Cette action renverra le nombre d'éléments effectivement modifiés et si cette valeur n'est pas nulle, le contenu du CGridView sera mis à jour.


<?php
   echo CHtml::ajaxLink("Delete Selected",
   
      // route vers l'action en charge d'effacer les éléments
      // depuis la base de données (voir plus bas pour le code)
      
       $this->createUrl('deleteBulk'),
       array(
      
          "type" => "post",   // POST donc.
         
         // les identifiants des modèles sélectionnées sont accessibles
         // via la méthode $.fn.yiiGridView.getSelection à laquelle
         // on passe l'identifiant du CGridView visé (ici 'data-grid').
         
          "data" => "js:{ids:$.fn.yiiGridView.getSelection('data-grid')}",
         
         // cette fonction javascript traite la réponse renvoyée par
         // l'action 'deleteBulk'. La variable 'data' contient le nombre
         // d'enregistrement supprimés. 
         // La mise à jour du CGridView se fait via la méthode
         // $.fn.yiiGridView.update (à qui on passe l'identifiant du CGridView)
         
          'success'=> 'js:function(data, textStatus, XMLHttpRequest){'.
          'if(data!=0)$.fn.yiiGridView.update("data-grid")}'
       )
    );
   
   // déclarer le CGridView ici...
?>

Toute la magie ajax est possible grâce aux fonctions javascript mise à disposition par le CGridView : getSelection() et update()
Enfin, dernière étape, l'action deleteBulk, qui est appelée (ajax) pour effacer les lignes dont les ids sont  passées dans la requête (POST). Bon, là c'est du classique, tout (trop?) simple pour les besoins de cet exemple.

public function actionDeleteBulk(){
      $modelDeleted=0;
      
      if( Yii::app()->request->isPostRequest && 
         isset($_POST['ids']) && 
         is_array($_POST['ids']))
      {
         foreach ($_POST['ids'] as $modelId){
            $this->loadModel($modelId)->delete();
         }
      }
      echo $modelDeleted;
   }   

Et voilà. Pour conclure, les liens habituels :


1 commentaire: