CButtonColumn Ajax Post button?

Hi All,

I need to add a button to my CButtonColumn that calls an action in my controller via AJAX/POST.

This button will simply change a field in a table from unpaid to paid.

I have the following in my view right now.




		array(

			'class'=>'CButtonColumn',

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

			'buttons'=>array(

				'pay'=>array(

					'label'=>'Pay',

					'imageUrl'=>Yii::app()->request->baseUrl.'/images/pay.png',

					'url'=>'Yii::app()->createUrl("commissions/pay", array("rep"=>$data->salesrep_id, "id"=>$data->id))',

				),

			),

		),



But i want to have any editing request done via POST and not GET.

I’ve looked over the forum and Google and haven’t been able to find any clear examples documented.

Any thoughts would be appreciated.

Thanks in advanced!!

Oliver

please look at the admin view generated by gii/giix, then mimic the delete functionality:




jQuery('#user-grid a.delete').live('click',function() {

	if(!confirm('Are you sure you want to delete this item?')) return false;

	var th=this;

	var afterDelete=function(){};

	$.fn.yiiGridView.update('user-grid', {

		type:'POST',

		url:$(this).attr('href'),

		success:function(data) {

			$.fn.yiiGridView.update('user-grid');

			afterDelete(th,true,data);

		},

		error:function(XHR) {

			return afterDelete(th,false,XHR);

		}

	});

	return false;

});






above is generated by gii; you can refer it and do the same thing with your "pay":




  your button config:

   'pay' => array(

    'label'=>'...',     // text label of the button

    'url'=>'...',       // a PHP expression for generating the URL of the button

    'imageUrl'=>'...',  // image URL of the button. If not set or false, a text link is used

    'options'=>array('class'=>'for-pay'), // HTML options for the button tag

    'click'=>'...',     // a JS function to be invoked when the button is clicked

    'visible'=>'...',   // a PHP expression for determining whether the button is visible

   )

  //mimic the delete button here:

  

<script type='text/javascript'>


jQuery('#user-grid a.for-pay').live('click',function() {

	if(!confirm('Are you sure you want to pay for this item?')) return false;

	

	var url = $(this).attr('href');

        //  do your post request here

        $.post(url,function(res){

               

             alert(res);

         });

            


	return false;

});


</script>



@yiqing95 Thank you for your reply. It’s exactly what i needed.

Oliver

@yiqing95 I’m still very new to Yii…where do i find the code you quoted? i tried to find the gii/giix folder but i could not find it in my project files or the base Yii install.

Just figured it out…i used Yii::app()->clientScript->registerScript in my view. now i just need to get the button to run the script.

Ok here’s what i have so far(and it work!!! thanks yiqing95)

In my view i added the following:




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

jQuery('#commissions-grid a.pay').live('click',function() {

        if(!confirm('Are you sure you want to mark this commission as PAID?')) return false;

        

        var url = $(this).attr('href');

        //  do your post request here

        $.post(url,function(res){

             alert(res);

         });

        return false;

});

");



and here’s my CGridView




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

	'id'=>'commissions-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'id',

		'order_id',

		//'salesrep_id',

		'customer_id',

		'commission_total',

		array(

			'name'=>'status',

			'filter'=>array('paid'=>'Paid', 'unpaid'=>'Un-paid'),

		),

		array(

			'class'=>'CButtonColumn',

			'htmlOptions'=>array('width'=>'80px'),

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

			'buttons'=>array(

				'pay'=>array(

					'label'=>'Pay',

					'imageUrl'=>Yii::app()->request->baseUrl.'/images/pay.png',

					'url'=>'Yii::app()->createUrl("commissions/pay", array("rep"=>$data->salesrep_id, "id"=>$data->id))',

					'options'=>array('class'=>'pay'),

					'visible'=>'$data->status == "unpaid"',

				),

			),

		),

	),

)); ?>



And in my controller i have my pay action:




	public function actionPay($id){

		if(Yii::app()->request->isPostRequest)

		{

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

			if($commissions->status !== 'paid'){

				$commissions->status = 'paid';

				if($commissions->save()){

					echo 'Updated';

				}else{

					echo 'Error while paying';

				}

			}

		}else{

			throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

		}

	}



