Adding custom button to grid view in Yii2
Here is a quick guide on how to add, in Yii2, a custom button to GridView’s ActionColumn, with standard or with customised URL.
First, you have to modify buttons
property of your ActionColumn. In Yii 2 we no longer play with putting PHP code into string, that is later eval
‘d because eval
is pure evil, right? :> Instead, you need to write a closure.
The simplest way of writing it, is to copy and modify ActionColumn::initDefaultButtons() method's code
. For example:
'buttons' => [ 'see' => function ($url, $model, $key) { $options = [ 'title' => Yii::t('yii', 'See in frontend'), 'aria-label' => Yii::t('yii', 'See'), 'data-pjax' => '0', ]; return Html::a('<span class="glyphicon glyphicon-asterisk"></span>', $url, $options); } ],
Note, that in above code you don’t have access to buttonOptions
property, just as it is done in ActionColumn::initDefaultButtons() method's code
, and this is generally OK. The buttonOptions
property is for setting options only to default buttons (as docs stands).
You have to care yourself for applying the same options to your custom buttons (if this is needed, because in default implementation, shown here, it isn’t).
You, of course, have to modify template
property, to “tell” GridAction, that it is supposed to render extra custom button. Therefore, the entire code of this column could look like that:
[ 'class' => 'yiigridActionColumn', 'template' => '{view} {update} {delete} {see}', 'contentOptions' => [ 'style' => 'width: 10%; text-align: center;' ], 'buttons' => [ 'see' => function ($url, $model, $key) { $options = [ 'title' => Yii::t('yii', 'See in frontend'), 'aria-label' => Yii::t('yii', 'See'), 'data-pjax' => '0', ]; return Html::a('<span class="glyphicon glyphicon-asterisk"></span>', $url, $options); } ], ],
This, basic, implementation will auto-create URL for your button and it will use button name (see
in this example) as action name and current (or the one set in controller
property) controller to generate URL for each custom button.
Therefore, you’ll end up with something like http://127.0.0.1/appname/web/controller/see?id=1
.
If you need to have really custom URL, pointing out to another controller (but just for this one button), another application or even away to the Internet, you’ll have two options.
One, a bit less professional, is to simply override $url
value, that your custom button’s closure function is fed, with URL generated using other function parameters, like that:
'see' => function ($url, $model, $key) { $options = [ 'title' => Yii::t('yii', 'See in frontend'), 'aria-label' => Yii::t('yii', 'See'), 'data-pjax' => '0', ]; $url = yiihelpersUrl::toRoute(['lab/index', 'id' => $key]); return Html::a('<span class="glyphicon glyphicon-asterisk"></span>', $url, $options); }
The other, a bit professional way, is to modify the urlCreator
property, as it is shown in Kartik’s example from Yii Forum (a bit modified version). And Url::toRoute()
method for generating URLs:
'urlCreator' => function ($action, $model, $key, $index) { if ($action === 'see') { return yiihelpersUrl::toRoute(['lab/index', 'id' => $key]); } else { return Url::toRoute([$action, 'id' => $model->id]); } }
Unfortunately, this example is not working. It only generates URL for custom button, not for default ones.
Sources: