Problem saving content with ajaxButton

Good morning, I’ve been working on an ajaxButton to save a record to my database. A value from this record comes from the selected row of a CGridView, other components works fine, even added an alert on js to verify it was receiving the right value, the one seems right.

However I get no errors or notifications at all, and code seems not to be working at all, cause it doesn’t even returns a data.msg. I’m still a bit confused on ajaxButton structure after reading some wiki and posts, can you give me a hand on what’s wrong please?

here’s the view





<?php


$this->pageTitle=Yii::app()->name . ' - Lista';

$this->breadcrumbs=array('Lista',);


?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(


 						   'id'=>'usuario-form',

						   'enableAjaxValidation'=>true,

                              )); ?>


<h1>Lista</h1>

<p>Amigos actualmente agregados</p>


<?php 


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

                                              'dataProvider'=>$origen_datos,

					      'itemView'=>'_listar',

					     )

	     ); 


?>

<br>

<h1>Agregar amigos</h1>


<?php


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

		  'id'=>'amigos-grid',

		  'selectableRows'=>1,

	          'dataProvider'=>$modelo->busquedaAproximacion(Yii::app()->user->getState('__id')),

		  'filter'=>$modelo,

		  'columns'=>array('nombre','apellido1','apellido2','ciudad_actual'),

			       		        )

	      );


?>


<div class="row buttons">


	<?php echo CHtml::ajaxSubmitButton(


				'Enviar solicitud',

			        'usuario/annadiramigo', array(

				'type'=>'POST',

				data'=>array('id'=>'js:function(){


                                        //just print to make sure it gets the desired value

					 alert($.fn.yiiGridView.getSelection("amigos-grid"));

					 return $.fn.yiiGridView.getSelection("amigos-grid");}'),

		                'success'=>'js:function(data){

				      

                                      if(data.result=="success"){

					do something on success, like redirect

				      }else{

					$("#result").html(data.msg);

				      }

				

                                 }'

				)

			);

?>

	

</div>


<div id="result"></div>


<?php $this->endWidget(); ?>




and controller method to insert







public function actionAnnadirAmigo(){

	

		$modelo = new AmigoPorUsuario;

		 

		$modelo->fkUsuario = Yii::app()->user->getState('__id');

		$modelo->fkUsuario_amigo = $_POST['data']['id'];

		$modelo->solicitud_amigo = true;

		$modelo->save();

				

	}




Thanks in advance

I’m not sure im following your question, but in Your controller action your not returning anything to the view




'success'=>'js:function(data){ //this means the result will be in an array named data

if(data.result=="success"){ //if result variable is success,which it currently isnt since u // havent set it in the controller

                                        do something on success, like redirect

                                      }else{

                                        $("#result").html(data.msg);

                                      }




So what you want to do is, return info from the controller action in a way javascript can understand, for that is json_encode();

So something like this:




if($modelo->save()){

echo CJSON::encode ( array (

                        'status'=>'success', 

			'msg'=>'Saved',		

			));

}else{

echo CJSON::encode ( array (

                        'status'=>'success',

			'msg'=>'failed',		

			));


}



Now u will be able to see "failed" or "Saved"in your #result div.

If you see failed, you know the request to the controller was successfull,but you for some reason couldnt save the data (validation rules,empty values or something like that)

If you see "Saved" all is fine:p

If u dont see anything at all, its something wrong with the request to your controller, lock in firebug console (if u use firefox,else all browsers has something similair) for javascript errors,its a must when working with ajax,else massive headaches will arrive :P

Hi

This wiki offers some help on fixing problems with selecting gridview rows and getting javascript functions to work (see The Ajax).

http://www.yiiframework.com/wiki/323/dynamic-parent-and-child-cgridciew-on-single-view-using-ajax-to-update-child-gridview-via-controller-with-many_many-relation-after-row-in-parent-gridview-was-clicked/

Thank you very much for your answers, I’ve been working a bit after this one and I got this piece of code (I’ll be making corrections on the one I posted before and I’ll add feedback while you read this one since at least I have some debugging options with this one :P)





echo CHtml::button('Enviar solicitud',array('id'=>'btnEnviar','name'=>'btnEnviar'));


Yii::app()->clientScript->registerScript(

                                          'enviarDatos',

                  			  '$("#btnEnviar").click(function(){

					                                     $.ajax({

									             type: "POST",

							                             url: "amigoporusuario/annadiramigo",

										     beforeSend: function(){

										                             alert("bye, going to execute");

	                                                                                         },


                                                                                    complete: function(result){

													alert("just done")

													if(result=="success"){

													     alert("successfully");

                                                                                                             $("#result_here").html(result.msg);

													}else{

													    alert(result.msg);

                                                                                                             $("#result_here").html(result.msg);

 													}

										                       },

										

										     error: function(reason){

													alert("sorry, I failed");

													alert("the reason was: "+reason);

												    },

										    data: "id=" + $.fn.yiiGridView.getSelection("amigos-grid")

										  });

																				

								          })'

				                  );




