Yii2 GridView自定义链接之重写 ActionColumn
最近刚开始用yii2,真是超棒的,但是也有许多不足的地方,今天要说的就是GridView链接问题。
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'username',
'email',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
这是一个最简单的默认 GridView,gii生成的就这样,那么问题来了。
如果用户管理不是独立的控制器,而是在user控制器或者是site控制器下,ActionColumn默认链接却是view, update, delete
但是我想要的却是 user-view, user-update, user-delete 这样的链接,然后我修改了下,代码如下。
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'username',
'email',
[
'class' => 'yii\grid\ActionColumn',
'template' => '{user-view} {user-update} {user-delete}',
],
],
]); ?>
结果,什么都没了,为什么呢?然后我打开 yii\grid\ActionColumn,看了源码,发现他默认只渲染了view, update, delete
如果 {user-view} 这样的标签在按钮组(buttons[])里不存在,就输出空。
所以我们还要添加按钮才行,然后代码就成了这样。
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'username',
'email',
[
'class' => 'yii\grid\ActionColumn',
'template' => '{user-view} {user-update} {user-delete}',
'buttons' = [
// 下面代码来自于 yii\grid\ActionColumn 简单修改了下
'user-view' => function ($url, $model, $key) {
$options = [
'title' => Yii::t('yii', 'View'),
'aria-label' => Yii::t('yii', 'View'),
'data-pjax' => '0',
];
return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url, $options);
},
'user-update' => function ($url, $model, $key) {
$options = [
'title' => Yii::t('yii', 'Update'),
'aria-label' => Yii::t('yii', 'Update'),
'data-pjax' => '0',
];
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, $options);
},
'user-delete' => function ($url, $model, $key) {
$options = [
'title' => Yii::t('yii', 'Delete'),
'aria-label' => Yii::t('yii', 'Delete'),
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'data-method' => 'post',
'data-pjax' => '0',
];
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, $options);
},
]
],
],
]); ?>
这样就OK了,但是代码变的超恶心,这不是我想要的,于是我重写了 yii\grid\ActionColumn 增强了 template 的功能。
类似 'template' => '{url-link:type}' 这样的,这里的 url-link 就是你的链接地址,type就是按钮类型,默认的3类按钮还在。
例如:'template' => '{user-view:view} {user-update:update} {user-del:delete}'
这样地址和样式都可以简单搞定,当然你依然可以自定义按钮,方法跟上面那个一样。
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'username',
'email',
[
'class' => 'backend\components\ActionColumn',
'template' => '{user-view:view} {user-update:update} {user-del:delete} {user-diy-btn:diy}',
'buttons' => [
// 自定义按钮
'diy' => function ($url, $model, $key) {
$options = [
'title' => Yii::t('yii', 'View'),
'aria-label' => Yii::t('yii', 'View'),
'data-pjax' => '0',
];
return Html::a('<span class="glyphicon glyphicon-refresh"></span>', $url, $options);
},
]
],
],
]); ?>
你只要增加一个 diy 类型的按钮就OK了,如果常用的话,你完全可以直接写到 backend\components\ActionColumn 这里面。
效果如下。
这才是理想的状态,好了,下面给出这个 ActionColumn 代码吧。
我是放在 backend\components 目录下,你也可以放在其他你自己喜欢的地方,命名空间改下就OK了。
namespace backend\components; class ActionColumn extends \yii\grid\ActionColumn
{ public $template = '{:view} {:update} {:delete}'; /**
* 重写了标签渲染方法。
* @param mixed $model
* @param mixed $key
* @param int $index
* @return mixed
*/
protected function renderDataCellContent($model, $key, $index)
{
return preg_replace_callback('/\\{([^}]+)\\}/', function ($matches) use ($model, $key, $index) {
list($name, $type) = explode(':', $matches[1].':'); // 得到按钮名和类型 if (!isset($this->buttons[$type])) { // 如果类型不存在 默认为view
$type = 'view';
} if ('' == $name) { // 名称为空,就用类型为名称
$name = $type;
} $url = $this->createUrl($name, $model, $key, $index); return call_user_func($this->buttons[$type], $url, $model, $key);
}, $this->template); }
}
<input type="button" class="btn btn-success" value="点击投票" >
class="am-btn am-btn-secondary am-btn-xs" class="am-icon-search"查看
class="am-btn am-btn-warning am-btn-xs" class="am-icon-edit"修改
btn-warning 黄色 success 绿色
plus 显示加号 ok 显示对号 remove 显示错号 eye-open 显示眼符号
open 显示上传 pencil 显示铅笔 trash 显示删除 refresh 显示刷新
分页显示:
'pagination' =>[
'pagesize' => '3',
]
'pager' => ['activePageCssClass'=>'active','options'=>['class'=>'pagination pagination-default'],],
想在某列td上应用样式。
老写法是这样的
<?= GridView::widget([
'dataProvider' => $dataProvider,
'layout' => "{items}\n{pager}\n{summary}",
'summary' => '<p class="summary">当前显示第{begin} - {end}条,共{totalCount}条。</p>',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'name',
[
// 看这里
'attribute' => 'propertyValuesString',
'format' => 'html',
'value' => function ($model, $key, $index, $column){
return '<div class="limit-width">'. $model->propertyValuesString .'</div>';
}
],
......
这样返回的html,td标签里面会套一层<div class="limit-width"></div>。
如果才能将class应用在td上呢
查了源码之后,可以这样:
<?= GridView::widget([
.......
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'name', // 新增的代码
[
'class' => 'yii\grid\Column',
'contentOptions' => [
'class' => 'limit-width',
],
'header' => '类目下的所有种类',
'content' => function ($model, $key, $index, $column){
return $model->propertyValuesString;
}
],
也就是说。该列我需要用到 yii/grid/Column类。该类有个contentOptions属性。接收匿名函数或数组。数组就是属性名和属性值得键值对。渲染时该列包含一个th和多个td。th内容从header中取,td就是content。
'rowOptions' => function($model, $key, $index, $grid) {
return ['class' => $model->isEnabled ? 'label-green' : 'label-red'];
}
要添加复选框列到[[yii\grid\GridView]],如下添加它到[[yii\grid\GridView::$columns|columns]]配置:
echo
GridView::widget([
'dataProvider'
=>
$dataProvider
,
'columns'
=> [
// ...
[
'class'
=>
'yii\grid\CheckboxColumn'
,
// 在此配置其他属性
],
],
用户可以点击复选框来选择网格的行。被选中的行可调用以下 JavaScript 代码获取:
var
keys = $(
'#grid'
).yiiGridView(
'getSelectedRows'
);
// keys 是键名关联到选中行的数组
数据筛选
要筛选数据,表格视图需要一个模型从过滤的表单取得输入数据,并调整 dataprovider 的查询语句到期望的搜索条件。使用active records的惯例是建立一个搜索模型类继承活动记录类。然后用这个类定义搜索的验证规则和提供 search()
方法来返回 data provider 。
要给 Post
模型添加搜索能力,可以创建 PostSearch
,如下所示:
<?php
namespace
app\models;
use
Yii;
use
yii\base\Model;
use
yii\data\ActiveDataProvider;
class
PostSearch
extends
Post
{
public
function
rules()
{
// 只有在 rules() 的字段才能被搜索
return
[
[[
'id'
],
'integer'
],
[[
'title'
,
'creation_date'
],
'safe'
],
];
}
public
function
scenarios()
{
// bypass 父类实现的scenarios()
return
Model::scenarios();
}
public
function
search(
$params
)
{
$query
= Post::find();
$dataProvider
=
new
ActiveDataProvider([
'query'
=>
$query
,
]);
// 加载搜索表单数据并验证
if
(!(
$this
->load(
$params
) &&
$this
->validate())) {
return
$dataProvider
;
}
// 通过添加过滤器来调整查询语句
$query
->andFilterWhere([
'id'
=>
$this
->id]);
$query
->andFilterWhere([
'like'
,
'title'
,
$this
->name])
->andFilterWhere([
'like'
,
'creation_date'
,
$this
->creation_date]);
return
$dataProvider
;
}
}
你可以在控制器使用这个方法来为表格视图获取 dataProvider :
$searchModel
=
new
PostSearch();
$dataProvider
=
$searchModel
->search(
$_GET
);
return
$this
->render(
'myview'
, [
'dataProvider'
=>
$dataProvider
,
'searchModel'
=>
$searchModel
,
]);
然后在视图将 $dataProvider
和 $searchModel
赋值给表格视图:
echo
GridView::widget([
'dataProvider'
=>
$dataProvider
,
'filterModel'
=>
$searchModel
,
]);
使用模型关系
当使用 GridView 显示活动记录(active records)时,你可能会遇到需要显示关联模型列的数值,比如想显示文章的作者的名字而不是他的 id
。你可以在 columns 里面把这个属性名定义为 author.name
,当 Post
模型存在一个名为 author
的关系并且这个 author 模型拥有一个 name
属性,GridView将能显示作者的名字,不过缺省情况下,排序和过滤没有被启用。你得调整 PostSearch
模型(在最后部分介绍过)来添加这个功能。
为了启用关联列的排序,你得联合(join)这个关联表,并添加排序规则到数据提供器(data provider)的 Sort 组件中:
$query
= Post::find();
$dataProvider
=
new
ActiveDataProvider([
'query'
=>
$query
,
]);
// 连接关联 `author` 表作为 `users` 表的一个关系
// 并设置表别名为 `author`
$query
->joinWith([
'author'
=>
function
(
$query
) {
$query
->from([
'author'
=>
'users'
]); }]);
// 使关联列的排序生效
$dataProvider
->sort->attributes[
'author.name'
] = [
'asc'
=> [
'author.name'
=> SORT_ASC],
'desc'
=> [
'author.name'
=> SORT_DESC],
];
筛选也需要像上面那样调用 joinWith 。也可以定义可搜索特性和规则的列如下:
public
function
attributes()
{
// 添加关联字段到可搜索特性
return
array_merge
(parent::attributes(), [
'author.name'
]);
}
public
function
rules()
{
return
[
[[
'id'
],
'integer'
],
[[
'title'
,
'creation_date'
,
'author.name'
],
'safe'
],
];
}
然后在 search()
方法只须以 $query->andFilterWhere(['LIKE', 'author.name', $this->getAttribute('author.name')]);
添加另一个过滤条件。
Yii2 GridView自定义链接之重写 ActionColumn的更多相关文章
- yii2 GridView常见操作
作者:白狼 出处:http://www.manks.top/article/yii2_gridview 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- 利用yii2 gridview实现批量删除案例[转]
今天仍然继续探讨GridView的问题,昨天有个小伙伴留言说你用gridview给我去掉表头的链接?我想啊想,这用gridview确实不容易实现,至少我没想出来,会的下方可留言.但是呢,这根gridv ...
- 利用yii2 gridview实现批量删除案例
作者:白狼 出处:http://www.manks.top/article/yii2_gridview_deleteall本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- YII2 Gridview
YII2 Gridview 部分使用规则 1.页面显示的时间戳转换 a. [ 'label'=>'创建日期', 'attribute' => 'created_at', 'filter' ...
- yii2 gridview默认排序
Yii2 GridView 使用起来很方便,但是默认排序很是个问题,数据默认按 主键 正序排列 但是在使用过程中,大多数数据默认是 倒序才符合正常思维的. 第一次 的解决方法是在 直接为 Model添 ...
- FastAdmin Bootstrap-Table 自定义搜索的重写提示
Bootstrap-Table 自定义搜索的重写提示 群友询问:这个搜索能自己写么? [群主]Karson-深圳(请勿@) "★找大神-山西 10:59:32 查看原文 [图片] 这个搜索能 ...
- Python中自定义类如果重写了__repr__方法为什么会影响到str的输出?
这是因为Python3中,str的输出是调用类的实例方法__str__来输出,如果__str__方法没有重写,则自动继承object类的__str__方法,而object类的__str__方法是调用_ ...
- yii2 Gridview网格小部件
Gridview 网格小部件 一.特点: 1.是yii中功能最强大的小部件之一: 2.非常适合快速建立系统的管理后台. 3.用 dataProvider 键来指定数据的提供者 4.用 filterMo ...
- gridview自定义表头
gridview为我们提供了丰富的接口,用于满足自定义需求. 通常asp:gridview会根据绑定的列Columns自动生成表头,展现在前台元素. 序号 类别 有时候需要复杂一些的表头. 序号 类别 ...
随机推荐
- 《javascript高级程序设计》 第24章 最佳实践 Best Practices
24.1 可维护性 Maintainability24.1.1 什么是可维护的代码 What Is Maintainable Code?24.1.2 代码约定 Code Conventions 24. ...
- Java的内存回收机制
原文出处: cnblogs-小学徒V 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C ...
- C++继承与派生(原理归纳)
1. C++继承与java不同,java遵循单继承,但java的接口为其不足做了很好的弥补了. C++则是灵活的多,为多继承.即一个C++类可以同时继承N个类的属性. 2. 对于继承方式 : 有三 ...
- Path Sum [LeetCode]
Problem Description: http://oj.leetcode.com/problems/path-sum/ Pretty easy. /** * Definition for bin ...
- memcached 学习 1—— memcached+spring配置
memcached 学习目录: memcached 学习 1—— memcached+spring配置 这几天自己搭建项目环境,解决问题如下: 有关常见的配置这里没有列出,中间遇到的搭建问题比较顺利g ...
- 源码编译Chrome
官网描述 http://www.chromium.org/developers/how-tos/build-instructions-windows 为啥还要写这篇博客 太久没在这里写博客 Chrom ...
- linux sort 命令详解
sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始! 1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按AS ...
- ajax分页2:jquery.pagination +JSON 动态无刷新分页
静态页面: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- 类成员函数作为pthread_create函数参数
from:http://www.cnblogs.com/shijingxiang/articles/5389294.html 近日需要将线程池封装成C++类,类名为Threadpool.在类的成员函数 ...
- pthread_create如何传递两个参数以上的参数
涉及多参数传递给线程的,都需要使用结构体将参数封装后,将结构体指针传给线程 定义一个结构体 struct mypara { var para1;//参数1 var para2;//参数2 } 将这个结 ...