Monday, 20 June 2016

CGridView Multiple rows update , Bulk Update of records in YII

By keeping a simple check box before each record in CGridView we can achieve bulk update of records. User can check the selected records and click on UpdateALL button , this is very useful when multiple records having same data to update. Here in this case we are having File Monitoting System . The Inward section receives more than 200 files daily and in which some files belongs to same section with same PR Number so instead of updating each file and giving the file number and forwarding to section, User can simply select the files and update the selected files at once.




1. To achieve above, first we design the view part. So in the admin view of the main table (here say it      is files) then the path would be >application_folder/protected/views/files/admin.php , Open the
     file in which we have a CGridView defined already

     First note the user about this simple action, the below statements is for that purpose only

   <b><font color="red"> Bulk Update: </font> Select same file number inward list by clicking the    check boxes beside inward numbers and then click new button "Update ALL" give all the     
   required fields and click save </b> 

   Then we need a Button with label "Update ALL" in our view,
   
   <?php
            $baseUrl = Yii::app()->baseUrl;
            $imgpath = $baseUrl.'/images/new.gif';
    ?>
   <div class="row buttons">
    <center>
        <table border='0'><tr>
             <td> <img src="<?php echo $imgpath ?>" /></td>
             <td><?php echo CHtml::button('Update 
                                           ALL',array('name'=>'btnupdateall','class'=>'updateall-button')); ?>
            </td>
         </tr></table>
    </center>
    </div>

   Now we need to register a client script (JQuery script) for the button, Please add the following underlined lines to the script.
 <?php
       Yii::app()->clientScript->registerScript('search', "
        $('.search-button').click(function(){
$('.search-form').toggle();
return false;
      });
      $('.search-form form').submit(function(){
p$('#inward-grid').yiiGridView('update', {
data: $(this).serialize()
});
return false;
      });
      $('.updateall-button').click(function(){
       var atLeastOneIsChecked = $('input[name=\"inward-grid_c0[]\"]:checked').length > 0;
        if (!atLeastOneIsChecked)
        {
                alert('Please select atleast one inward number to Update');
        }
        else if (window.confirm('Are you sure you want to Update ALL the selected inward files?'))
        {
                document.getElementById('inward-search-form').action='index.php?r=inward/updateall';
                document.getElementById('inward-search-form').submit();
        }
      });
      ");
  ?>

and Now in columns of the CGridView  add a check box before the file number field

<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'inward-grid',
'selectableRows'=>2,   // Two means many 0 means none
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
        array(
                    'value'=>'$data->inw_no',
                    'class'=>'CCheckBoxColumn',
                    ),
'inw_no',

Now the check box is added to the gridview.

2. The Action Part:  We have defined the action for the UpdateALL button in our view now we have        to write the action in our controller i.e., inward controller. (note the above highlighted text
      action=index.php?r=inward/updateall)

     ////////////////////////////////// UPDATE ALL ////////////////////////////////////////////////////

     public function actionUpdateall()
    {
   $session=new CHttpSession;
        if (isset($_POST['inward-grid_c0']))
        {
               $session->open();
               $session['sel'] = $_POST['inward-grid_c0'];
        }
       
       // if(isset($_POST['inward-grid_c0']))
        if(isset($session['sel']))
        {
                $upd_inws = $session['sel'];
// $upd_inws = $_POST['inward-grid_c0'];
                $uname=Yii::app()->user->name;
                $baseUrl = Yii::app()->baseUrl;
                $cs = Yii::app()->getClientScript();

                $cs->registerScriptFile($baseUrl.'/js/utility.js');
                $cs->registerScriptFile($baseUrl.'/js/validations.js'); 
                
                /* $model_inw=new Inward;
                $model_inwTrans = new InwTrans; */
                $model = new Inward;
            $cnt=count($_POST);
            $isinw = isset($_POST['Inward']);
                //if(isset($_POST['Inward']))
                
                //if(isset($_POST['Inward']))
                if(isset($_POST['frender']))
                {
                                             
                        $model->attributes=$_POST['Inward'];
                        $valid = true;

                        if(($uname<>'record.collectorate') and 
                                ($model->sec_fno!='' or $model->sec_fno!=null) or 
                                ($model->sec_year!='' or $model->sec_year!=null)){
                                //$model->scenario='PR';
                           if(($model->sec_fno!='')and($model->sec_year!='')){
                            $valid=true;
                           }else{
                            $valid=false;
                           }
                        }
                      
                        if(($uname==='record.collectorate') and $model->clo_yn==='Y'){
                           // $model->scenario='finalization';
                        if(($model->sec_fno!='')and($model->sec_year!='')and($model->nfp!='')
                        and($model->cfp!='')and($model->tot!='')and($model->clo_date!='')and
                        ($model->clo_cat!='')){
                        $valid=true;
                        }else{
                        $valid=false;
                        }
                        }
                            

                           // Dialog::message('Model',"model attributed $model->sec_fno");

                        if($valid){
// Dialog::message('title',"username is $uname");
$curYear= date('Y');
$model->sec_year = $curYear - $model->sec_year;
                               foreach ($upd_inws as $inwno){
                                $umodel = Inward::model()->findByPk($inwno);
                              //  Dialog::message('INFO',"Got Inward number $umodel->inw_no");
                                 if($umodel->updateallFields($model)){
                                        $umodel->save();
                                  }
                               } 
                               $session->close();

// destroys all data registered to a session.
                       //  $session->destroy();
                      //$this->actionAdmin();
                      Dialog::message('INFO', "Records Saved Successfully Click Home button before proceeding");
                               $searchModel=new Inward('search');
                               $searchModel->unsetAttributes();  // clear any default values
  $searchModel->sec_fno=$model->sec_fno;
  $searchModel->sec_year=$model->sec_year;
                      $this->render('admin',array(
    'model'=>$searchModel,
      ));
                        }else{
                       
                          Dialog::message('ERROR', "unable to save Please Enter all the fields");
                       /*  $process = Yii::app()->createController('FirstController'); //create instance of controller
                         $process->test1();  */
                        // InwardController::errorpage();
                           $this->render('errorpage');
                        }

                     
                }else{
               
                 $this->render('updateall',array(
                        'model'=>$model,
                 ));
                }
        }
        else
        {
                //Yii::app()->user->setFlash('error', 'Please select at least one record to Update.');
          Dialog::message('ERROR', "Please select at least one record to Update.");
          $model = new Inward;
               $this->render('admin',array(
   'model'=>$model,
      ));
        }               
    }
////////////////////////////////////////////////////////////////////////////////////////////////////

3. Finally the UpdateAll view has to be created with the fields which are common for the files. ie., in our views/app_folder/updateall.php



//////////////////////////////// updateall.php  ////////////////////////////////////////////////////

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
        'id'=>'inward-form',
        'enableAjaxValidation'=>false,
        'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>

<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<center>
<?php 
     $uname=Yii::app()->user->name;
?>
<table id="withborder" border=0 cellspacing=0 cellpadding=0 bgcolor="lightblue">
<tr><td>
<table border=0 cellspacing=0 cellpadding=0 bgcolor="lightblue">
<div class="row"> <tr><td>
                <?php echo $form->labelEx($model,'PR Number'); ?>
</td><td>
<?php echo $form->textField($model,'sec_fno',array('size'=>8,'maxlength'=>11)); ?>
<?php echo $form->error($model,'Sec. Asst.'); ?>
<?php echo "PR year"; ?>
   <?php  
$curYear= date('Y');
$prevYear = $curYear-5;
   echo $form->dropDownList ($model, 'sec_year', range($curYear,$prevYear), array('prompt'=>'Select Year'));  ?>
  <?php echo $form->error($model,'sub_scode'); ?>
</td>
</tr>
</div>
<?php
    if($uname<>'record.collectorate'){
?>
 <div class="row">
   <tr><td>
                <?php echo $form->labelEx($model,'Forward to --->'); ?>
      </td><td>
 <?php echo $form->dropDownList($model, 'sec_code' , CHtml::listData(Sections::model()->findAll(), 'sec_code', 'sec_name'),
                        array(
                                'prompt'=>'Select Section',
                                'ajax'=> array(
                                'type' => 'POST',
                                'url'=>CController::createUrl('Inward/Sec'),
                                'update'=>'#'.CHtml::activeId($model,'sub_scode'),
                                )
                        )
                    );
        ?>
                <?php echo $form->error($model,'Sec. Asst.'); ?>
          <?php echo "Sec.Asst."; ?>

 <?php echo $form->DropDownList($model,'sub_scode',CHtml::listData(SubSections::model()->findAllByAttributes(array('sec_code'=>$model->sec_code)),'sub_scode','sub_section'),array('prompt'=>'Select Subsection')); ?>
                <?php echo $form->error($model,'sub_scode'); ?>
         </td>
        </tr>
    </div>

 <div class="row">
                <tr>
                <td>
                <?php echo $form->labelEx($model,'File Status'); ?>
                </td>
                <td>
                <?php echo $form->textField($model,'filestatus',array('size'=>50,'maxlength'=>300)); ?>
                            <?php echo $form->error($model,'filestatus'); ?>
                </td>
                </tr>
        </div>


        <div class="row">
                <tr>
                <td>
                <?php echo $form->labelEx($model,'Remarks'); ?>
                </td>
                <td>
                <?php echo $form->textField($model,'sec_rem',array('size'=>50,'maxlength'=>360)); ?>
                            <?php echo $form->error($model,'sec_rem'); ?>
                </td>
                </tr>
        </div>
<?php } ?>
<?php   $tuname=Yii::app()->user->name; ?>

<?php  if($tuname=='record.collectorate') { ?>

<tr>
        <div class="row">
        <td>
<?php echo $form->labelEx($model,'close the file?'); ?> 
</td> <td>
<?php echo $form->dropDownList($model,'clo_yn',
array('N' =>'No', 'Y'=> 'Yes'),
array(
'ajax'=>array(
          'type'=>'POST',
          'url'=>CController::createUrl('Inward/Dis'),
          'update'=>'#description_id',
)));
?>
        </td>
</div>
</tr>

</table>
<table border=0 cellspacing=0 cellpadding=0 bgcolor="lightblue">
<?php $tc=$model->clo_yn; ?>
<tr>
<td>
<div id="description_id">
<?php if($tc=='Y'){ ?>

<?php
echo "<table>";
echo "<tr><td>";
echo "<b>Close type</b>";
echo "</td>";
echo "<td>";
echo $form->dropDownList($model,'clo_cat',array('D'=>'D','L'=>'L','N'=>'N','R'=>'R'),array('prompt'=>'Select Dis'));
echo "</td>";
echo "</tr>";
echo "<tr><td>";
echo "<b>Closing Date <br/> (Year-Mon-Date)</b>";
echo "</td>";
echo "<td>";
 echo $form->textField($model,'clo_date',array('size'=>30,'maxlength'=>30));
echo "</td>";
echo "</tr>";
echo "<tr><td>";
echo "<b>NFP</b>";
echo "</td>";
echo "<td>";
 echo $form->textField($model,'nfp',array('size'=>10,'maxlength'=>10));
echo "</td>";
echo "</tr>";
echo "<tr><td>";
echo "<b>CFP</b>";
echo "</td>";
echo "<td>";
echo $form->textField($model,'cfp',array('size'=>10,'maxlength'=>10));
echo "</td>";
echo "</tr>";
echo "<tr><td>";
echo "<b>Total</b>";
echo "</td>";
echo "<td>";
echo $form->textField($model,'tot',array('size'=>10,'maxlength'=>10));
echo "</td>";
echo "</tr>";
echo "<tr><td>";
echo "<b>Remarks</b>";
echo "</td>";
echo "<td>";
 echo $form->textField($model,'clo_rem',array('size'=>45,'maxlength'=>360));
echo $form->error($model,'clo_rem'); 
echo "</td>";
echo "</tr>";
echo "</table>";
?>

<?php } ?>
</div>
</td>
</tr>
<?php  }
echo CHtml::hiddenField('frender' , '1', array('id' => 'frender'));

 ?>
<?php /// END OF CLOSING IF for RECORD SECTION ?>

        <div class="row buttons">
         <tr>
           <td><td>
           <td align="left">
                <?php echo CHtml::submitButton($model->isNewRecord ? 'Save' : 'Save'); ?>
                <?php // echo CHtml::button('Save',array('submit' => array('inward/updateall'))); ?>
           </td>
        </tr>
        </div>
</table>
</td>
</tr>
</table>

<?php $this->endWidget(); ?>

</div><!-- form -->

</center>

Thats it.. I have done for my example with defined fields, change the fields according to your requirement.

GOOD LUCK!!!