Sorry for the bad indentation tabs are completely disordered once I paste code here :s

it doesn’t even reaches controller since I’m not getting anything on div result_here, and I get the following alerts

"bye, going to execute"

"sorry, I failed"

"the reason was [object Object]"

"just done"

"undefined"

is there a way to get a more detailed result from result.msg?

just in case here’s the controller method





public function actionAnnadirAmigo(){

	

		$modelo = new AmigoPorUsuario;

		 

		$modelo->fkUsuario = Yii::app()->user->getState('__id');

		$modelo->fkUsuario_amigo = $_POST['id'];

		$modelo->solicitud_amigo = true;

		

		if($modelo->save()){

		

			echo CJSON::encode ( array (

					            'status'=>'success', 

						    'msg'=>'Saved', 

                                                    ));

		}else{

		

			echo CJSON::encode ( array (

                                                     'status'=>'success',

						     'msg'=>'failed',  

                                                   ));


		}

				

	}




You are returning JSON from your controller and you are comparing it to a string. That won’t work.

Instead, you could use




...

    if (result.status == "success") {

        ...

    }

...



And maybe you should specify in the ajax call that the expected result is JSON.

Or you could just use directly success and error instead of complete callback.

Edit: have you seen Sampa’s answer? It also specifies one important detail, the “js:” in all the callbacks.

Sorry for delay was testing the above solutions. Yes, I read Sampa’s post and he was right, headaches were coming :P now I get access to the controller, but the value from selected item in grid view is nos passing correctly, I know it because I tried with a static value before and worked, here’s my actual code

from view





?php echo CHtml::ajaxSubmitButton(


                                'Enviar solicitud',

                                $this->createUrl("amigoporusuario/annadirAmigo"), array(

                                'type'=>'POST',

                                'data'=>array('id'=>'$.fn.yiiGridView.getSelection("amigos-grid")'),

                                'success'=>'js:function(data){

                                      

                                      if(data.result=="success"){

								$("#result_here").html(data.msg);

                                      }else{

                                        $("#result_here").html(data.msg);

                                      }

                                

                                 }',

			       'update'=>'#result_here',

                                )

                        );

?>




controller





$modelo->fkUsuario = 2;

			$modelo->solicitud_amigo = true;

			$modelo->fkUsuario_amigo = $_POST['id'];

			

			echo $_POST['id'];

			

			if($modelo->save()){

			

				echo CJSON::encode ( array (

									'status'=>'success', 

									'msg'=>'Saved',         

									));

			}else{

			

				echo CJSON::encode ( array (

									'status'=>'success',

									'msg'=>'failed',                

									));


			}



I have the feeling I need to convert the value from variable somehow, but I don’t know how at the moment, trying on it while I read the wiki Gerhard Liebenberg posted trying to find out how

Any advice would be greatly appreciated, thank you in advance!

Update: after some time debugging jquery class as I suspected it was taking literally $.fn.yiiGridView.getSelection("amigos-grid") as the value to pass, not the content of the variable

I fixed it setting data type as a script, and returning this property inside a variable so it receives the variable content instead a string with $.fn.yiiGridView.getSelection("amigos-grid") , this way:





<?php echo CHtml::ajaxSubmitButton(


                                'Enviar solicitud',

                                $this->createUrl("amigoporusuario/annadirAmigo"), array(

                                'type'=>'POST',

								'dataType'=>'script',

                                'data'=>array('id'=>'js:function(){

								    var selectedId = $.fn.yiiGridView.getSelection("amigos-grid");

								    return selectedId;

								}'),

                                'success'=>'js:function(data){

                                      

                                      if(data.result=="success"){

                                           $("#result_here").html(data.msg);

                                      }else{

                                          $("#result_here").html(data.msg);

                                      }

                                

                                 }',

				 'update'=>'$("#result_here").html()',

                                )

                        );

?>




The only problem I have now is I don’t know how to refresh data, I tried with $this->refresh() however it crashes I don’t know why :( thank you very much for your help, and if you know how could I refresh the view components would be wonderful :) thank you in advance

You’re using the success property, so why do you also use the update one?

Plus, if you choose update instead of success, it should be just the target div’s id, like this:


'update'=>'#result_here'

Than you for answer, I’m sorry about that mistake I just learned using ajax with JQuery basics today so I’m still feel a bit lost on how functions exactly works, and haven’t been able to refresh the page yet, could anyone give me some input about it?

Thank you very much for your kind help :)