AJAX: problems with cache

Hi,

I’m new with Yii but, even I have been improving a lot, I can’t resolve this problem.

I have a user form to process data from two different tables, Users and Employees (or ‘person’). This form has a select to chose one person. The purpose is when the user selects a Person from the list, automatically it have to change all the data fields corresponding to the person information. To do this I’ve tried to apply the changes with Ajax in the layer where I have all the data of the person. Also I’ve add a new function to get the new data, but my surprise is that Ajax always replaces the layer with a older page on the cache. I think I’ve done all to solve the problem with the cache (cache set to false, include a variable with aleatorial values ​​in each trial, etc.) but nothing.

This is the code in the form:


...

<div class="row">

  <?php echo $form->labelEx($modelUser,'id_personal'); ?>

  <?php echo $form->dropDownList($modelUser,

                                 'id_personal',

                                 CHtml::listData($modelPersonal::model()->findAll(), 'id', 'nom'),

                                 array( 'empty'=>'Sense persona vinculada',

                                        'ajax' => array('type'=>'POST',

                                                        'cache'=>false,

                                                        'url'=>CController::createUrl('user/getPersonalInfo').'?s='.date('YmdHs'),

                                                        'data'=>array('id_user'=>$modelUser->id,

                                                                      'id_persona'=>'js:this.value',

                                                                      'time'=>date('YmdHs')),

                                                        'update'=>'#user-form' )); ?>

                <?php echo $form->error($modelUser,'id_personal'); ?>

        </div>



And the code in the controller:


public function accessRules()

        {

                return array(

                        array(  'allow', // allow admin user to perform 'admin' and 'delete' actions

                                'actions'=>array('index','view','create','update','admin','delete','GetPersonalInfo'),

                                'roles'=>array('Admin'),

                        ),

                        array('deny',  // deny all users

                                'users'=>array('*'),

                        ),

                );

        }

...

public function actionGetPersonalInfo(){


                $id_usuari = $_POST['id_user'];

                $id_personal = $_POST['id_persona'];


                $modelUser=$this->loadModel($id_usuari); //echo $modelUser->id_personal;

                $modelPersonal = $this->loadModel_Personal($id_persona); //echo '<br>'.$modelPersonal->email;


                $modelUser->password = '';

                $modelUser->password2 = '';


                $this->renderPartial('application.views.user._form', array(

                    'modelUser'=>$modelUser,

                    'modelPersonal'=>$modelPersonal,

                ), false, true);

        }

Sems that Ajax not make anithing with actionGetPersonalInfo(), but fails if it isn’t included in the accessRules().

The layer is replaced by a full page of any old framework page, and this happends with no particular browser I’ve tried with several (FF, IE …) Then I understand that is a problem with cache, but I can’t fix it.

Thank you very much for any help or idea,

At least I’ve found the solution :rolleyes:

The error was due to a permissions check that it is done previously every controller action. The new actions don’t pass the control because I’ve not added the permissions to the corresponding role (I use the extension RBAM to Roles, tasks and operations).

This is the function in the controller that checks the permissions for each action:


protected function beforeAction($action){

        	if(Yii::app()->user->checkAccess(ucfirst($this->getId()).':'.ucfirst($this->getAction()->getId()))){

            	return true;

        	}else{

            	Yii::app()->request->redirect(Yii::app()->user->returnUrl);

        	}

  	}

On the other hand, I corrected the problem I had with Ajax when updating the data on the page.

Testing Ajax I realized It was expecting a ‘return true’ at the end of the output of the function called.

The following code shows an example of Ajax application for managing users. It creates a list of users by ‘CGridView’ which is treated as a partial rendering of the view. At the bottom of the list I add a button to clear all selected users via an AJAX function.

I hope this can help you.

User list:




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

	'id'=>'user-grid',

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

    	'filter'=>$modelUser,

    	'columns'=>array(

            	array(

                    	'class'=>'CCheckBoxColumn',

                    	'selectableRows'=>'2', 

                    	'id'=>'chbx',

                    	'value'=>'$data->id',

		),

            	array(

                	'name'=>'id',

                	'value'=>'$data->id',

                	'htmlOptions'=>array('style'=>'text-align: left; width:5%;'),

            	),

		'username',

            	

            	array( 

                    	'name' => 'id_personal',

                    	'value' => '($data->id_personal!="")?  CHtml::value(Personal::model()->find("id=".$data->id_personal),"nom",$data->id_personal):""',

            	),

            	array(

                	'name'=>'Ultim_inici_sessio',

                	'value'=>'(isset($data->Ultim_inici_sessio)  && $data->Ultim_inici_sessio!="")?  date("d-m-Y",strtotime($data->Ultim_inici_sessio)):""',

                	'htmlOptions'=>array('style'=>'text-align: center'),

            	),

            	array(

                	'name'=>'Habilitat',

                	'type'=>'boolean',

                	'value'=>'$data->Habilitat',

                	'htmlOptions'=>array('style'=>'text-align: center; width:5%;'),

            	),

		array(

                	'name'=>'Ldap',

                	'type'=>'boolean',

                	'value'=>'$data->Ldap',

                	'htmlOptions'=>array('style'=>'text-align: center; width:5%;'),

                	'footer' => 'Seleccionats:',

            	),

		array(

                	'class'=>'CButtonColumn',

                	'template'=>'{update}{delete}',

                	'deleteConfirmation'=>"js:'Vols borrar aquest/s usuari/s?'",

                	'footer' => '<a class="deleteall"  title="Esborrar els seleccionats" href="#"  onclick="borrarMultiple();"><img  src="/aplicacions/assets/29f83aa7/gridview/delete.png" alt="Esborrar els  seleccionats" /></a>',

		),

	),

));



