CGridview conditional delete button

2019-06-16 01:58发布

I want the delete button to be active only in certain condition in CGgridView CButtonColumn (or make a custom delete button) e g if user=='admin' or status=='draft'. Any ideas? Thanks!

4条回答
ゆ 、 Hurt°
2楼-- · 2019-06-16 02:17
'visible'=>'$data->status=="draft" || Yii::app()->user->checkAccess("admin")'
查看更多
唯我独甜
3楼-- · 2019-06-16 02:20

You can also use anonymous function if PHP >= 5.3

'visible'=>function($row, $data) {
    return Yii::app()->user->checkAccess('admin') || 'draft' == $data->status;
}
查看更多
够拽才男人
4楼-- · 2019-06-16 02:26

As zuups states in Mukesh post, you have to use single quotes! And user1584901 is right with the answer, in the case the status is a property of the model instance. So,

'visible'=>'$data->status=="draft" || Yii::app()->user->checkAccess("admin")',

is correct. (Explanation at the bottom)

I want to add some interesting things you can do as well. For example, consider a user with assets. In this case I would want to add the delete button only to users that don't have any assets.

In this case, you can make a relation in the user model such as

'haveAssets' = array(self::STAT,'Asset', 'asset_id','select'=>'1')

Which will return 1 if the user has assets, or 0 otherwise. And define the visible parameter as

'visible' => '!$data->haveAssets',

The reason all this works (as asked by 0x7fffffff) is because Yii uses the string defined in visible to apply it to the evaluateExpression function inside the function that render the buttons (renderButton).

From: https://github.com/yiisoft/yii/blob/1.1.14/framework/zii/widgets/grid/CButtonColumn.php line 337

protected function renderButton($id,$button,$row,$data)
    {
            if (isset($button['visible']) && !$this->evaluateExpression($button['visible'],array('row'=>$row,'data'=>$data)))
                      return;

Which is defined in the CComponent class: https://github.com/yiisoft/yii/blob/1.1.14/framework/base/CComponent.php line 607

public function evaluateExpression($_expression_,$_data_=array())
    {
            if(is_string($_expression_))
            {
                    extract($_data_);
                    return eval('return '.$_expression_.';');
            }
            else
            {
                    $_data_[]=$this;
                    return call_user_func_array($_expression_, $_data_);
            }
    }

So basically what happens is that the evaluateExpression function will make available the variables $data (which is the model instance for the row in question) and $row (all this by using the extract function) and evaluate your string expression as php code. So any mention to $data or $row will use the variable already set by the evaluteExpression function in this scope. That's why you can use the respective model instance of the respective row (as $data->status, or $data->haveAssets from the examples). Notice that the string should be a expression that returns a boolean to determine the visibility of the button.

And the reason the strings should be in single quotes is that while using double quotes, php will assume that any string that starts with $ is a variable and will try to replace it with that variable value. Since, in your scope the $data variable is meaningless (or could be defined) it will throw an error or replace it misleadingly. Using single quotes you prevent having this behaviour.

查看更多
啃猪蹄的小仙女
5楼-- · 2019-06-16 02:31

use 'visible' parameter -

 'buttons'=>array
    (
        'delete' => array
        (
            'label'=>'Delete',
            //other params
            'visible'=>!Yii::app()->user->checkAccess('admin'),
        ),
查看更多
登录 后发表回答