The only bit i’m trying to figure out now is how to refresh/redirect after the ajax request.

I tried both the redirect and refresh methods in my pay action but nothing happened. Does this need to be done via JS ?

Thanks

Oliver

the code i give is html code ,you can viewed it from web browser ,not the admin.php(but is the output from it :D )

refresh:




       $.fn.yiiGridView.update('yourGridIdHere');

      




// do after the ajax success , you see i give you “alert(res);” originally :rolleyes:

   /* use document.reload(true); or location.href = location.href;  <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/laugh.gif' class='bbc_emoticon' alt=':lol:' />   to refresh current whole  page, above is ajax update only refresh partial of page.*/

Perfect!! thanks yiqing95

Oliver

This is far far simpler to do like this, in your CGridView cButtonColumn:




array(

      'class'=>'CButtonColumn',

      'template' => '{mybutton}',

      'buttons'=>array

      (

          'mybutton' => array

          (

              'label' => 'My Funky Button',

              'imageUrl' => 'images/myfunkybutton.png',

              'url' => 'Yii::app()->createUrl("mycontroller/myaction", array("id"=>$data->id))',

              'options' => 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("my-grid")}')

          ),

      ),

     ),



Why you would want it as $_POST is beyond me, its no safer than $_GET… up to you to change accordingly

Great Idea Backslider, i wonder if an array(… is missing after options’ =>

i mean …




array(

      'class'=>'CButtonColumn',

      'template' => '{mybutton}',

      'buttons'=>array

      (

          'mybutton' => array

          (

              'label' => 'My Funky Button',

              'imageUrl' => 'images/myfunkybutton.png',

              'url' => 'Yii::app()->createUrl("mycontroller/myaction", array("id"=>$data->id))',

              'options' => array( 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("my-grid")}') )

          ),

      ),

     ),



Yes, you are correct - bad copy and paste :)

This solves a problem I’m having, thanks! How would you add a confirmation yes/no popup into this ?

[size=“2”]hi friend if in CGridView all cell’s value of column are hide by this property(‘visible’=>’$data->status == “unpaid”’,) then i want to hide the hole column.

can anybody tell how can i do this.[/size]

thanks

Hi,

give a specific id to your column: "myId"

Then, if your using an ajax updat as above:




array(

      'class'=>'CButtonColumn',

      'template' => '{mybutton}',

      'buttons'=>array

      (

          'mybutton' => array

          (

              'label' => 'My Funky Button',

              'imageUrl' => 'images/myfunkybutton.png',

              'url' => 'Yii::app()->createUrl("mycontroller/myaction", array("id"=>$data->id))',

              'options' => 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("my-grid");$("myId").hide();}')

          ),

      ),

     ),



:

just add $("myId").hide() in your succes response.

hi luc

i try this but it only hide the header of column only for a second, later it seen similar to previously.

Why does this work:


        array(

              'class'=>'CButtonColumn',

              'template' => '{inAttack}&nbsp;&nbsp;&nbsp;{isEmpty}',

              'buttons'=>array

              (

                  'inAttack' => array

                  (

                      'label' => 'I Attack this Treassure',

                      'imageUrl'=> Yii::app()->baseUrl.'/images/gicon_attack_small.png',

                      'url'=>'Yii::app()->createUrl("treasures/attack", array("id"=>$data->primaryKey))',

                      'options' => array( 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("treasures-grid")}') ),

                      //'visible'=>'$data->empty<=0',

                  ),

                 

                  'isEmpty' => array

                  (

                      'label' => 'This Treasure is empty',

                      'imageUrl'=> Yii::app()->baseUrl.'/images/icon_treasure1.png',

                      'url'=>'Yii::app()->createUrl("treasures/looted", array("id"=>$data->primaryKey))',

                      'options' => array( 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("treasures-grid")}') ),

                      //'visible'=>'$data->empty<=0', 

                  ),

                  

              ),

             ),

