Skip to content

Instantly share code, notes, and snippets.

@umidjons
Last active January 2, 2024 20:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save umidjons/9462265 to your computer and use it in GitHub Desktop.
Save umidjons/9462265 to your computer and use it in GitHub Desktop.
Yii: custom button in CGridView with AJAX functionality

#Approve/Unapprove comments

Create approve action in our controller:

<?php
class CommentsController extends Controller
{
	// ...
	public function actionApprove( $id, $oper = NewsComments::STATUS_APPROVED )
	{
		$model = NewsComments::model()->findByPk( $id );
		if ( $model )
		{
			$model->scenario = 'approve';
			$model->status   = $oper; // 0-not published, 1-approved/published
			if ( $model->save() )
				echo CJSON::encode( [ 'code' => 200 ] );
			else
				echo CJSON::encode( $model->getErrors() );
		}
	}
	// ...
}

Allow approve action in accessRules

<?php
class CommentsController extends Controller
{
    // ...
	public function filters()
	{
		return array(
			'accessControl', // perform access control for CRUD operations
			'postOnly + delete, approve', // we only allow approving via POST request
		);
	}
	
	public function accessRules()
	{
		return [
			[
				'allow',
				'actions' => [ 'admin', 'view', 'delete', 'approve' ],
				'roles'   => [ 'siteModerator', ],
			],
			[ 'deny', // deny all users
				'users' => [ '*' ],
			],
		];
	}
    // ...
}

Put CGrigView widget into view:

<?php
$this->widget( 'zii.widgets.grid.CGridView', [
	'id'            => 'news-comments-grid',
	'itemsCssClass' => 'table table-striped table-hover table-condensed',
	'dataProvider'  => $model->search(),
	'filter'        => null,
	'template'      => '{items}{pager}',
	'columns'       => [
		'id',
		'news_id',
		'author_id',
		'author',
		'text',
		'status',
		[
			'class'                => 'CButtonColumn',
			'template'             => '{approve}{unapprove}<br>{view}{delete}', // buttons here...
			'viewButtonLabel'      => '<span class="glyphicon glyphicon-search"></span>&nbsp;', // custom icon
			'viewButtonOptions'    => [ 'title' => 'Details', ], // change hint/tooltip text
			'viewButtonImageUrl'   => false, // disable default image
			'deleteButtonLabel'    => '<span class="glyphicon glyphicon-remove"></span>&nbsp;',
			'deleteButtonOptions'  => [ 'title' => 'Remove', ],
			'deleteButtonImageUrl' => false,
			'deleteConfirmation'   => 'Remove comment?', // confirmation message for delete
			'buttons'              => [ // custom buttons options here...
				'approve'   => [
					'label'   => '<span class="glyphicon glyphicon-ok-sign"></span>&nbsp;',
					'url'     => '[ "approve", "id" => $data->id, ]', // ?r=controller/approve/id/123
					'options' => [
						'title'        => 'Approve',
						'data-confirm' => 'Approve comment?', // custom attribute to hold confirmation message
					],
					'click'   => $approveJs, // JS string which processes AJAX request
				],
				'unapprove' => [
					'label'   => '<span class="glyphicon glyphicon-minus-sign"></span>&nbsp;',
					'url'     => '[ "approve", "id" => $data->id, "oper" => 0 ]', // ?r=controller/approve/id/123/oper/0
					'options' => [
						'title'        => 'Un-Approve',
						'data-confirm' => 'Un-approve comment?', // custom attribute to hold confirmation message
					],
					'click'   => $approveJs, // JS string which processes AJAX request
				],
			],
		],
	],
] ); ?>

Initialize $approveJs variable before CGridView widget:

<?php
$approveJs = 'js:function(__event)
{
	__event.preventDefault(); // disable default action

	var $this = $(this), // link/button
		confirm_message = $this.data("confirm"), // read confirmation message from custom attribute
		url = $this.attr("href"); // read AJAX URL with parameters from HREF attribute on the link

	if(confirm(confirm_message)) // if user confirmed operation, then...
	{
		// perform AJAX request
		$("#news-comments-grid").yiiGridView("update",
		{
			type	: "POST", // importatnt! we only allow POST in filters()
			dataType: "json",
			url		: url,
			success	: function(data)
			{
				console.log("Success:", data);
				$("#news-comments-grid").yiiGridView("update"); // refresh gridview via AJAX
			},
			error	: function(xhr)
			{
				console.log("Error:", xhr);
			}
		});
	}
}';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment