How To Design My Ajax Process. (Refactoring Need - The Webapp Works Well)

Hi.

I need a help in refactoring, or in design :). I did my webapp, it works well/fine. But I still can’t understand well the Ajax process in the Yii.

For example, when I use the $.fn.yiiGridView.update() method, I saw this return by the all webpage and not just with the content of CGridView. It was interesting for me.

But now:

At the index view, I use a CGridView, but without pager!

This is a simple bet game webapp. And at the index.php I view only 10 bet/result on the page, and after 10 seconds I view the next 10 bet/result and again the next 10 result/bet after 10 seconds :), with JavaScript.

The simple process like this:

[list=1]

[*] actionIndex() is called, it renders the index.php (the index.php contains the JS codes the design, but not the CGridView, where the webapp views the results)

[*] index.php rendert the _ajaxIndex.php files content.

[*] The JS code calculate the next 10 result, which will have to view on the webpage.

[*] actionAjaxIndex() is called. This give the refresh content of _ajaxIndex.php

[*] repeat from the 3. again. The JS code calculate again the next 10 resut…

[*]Notice: While the admins insert the results at the admin webpage, the webapp has to show the temporary results. This is why I need to refresh the summary and the round JS variables in the _ajaxIndex.php

[/list]

Controller:





   /**

     * Lists all models.

     */

    public function actionIndex() {

        Yii::app()->language='hu';

        

        $model = new Result('search');

        $model->unsetAttributes();


        if (isset($_GET['Result']))

            $model->attributes = $_GET['Result'];

        

        if (isset($_POST['offset']) && $_POST['offset'] >= 0)

            $model->offset = $_POST['offset'];  

        

        $summary = Result::getCountSavedResults();

        $model->isLimited = true;

        $this->layout='projector'; 

        

        $this->render('index', array('model' => $model, 'summary'=>$summary));

        //$this->actionAjaxIndex();

    }


    /**

     * List all models by Ajax request.

     */    

    public function actionAjaxIndex() {

        Yii::app()->language='hu';

        

        $model = new Result('search');

        $model->unsetAttributes();  // clear any default values


        if (isset($_GET['Result']))

            $model->attributes = $_GET['Result'];

        

        if (isset($_POST['offset']) && $_POST['offset'] >= 0)

            $model->offset = $_POST['offset'];  


        $summary = Result::getCountSavedResults();

        $model->isLimited = true;


        $this->renderPartial('_ajaxIndex', array('model' => $model, 'summary'=>$summary));

    }



I would like to terminate this code repeat in the actionIndex(). But I don’t have any idea how I can do… I tried to call actionAjaxIndex etc. But before I can call the actionAjaxIndex I got PHP errors from Yii. (Summary variable is not exist, etc.)

View - Index.php




<!--<h1><?php echo Yii::t('strings','Results'); ?></h1>-->

<?php 

    echo CHtml::image(Yii::app()->request->baseUrl.'/images/toplista.jpg', "Fogadás");

?>

<script type="text/javascript">

    // Initialize the variables for calculating

    var summary = <?php echo $summary ?>; // get all stored results

    var timeout = 10 * 1000; // in Milliseconds -> multiply with 1000 to use seconds

    var current = 0;

    var turn = 0;

    var rounds = Math.floor(summary / 10);

</script>


<?php $this->renderPartial('_ajaxIndex', array('model'=>$model, 'summary'=>$summary)); ?>


<script type="text/javascript">

    

    // Refresh the CGridView's content in _ajaxIndex.php

    window.setInterval("refresh()", timeout);

    // Get the offset to the search() to set the criteria

    // Increase turn.

    function counter(){

        turn += 1;

        

        if(turn > rounds){

            turn = 0;

        }

        return turn *10;

    }

    

    function refresh() {       

        <?php

        echo CHtml::ajax(array(

                'url'=> CController::createUrl("result/ajaxIndex"),

                'type'=>'post',

                'data'=> array('offset'=>'js: counter()'),

                'replace'=> '#ajax-result-grid',

                ))

        ?>

    }

</script>



View - _ajaxIndex.php




<?php

/* @var $model Result */

?>

<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'ajax-result-grid',

	'dataProvider'=>$model->search(),	

	'columns'=>array(

                array(

                    'header'=>Yii::t('strings','No.'),

                    'value'=> $model->offset.' + $row+1',

                    'htmlOptions'=>array('style'=>'width:50px;'),

                 ),

		array(

                    'header'=>Yii::t('strings','team_name'),

                    'name'=>'team_id',

                    'value'=>'$data->team->name'

                ),

            array(

                    'header'=>Yii::t('strings','value'),

                    'name'=>'value',

                    'value'=>'$data->value'

                ),

				

	),

)); ?>


<script type="text/javascript">

    // This is need while the admins insert the results during this page is run.

    summary = <?php echo $summary ?>;

    rounds = Math.floor(summary / 10);

</script>



Yes, I think I don’t understand clearly the Ajax process in the Yii :rolleyes:

CGridView took a big shortcut in it’s ajax implementation. It was just easier to render same page and cut out one part and replace just the table contents with it.

That’s why I wrote my own CGridView replacement using dataTables.net JS library. There are also other extensions extending CGridView to pass only (json) encoded data in resonse to the ajax call.

When I execute my index action for an ajax request I just skip the rendering part, extract raw data from the grid, encode it and sent back as a response.

Yes, I thought in this way too… the calculate the rounds, offset at the server side, and not at the client side.

Maybe I will try this :)