How to load content after page rendering

Hi all, I have an application collecting data from several databases and sometimes the data processing is not so fast. So I would separate the page structure from the data rendering: I think this is possible using Ajax but I’m not so strong about it.

The logical structure is quite standard, but the output of view action can be different: a single value or a complex table. Regardless of that, the data reading and processing should start after the page is loaded to user.

Does someone can help me? Thanks

Yes, this can be done using several ajax calls. Every Ajax request should start an controller action which returns single value, or complex HTML form. So normally you put your logic into controller, and rendering in view, but this time, you will return view content as ajax response rather than printing it.

Here are few examples:

[size="4"]Example with HTML response [/size]




public function actionAjaxGetUser($id){

	if(Yii::app()->request->isAjaxRequest()){

		$user = Users::model()->findByPk($id);//Get user

		$this->renderPartial('displayUser',array('user'=>$user));//Render this user using displayUser view file

		Yii::app()->end();//End application

	}

	echo 'Ups you should do ajax request to access this action';

}

[size="4"]Example of controllers action with JSON response [/size]

[size=“2”]Note: If you want to return JSON as AJAX response, then set dataType=‘json’ in ajax call (look below)[/size]




public function actionAjaxGetUserJson($id){

	if(Yii::app()->request->isAjaxRequest()){

		$user = Users::model()->findByPk($id);//Get user

		echo json_encode($user);

		Yii::app()->end();//End application

	}

	echo 'Ups you should do ajax request to access this action';

}

[size="4"]How to make ajax call on front-end[/size]

[size="2"]Note: This ajax call can be encapsulated in any other javascript code[/size]




jQuery.ajax({

            type: 'POST',//You can set GET or POST

            dataType:'json',//Here you define return format. Set html if you will return HTML content, and set json if you will return json format

            url: '<?php echo $this->createAbsoloteUrl('controller/AjaxGetUser'); ?>',//The url of action you want to call

			data:{id:<?php echo $idUser; ?>,otherParameter:'hallo'},//These values can be accessed in controller by typing Yii::app()->request->getParam('id'), Yii::app()->request->getparam('otherParameter')

            success:function(data){//Function that be called upon successful ajax call

       		alert(data);//Print received data

            },

            error:function(a, b, c){//Function that be called upon unsuccessful ajax call

                //console.log(a,b,c);//Use this to print errors or somethign

				alert('Ajax call was not successful');

				

            }

        });

Thanks for answer.

Following you instructions, this is my controller:




    public function actionAjaxView($id) {

        if (Yii::app()->request->isAjaxRequest()) {

            $riepilogo = $this->loadModel($id);

            $riepilogo->elaboraRiepilogo(); // this line does the heavy work

            $this->renderPartial('_riepilogo', array(

                'model' => $riepilogo,

            ));

            Yii::app()->end();

        }

    }


    public function actionView($id) {

        $riepilogo = $this->loadModel($id);


        $this->render('view', array(

            'model' => $riepilogo,

        ));

    }



… and this is my view:




...

if ($model->risultato) { // TRUE if it has done the heavy work

        $this->renderPartial('_riepilogo', array(

            'model' => $model,

        ));

} else {

    echo '<div id="risultato">';

    echo 'wait a moment...';

    echo '</div>';

}

...

Yii::app()->clientScript->registerScript('carica', "

jQuery.ajax({

        type: 'POST',

        dataType: 'html',

        url: '<?php echo Yii::app()->createAbsoluteUrl('riepilogo/ajaxView', array('id' => $model->id)); ?>',

        data: {risultato:<?php echo 'boh'; ?>},

        success: function(data){

            alert(data);

        },

        error: function(a, b, c){

            alert('Ajax call was not successful');

        }

    });

", CClientScript::POS_LOAD);



Calling the view, the page renders correctly without data, but nothing happens more.

Can you help me to find mistake?

Looks like you still need to trigger your client script.

The script starts after page load (due to CClientScript::POS_LOAD); putting a simple "alert" in the script it runs.

There is some mistake in the script I can’t see.

‘<?php echo’ inside php method is not the best idea.




Yii::app()->clientScript->registerScript('carica', "

jQuery.ajax({

        type: 'POST',

        dataType: 'html',

        url: '" . Yii::app()->createAbsoluteUrl('riepilogo/ajaxView', array('id' => $model->id)) . "',

        data: {risultato:'boh'},

        success: function(data){

            alert(data);

        },

        error: function(a, b, c){

            alert('Ajax call was not successful');

        }

    });

", CClientScript::POS_LOAD);



Ok, after a lot of time and thanks to this article, I found the solution.

Controller:




    public function actionAjaxView($id) {

            $riepilogo = $this->loadModel($id);

            $riepilogo->elaboraRiepilogo();

            $this->renderPartial('_riepilogo', array(

                'model' => $riepilogo,

            ), false, true);

            Yii::app()->end();

    }


    public function actionView($id) {

        $riepilogo = $this->loadModel($id);

        $this->render('view', array(

            'model' => $riepilogo,

        ));

    }



View:




...

if ($model->risultato) {

        $this->renderPartial('_riepilogo', array(

            'model' => $model,

        ));

} else {

    echo '<div id="risultato">';

    echo 'data processing, wait a moment...';

    echo '</div>';

}

...

Yii::app()->clientScript->registerScript('carica', "

jQuery.ajax({

        type: 'POST',

        dataType: 'html',

        url: '" . Yii::app()->createUrl('riepilogo/ajaxView', array('id' => $model->id)) . "',

        success: function(data){

            document.getElementById('risultato').innerHTML = data;

        },

        error: function(){

            alert('Error in Ajax call');

        }

    });

", CClientScript::POS_LOAD);



Thanks everybody