and this doesn’t work:


        array(

              'class'=>'CButtonColumn',

              'template' => '{inAttack}&nbsp;&nbsp;&nbsp;{isEmpty}',

              'buttons'=>array

              (

                  'inAttack' => array

                  (

                      'label' => 'I Attack this Treassure',

                      'imageUrl'=> Yii::app()->baseUrl.'/images/gicon_attack_small.png',

                      'url'=>'Yii::app()->createUrl("treasures/attack", array("id"=>$data->primaryKey))',

                      'options' => array( 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("treasures-grid")}') ),

                      'visible'=>'$data->empty<=0',

                  ),

                 

                  'isEmpty' => array

                  (

                      'label' => 'This Treasure is empty',

                      'imageUrl'=> Yii::app()->baseUrl.'/images/icon_treasure1.png',

                      'url'=>'Yii::app()->createUrl("treasures/looted", array("id"=>$data->primaryKey))',

                      'options' => array( 'ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("treasures-grid")}') ),

                      'visible'=>'$data->empty<=0', 

                  ),

                  

              ),

             ),


array(

      'class'=>'CButtonColumn',

      'template' => '{mybutton}',

      'buttons'=>array

      (

          'mybutton' => array

          (

              'label' => 'My Funky Button',

              'imageUrl' => 'images/myfunkybutton.png',

              'url' => 'Yii::app()->createUrl("mycontroller/myaction", array("id"=>$data->id))',

              'options' => 'ajax' => array('confirm'=>'Yes or No','type' => 'get', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("my-grid")}')

          ),

      ),

     ),



This add a confirmation yes/no popup before ajax call

Hi, I have this one, but I have error exception for getting the controller, like this "Invalid request. Please do not repeat this request again. ".

this is my view :


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

jQuery('#pelanggan-grid a.active').live('click',function() {

        if(!confirm('Are you sure you want to mark this commission as PAID?')) return false;

        var url = $(this).attr('href');

        //  do your post request here

        $.post(url,function(res){

             alert(res);

         });

        return false;

});

");

this is my button :


'template'=>'{active}{inactive}{view}{update}{delete}',

	   'buttons'=>array(

	         'active'=>array(

	                      'label'=>'<div class="col-md-1"><button class="btn btn-success btn-xs"><i class="glyphicon glyphicon-ok"></i></button></div>',

	                      'imageUrl'=>false,

	                      'visible'=> '$data->status == "NonAktif"', // <-- SHOW IF ROW INACTIVE

	                      'url' => 'Yii::app()->createUrl("/pelanggan/active", array("id"=>$data->id_pelanggan))',

              			  //'url'=>'Yii::app()->createUrl("pelanggan/active", array("rep"=>$data->salesrep_id, "id"=>$data->id))',

                         'options' => array( 'ajax' => array('confirm'=>'yes or no ? ','type' => 'post', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("pelanggan-grid")}') ),


              			),


	         'inactive'=>array(

	                        'label'=>'<div class="col-md-1"><button class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-remove"></i></button></div>',

	                        'imageUrl'=>false,

	                        'visible'=> '$data->status == "Aktif"', 

	       					'url' => 'Yii::app()->createUrl("/pelanggan/inactive", array("id"=>$data->id_pelanggan))',

              			  //'url'=>'Yii::app()->createUrl("pelanggan/active", array("rep"=>$data->salesrep_id, "id"=>$data->id))',

                         'options' => array( 'ajax' => array('confirm'=>'yes or no ? ','type' => 'post', 'url'=>'js:$(this).attr("href")', 'success' => 'js:function(data) { $.fn.yiiGridView.update("pelanggan-grid")}') ),

	                ),

and this is my controller :


public function actionActive($id){

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

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

	                    $this->performAjaxValidation($model);

	                    if($model->status !== 'Aktif'){

	                          $model->status = 'Aktif';

	                           if($model->save()){

	                                 $this->redirect(array('admin'));

	                                }else{

	                                 echo 'Error while paying';

	                                }

	                        }

	                }else{

	                      throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

	                }

	}

	public function actionInactive($id){

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

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

	                    $this->performAjaxValidation($model);

	                    if($model->status !== 'NonAktif'){

	                          $model->status = 'NonAktif';

	                           if($model->save()){

	                                 $this->redirect(array('admin'));

	                                }else{

	                                 echo 'Error while paying';

	                                }

	                        }

	                }else{

	                      throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

	                }

	}

what should I do??? pleas help to fix it…