Script with AJAX function:




<script type="text/javascript">

	<!--

	$.ajaxSetup({cache: false});//Per fer que no guardi la cache


	function borrarMultiple(){

            	var usuaris = "";

            	var num = 0;

            	$("input[type=checkbox]:checked").each(function(){

                    	usuaris = usuaris +  $(this).val() +  ",";

                    	num++;

            	});

            	

            	if (usuaris.length <= 0){

                    	alert("Si us plau, selecciona els usuaris a borrar.");

                    	return false;

            	}          	

            	var aleatori = Math.random();

            	$.ajax({

       				type: "POST",

       				url: baseUrl+"/user/deleteItems",

       				data: "usuaris="+usuaris+"&a="+aleatori,

       				cache: false,

       				statusCode: { 404:function() { alert('Error 404: No se encuentra la página (archivo)'); } },

       				success: function(result){

                            	$('#user-grid').html(result); //Si la  acción retorna true sustituye el listado por la salida de la función

                    	}

 				});

	}

	-->

</script>



The action to remove the users created in the controller, based on the solution proposed by [size=“2”]liu1084[/size][size=“2”] in his post ‘how to delete items in GGridView(my example)’ :[/size]




public function actionDeleteItems(){


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

                	if(isset($_POST['usuaris']) && $_POST['usuaris']!=''){


                    	$model = new User();

                    	$items = explode(',', rtrim($_POST['usuaris'], ','));

                    	$num_eliminats = 0;

                    	$num_items = 0;


                    	if(!empty($items[0])){

                        	foreach($items as $item){

                                	$sql = 'DELETE from tbl_user WHERE id = :id';

                                	$command = Yii::app()->db->createCommand($sql);

                                	$command->bindValue(':id', $item);

                                	$return = $command->execute();

                                	if ($return == 1) $num_eliminats++;

                                	$num_items++;

                        	}

                    	}

                    	$missatge = "Usuaris esborrats: ".$num_eliminats." de ".$num_items;

                	}else{

                    	$missatge = "No s'ha eliminat cap element.";

                	}


                	$modelUser = new User('search');

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

                	if(isset($_GET['User'])) $modelUser->attributes=$_GET['User'];

                	echo $this->renderPartial('_admin_list', array('modelUser'=>$modelUser,));

                	echo "<br><div class='missatge'>".$missatge."</div>";

                	

                	return true;

            	}else{

                	return false; //Cuando no es una acción ajax

            	}

    	}



Regards,