Сохранить значения флажка в Yii gridview pagination

У меня есть gridview, который содержит столбец флажка, а также использует разбиение на страницы. Когда я проверяю некоторые флажки на первой странице и перехожу на вторую страницу и проверяю другую на второй странице, параметры, которые я проверил на первой странице, не сохраняются там. Возможно ли сохранить значения флажка во время разбивки на страницы?

Код для Gridview

$widget = $this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'     => $model->search(),
    'cssFile'          => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
    //'filter' => $model,
    'ajaxUpdate'       => true,
    'enablePagination' => true,
    'columns'          => array(
        array(
            'name'   => 'id',
            'header' => '#',
            'value'  => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
        ),
        array(
            'class'          => 'CCheckBoxColumn',
            'selectableRows' => '2',
            'header' => 'Selected',
        ),
        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)',
        ),
        array(
            'name'   => 'demo',
            'type'   => 'raw',
            'header' => "Select",
            'value'  => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
        ),
    ),
));

Edit:

Расширение для запоминания выбранных параметров в gridview, проверьте эту ссылку Selgridview

Благодаря bool.dev

Ответ 1

Вы можете использовать сеансы/файлы cookie для хранения отмеченных значений. Я не очень уверен, как сделать файлы cookie, поэтому я расскажу вам, как это сделать с сеансами. В частности, пользовательский сеанс, созданный yii.

Теперь, чтобы использовать сеансы, нам нужно передать проверенные (и непроверенные) идентификаторы на контроллер, поэтому мы будем изменять данные, отправляемые контроллеру при каждом обновлении ajax (т.е. между разбивкой по страницам), для этого мы используем beforeAjaxUpdate опция CGridView.

Я также использую CCheckBoxColumn вместо из следующего в вашем кода (конечно, вы можете изменить решение в соответствии с вашими потребностями):

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

Изменения в GridView:

<?php $this->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
            ),
    ),
));
?>

Обратите особое внимание на код beforeAjaxUpdate и CCheckBoxColumn, в beforeAjaxUpdate мы передаем checkedIds как строку csv всех идентификаторов (в данном случае email_ids), которые были отмечены, и uncheckedIds в качестве строки csv из всех непроверенных идентификаторов мы получаем непроверенные поля, вызывая функцию getUncheckeds(), которая следует вкратце. Пожалуйста, обратите внимание на то, что когда я тестировал, я использовал целое число id (моей таблицы) как уникальное поле, а не поле электронной почты.

Функция getUncheckeds() может быть зарегистрирована в любом месте файла вида для 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();
       }
       "
);

В приведенной выше функции обратите внимание на селекторы и each и push.

При этом нам нужно изменить контроллер/действие для этого представления.

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()
}

Чтобы это, оно должно работать сейчас.

Ответ 2

Для разработки этой схемы вам нужно будет знать, что происходит при навигации.

Когда вы переходите на страницу разбиения на страницы, выполняются аякс-вызовы и принимаются новые данные, и они извлекаются из CActive Record или того, что когда-либо было источником данных. Новые данные соответствуют записям базы данных или исходным записям. когда вы вернетесь на предыдущую страницу, снова выполняется вызов Ajax, а контент обновляется, так же, как и в базе данных.

Я считаю, что вы должны сохранять данные проверенных элементов временно и делать их постоянными, если действие выполнено.

Вы можете сделать что-то вроде этого

<script type="text/javascript">
$("input:checkbox").click(function () {
    var thisCheck = $(this);
    if (thisCheck.is (':checked')){
        // do what you want here, the way to access the text is using the
        // $(this) selector. The following code would output pop up message with
        // the selected checkbox text
        $(this).val());
    }
});
</script>

вы можете сохранить временное хранилище где-нибудь

Ответ 3

Также сделайте эту работу в нормальной форме submit:

Я хотел добавить это как комментарий к запросу bool.dev, но у меня пока нет достаточной репутации, чтобы сделать это. Поэтому я должен был дать ему отдельный ответ.

bool.dev, ваш ответ велик, и он работает хорошо, thanx.

Однако, как и предполагалось, он работает только тогда, когда ajax вызывает обновление gridview. У меня есть gridview, являющийся частью формы, поэтому я хотел, чтобы он также работал над нормальным представлением формы, в противном случае флажки снова не загружаются, если в форме есть другие ошибки проверки.

Итак, в добавлении к тому, что вы сделали, я добавил скрытые поля в свою форму, например:

<input type="hidden" name='checkedBox1' id='checkedBox1' value=''>
<input type="hidden" name='uncheckedBox1' id='uncheckedBox1' value=''>

Затем перед отправкой формы моя кнопка sumbit запускает функции getChecked() и getUncheckeds() и сохраняет их результаты в скрытых полях:

if ($('#checkedBox1').length >0)   {$('[name=checkedBox1]').val(getChecked());}
if ($('#uncheckedBox1').length >0) {$('[name=uncheckedBox1]').val(getUncheckeds());}

В контроллере, помимо проверки на $_GET ['checkedIds'], вы также проверяете $_POST ['checkedBox1'] и сохраняете его значения для сеанса так же, как и для $_GET ['checkedIds']., используя ту же самую переменную сеанса.

Сделайте то же самое с $_POST ['uncheckedBox1'].

Это должно работать.