Retain Checkbox values in Yii gridview pagination

后端 未结 3 1468
故里飘歌
故里飘歌 2020-12-30 08:19

I have a gridview which contains a checkbox column and also uses pagination. When I check some checkboxes in the first page and navigate to the second page and check another

3条回答
  •  礼貌的吻别
    2020-12-30 08:28

    You could use sessions/cookies to store the checked values. I'm not very sure how to make cookies work, so i'll tell you how to do it with sessions. Specifically the user session that yii creates.

    Now to use sessions we need to pass the checked (and unchecked) ids to the controller, therefore we'll modify the data being sent to the controller on every ajax update(i.e between paginations), to do this we exploit the beforeAjaxUpdate option of CGridView.

    I'm also using CCheckBoxColumn instead of the following in your code(of course you can modify the solution to suit your own needs):

    array(
         'name' => 'demo',
         'type'=>'raw',
         'header' => "Select",
         'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
    ),
    

    GridView Changes:

    widget('zii.widgets.grid.CGridView', array(
        // added id of grid-view for use with $.fn.yiiGridView.getChecked(containerID,columnID)
        'id'=>'first-grid',
    
        'dataProvider'=>$model->search(),
        'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
    
        // added this piece of code
        'beforeAjaxUpdate'=>'function(id,options){options.data={checkedIds:$.fn.yiiGridView.getChecked("first-grid","someChecks").toString(),
            uncheckedIds:getUncheckeds()};
            return true;}',
    
        'ajaxUpdate'=>true,
        'enablePagination' => true,
        'columns' => array(
                array(
                     'name' => 'id',
                     'header' => '#',
                     'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
                ),
                array(
                     'name' => 'fb_user_id',
                     'header' => 'FaceBook Id',
                     'value' => 'CHtml::encode($data->fb_user_id)',
                ),
                array(
                     'name' => 'first_name',
                     'header' => 'Name',
                     'value' => 'CHtml::encode($data->first_name)',
                ),
                array(
                     'name' => 'email_id',
                     'header' => 'Email',
                     'value' => 'CHtml::encode($data->email_id)',
                ),
    
                /* replaced the following with CCheckBoxColumn
                  array(
                     'name' => 'demo',
                     'type'=>'raw',
                     'header' => "Select",
                     'value' =>'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
                  ),
                */
    
                array(
                     'class' => 'CCheckBoxColumn',
                     'selectableRows' => '2',
                     'header'=>'Selected',
                     'id'=>'someChecks', // need this id for use with $.fn.yiiGridView.getChecked(containerID,columnID)
                     'checked'=>'Yii::app()->user->getState($data->email_id)', // we are using the user session variable to store the checked row values, also considering here that email_ids are unique for your app, it would be best to use any field that is unique in the table
                ),
        ),
    ));
    ?>
    

    Pay special attention to the code for beforeAjaxUpdate and CCheckBoxColumn, in beforeAjaxUpdate we are passing checkedIds as a csv string of all the ids(in this case email_ids) that have been checked and uncheckedIds as a csv string of all the unchecked ids, we get the unchecked boxes by calling a function getUncheckeds(), which follows shortly. Please take note here, that when i was testing i had used an integer id field (of my table) as the unique field, and not an email field.

    The getUncheckeds() function can be registered like this anywhere in the view file for gridview:

    Yii::app()->clientScript->registerScript('getUnchecked', "
           function getUncheckeds(){
                var unch = [];
                /*corrected typo: $('[name^=someChec]') => $('[name^=someChecks]') */
                $('[name^=someChecks]').not(':checked,[name$=all]').each(function(){unch.push($(this).val());});
                return unch.toString();
           }
           "
    );
    

    In the above function pay attention to the selectors and each and push function.

    With that done, we need to modify the controller/action for this view.

    public function actionShowGrid(){
         // some code already existing
         // additional code follows
         if(isset($_GET['checkedIds'])){
              $chkArray=explode(",", $_GET['checkedIds']);
              foreach ($chkArray as $arow){
                   Yii::app()->user->setState($arow,1);
              }
         }
         if(isset($_GET['uncheckedIds'])){
              $unchkArray=explode(",", $_GET['uncheckedIds']);
              foreach ($unchkArray as $arownon){
                   Yii::app()->user->setState($arownon,0);
              }
         }
         // rest of the code namely render()
    }
    

    That's it, it should work now.

提交回复
热议问题