Question

i have a CGridview which is refreshed at a specific interval. The sorting, filtering and the pagination are all done by ajax and are working great. The problem is that $.fn.yiiGridView.update is updating the grid at a specific interval, due to which the filter, sort, pagination property are getting reset to null and the grid is displaying the 1st page upon each refresh.

This is the view in question, _productDataGrid.php

    <?php

$this->widget('bootstrap.widgets.TbGridView', array(
    'id' => 'realtime-gridAMZ',
    'itemsCssClass' => 'table table-dark table-striped ',
    'htmlOptions' => array(
        'class' => 'product-datagrid',
    ),
    'dataProvider' => $model->search(),
    'filter' => $model,
    'ajaxUpdate' => 'realtime-gridAMZ',
    'ajaxUrl' => Yii::app()->createUrl('realTime/AjaxUpdate'),

    'pager' => array(
        'header' => '',
        'cssFile' => false,
        'maxButtonCount' => 10,
        'selectedPageCssClass' => 'active',
        'hiddenPageCssClass' => 'disabled',
        'firstPageCssClass' => 'previous',
        'lastPageCssClass' => 'next',
        'firstPageLabel' => '<<',
        'lastPageLabel' => '>>',
        'prevPageLabel' => '<',
        'nextPageLabel' => '>',
    ),
    'summaryCssClass' => 'label label-warning',
    'columns' => array(
        'id',
        'name',
        'category',
        'price'
        'rating'


    ),

));
?>

Here is the main index.php view which is displaying the grid initially upon page load.

   <div class="box span12" onTablet="span6" onDesktop="span12">
        <div class="box-header">
            <h2><i class="icon-list"></i><span class="break"></span>AMZ</h2>
            <div class="box-icon">
                <a href="#" class="btn-minimize"><i class="icon-chevron-up"></i></a>
                <a href="#" class="btn-close"><i class="icon-remove"></i></a>
            </div>
        </div>
        <div class="box-content">
            <?php
            $this->renderPartial('//realTime/_productDataGrid', array(
                'model' => new RealTime(),
            ));
            ?>
        </div>        
    </div><!--/span-->
</div>


<?php
 $baseUrl = Yii::app()->baseUrl;
        $cs = Yii::app()->getClientScript();
        $cs->registerScriptFile($baseUrl . '/js/ajaxProductDataUpdate.js');
?>

This is the jquery file which sets the timer and call the grid update function. ajaxProductDataUpdate.js

    function updateAMZGrid() {
    $.fn.yiiGridView.update('realtime-gridAMZ', {
        data: $(this).serialize()
    });
    return false;
}

$(document).ready(function() {
    setInterval(updateAMZGrid, 60000);

});

And lastly here is the actionAjaxUpdate in RealTimeController responsible for the ajax rendering

public function actionAjaxUpdate() {
    $dataProvider = new RealTime();
    $dataProvider->unsetAttributes();

    if (isset($_GET['RealTime']))
        $dataProvider->attributes = $_GET['RealTime'];
    $this->renderPartial('_producDataGrid', array(
        'model' => $dataProvider,
    ));

}

Now, like i mentioned above all the functionality are working as desired. But the filter, sort, paging property is getting reset upon each call to yiiGridViewUpdate. So for example if a user is currently viewing page 24 of the table, after 1 minute the grid will be updated and he will be redirected to the front page of the table or page 1.

Same thing with filter, suppose the user enters a search keyword, and he is viewing the result, again after 1 min he will be seeing the front page or page 1 of the table, and the filter result will be gone. Thus he again have to type in the search keyword in the filter box, after 1 min.

Now, this is a big hindrance for anyone browsing the data through the grid.

Does anyone knows a fix for this? Please let me know what should i do to make it work properly. I'm trying to fix it by trial and error but i'm getting nowhere.

Thanks in advance,

Maxx

Was it helpful?

Solution

Maxx. I took a look at the generated JS-code for grid pager (when grid to be ajax-updated):

jQuery('#assortment-grid').yiiGridView({'ajaxUpdate':['assortment-grid'],'ajaxVar':'ajax','pagerClass':'pager','loadingClass':'grid-view-loading','filterClass':'filters','tableClass':'items','selectableRows':1,'enableHistory':false,'updateSelector':'{page}, {sort}','filterSelector':'{filter}','pageVar':'Assortment_page'});

this very js makes to send ajax request for grid paging like this:

http://srv50213.ht-test.ru/app2/index.php?Assortment[itemSearch]=31351134582, BMW 5 SERIES '85-95 ?28/32/34 FORD MONDEO&Assortment_page=5&ajax=assortment-grid&r=assortment/searchtool

in this uri there are magic parameters:

  • Assortment_page=5 resp. for paging
  • Assortment[itemSearch]=31351134582... and Assortment[subgroup]='ДЕТАЛИ КУЗОВА' - they are responsible for maintaining filtering on server side:

    if (isset($_GET['realtime-gridAMZ'])) $dataProvider->attributes = $_GET['realtime-gridAMZ'];

  • ajax=assortment-grid resp. for indicating ajax call.

Considering these prerequisites, you might try to modify your code to update grid on timer while fetching serialized data. Here you modify some:

 function updateAMZGrid() {
$.fn.yiiGridView.update('realtime-gridAMZ', {
    data: $(this).serialize()
});
return false;
}

you might want to check what data are passed thru $(this).serialize() or add smth. like $('#realtime-gridAMZ').serialize(). How about you check the $_GET['realtime-gridAMZ_page'] and "copy/paste" it into ajax request:

+ '&realtime-gridAMZ_page=' . $_GET['realtime-gridAMZ_page']

thus you fetch current data for repeated requests. In my case it works well with juiAutoComplete without ajax though:

...
'select'=>'js:function(event, ui) {                            
                $(this).val(ui.item.value); 
                location.href= "'. $this->createUrl($this->route) . '&Assortment[itemSearch]=" + ui.item.value + $("#uni-form").serialize() ;   
             }',    

Therefore you might try smth. similar to that:

 function updateAMZGrid() {
$.fn.yiiGridView.update('realtime-gridAMZ', {
    data: $(this).serialize() + $('#realtime-gridAMZ').serialize() + + '&realtime-gridAMZ_page=" . $_GET['realtime-gridAMZ_page'] . " 
});
...
return false;

Also check if GET parameters from XHR request are properly fetched on server side:

`if (isset($_GET['realtime-gridAMZ']))
    $dataProvider->attributes = $_GET['realtime-gridAMZ'];`

why do you have $dataProvider->attributes = $_GET['realtime-gridAMZ'];, i usually get GET/POST parameters into model, rather than into DataProvider:

 `$model->attributes = $_GET['realtime-gridAMZ'];`

and only after that

`$dataProvider = $model->search();`

Hope, this will help you, feel free to ask any questions if not clear. Do not forget gebugging tools: F12 or Ctrl+Shift+I

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top