# 数据表格
# 快速入门
ModStart\Grid\Grid
类用于生成基于数据模型的表格,先来个例子,数据库中有 blog
表
CREATE TABLE `blog` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`cover` varchar(200) DEFAULT NULL,
`summary` varchar(200) DEFAULT NULL,
`content` text,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2
3
4
5
6
7
8
9
10
使用下面的代码可以生成 blog
的数据表格。
<?php
namespace App\Admin\Controller;
use Illuminate\Routing\Controller;
use ModStart\Admin\Concern\HasAdminDetail;
use ModStart\Admin\Concern\HasAdminForm;
use ModStart\Admin\Concern\HasAdminGrid;
use ModStart\Detail\Detail;
use ModStart\Form\Form;
use ModStart\Grid\Grid;
use ModStart\Grid\GridFilter;
class BlogController extends Controller
{
// 设置当前 Controller 包含 Grid、Form、Detail 三种特性
use HasAdminGrid;
use HasAdminForm;
use HasAdminDetail;
// 定义当前页面主标题
public $pageTitle = '博客';
public function grid()
{
$grid = Grid::make('blog');
// 定义显示ID列
$grid->id('id', 'ID');
// 定义标题字段,格式为单行文本
$grid->text('title', '标题');
// 定义封面字段,格式为单张图片
$grid->image('cover', '封面');
// 定义摘要字段,格式为多行文本
$grid->textarea('summary', '摘要');
// 定义内容字段,格式为富文本
$grid->richHtml('content', '内容');
// 定义创建时间字段,格式为简单显示
$grid->display('created_at', '创建时间');
// 定义搜索过滤字段
$grid->gridFilter(function (GridFilter $filter) {
// 定义ID可搜索
$filter->eq('id', 'ID');
// 定义标题可模糊查找
$filter->like('title', '标题');
});
// 定义整体增删改查标题为「博客」
$grid->title('博客');
return $grid;
}
public function form()
{
return Form::make('blog', function (Form $form) {
// 定义标题字段,格式为单行文本
$form->text('title', '标题');
// 定义封面字段,格式为单张图片
$form->image('cover', '封面');
// 定义摘要字段,格式为多行文本
$form->textarea('summary', '摘要');
// 定义内容字段,格式为富文本
$form->richHtml('content', '内容');
});
}
public function detail()
{
return Detail::make('blog', function (Detail $detail) {
// 定义显示ID列
$detail->id('id', 'ID');
// 定义标题字段,格式为单行文本
$detail->text('title', '标题');
// 定义封面字段,格式为单张图片
$detail->image('cover', '封面');
// 定义摘要字段,格式为多行文本
$detail->textarea('summary', '摘要');
// 定义内容字段,格式为富文本
$detail->richHtml('content', '内容');
// 定义创建时间字段,格式为简单显示
$detail->display('created_at', '创建时间');
// 定义更新时间字段,格式为简单显示
$detail->display('updated_at', '更新时间');
});
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
定义Routes
<?php
Route::group(
[
'prefix' => env('ADMIN_PATH', '/admin/'),
'middleware' => ['admin.bootstrap', 'admin.auth'],
'namespace' => '\App\Admin\Controller',
], function () {
Route::match(['get', 'post'], 'blog', 'BlogController@index');
Route::match(['get', 'post'], 'blog/add', 'BlogController@add');
Route::match(['get', 'post'], 'blog/edit', 'BlogController@edit');
Route::match(['get', 'post'], 'blog/delete', 'BlogController@delete');
Route::match(['get', 'post'], 'blog/show', 'BlogController@show');
});
2
3
4
5
6
7
8
9
10
11
12
13
# 数据表格仓库
# 使用MySQL表名
使用数据表名称创建数据表格
$grid = Grid::make('blog');
# 使用数据模型类
使用数据模型类来创建数据表格
$grid = Grid::make(Blog::class);
其中 Blog
定义如下
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
protected $table = 'blog';
}
2
3
4
5
6
7
8
9
# 数据仓库筛选 repositoryFilter
使用 RepositoryFilter
可以进行数据源筛选条件的设置
$grid->repositoryFilter(function (RepositoryFilter $filter) {
// 只显示状态为 1 的数据
$filter->where(['status'=>1]);
});
2
3
4
# 列的配置和使用
一个基础列
$grid->display('field','名称');
# 行的配置和使用
数据表格行默认有 3 个操作:编辑
、删除
、查看
,可以通过如下方式关闭。
// 关闭编辑
$grid->canEdit(false);
// 关闭删除
$grid->canDelete(false);
// 关闭查看
$grid->canShow(false);
// 一键关闭编辑、删除、查看
$grid->disableCUD();
2
3
4
5
6
7
8
自定义渲染行操作
$grid->hookItemOperateRendering(function (ItemOperate $itemOperate) {
// 当前行数据
$item = $itemOperate->item();
// 在默认操作之前增加操作
$itemOperate->prepend('<a href="#">其他操作</a>');
// 在默认操作之后增加操作
$itemOperate->push('<a href="#">其他操作</a>');
});
2
3
4
5
6
7
8
不显示操作列
$grid->disableItemOperate();
# 分页大小和分页控制
设置默认分页大小和可选分页
$grid
->defaultPageSize(100) // 设定分页大小
->pageSizes([10, 100, 1000]); // 设定可选分页大小
2
3
# 筛选条件 gridFilter
# 定义表格筛选条件
$grid->gridFilter(function (GridFilter $filter) {
$filter->eq('id', 'ID');
$filter->like('title', '标题');
})
2
3
4
# 筛选条件字段
// 相等-文本
$filter->eq('foo','字段名');
// 相等-下拉选择
// 使用数组
$filter->eq('foo','字段名')->select(['1' => '选项1', '2' => '选项2']);
// 使用枚举类
$filter->eq('foo', '字段名')->select(XxxType::class);
// 使用表里面的值
$filter->eq('foo', '字段名')->selectModel('foo_table', 'id', 'title');
// 不包含(全部选项)
$filter->eq('foo', '字段名')->select(['1' => '选项1', '2' => '选项2'])->field()->optionContainsAll(false);
// 相等-单选
// 使用枚举类
$filter->eq('status', '状态')->radio(XxxStatus::class);
// 相等-开关
$filter->eq('isPublished', '已发布')->switchRadioYesNo();
// 模糊-文本
// 模糊查询
$filter->like('foo','字段名');
// 模糊查询(分词)
$filter->like('foo','字段名')->wordSplit();
// 范围-日期时间
$filter->range('postTime', '时间')->datetime();
// 范围-日期
$filter->range('postTime', '时间')->date();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 数据范围标签 scopeFilter
根据数据范围标签进行数据筛选,列表以多 Tab 形式展示
$grid
->scopeFilter('all', '全部', function (ScopeFilter $filter) {
// 没有任何筛选条件
})
->scopeFilter('male', '男', function (ScopeFilter $filter) {
$filter->where('gender', 'male');
})
->scopeFilter('female', '女', function (ScopeFilter $filter) {
$filter->where('gender', 'female');
})
->scopeDefault('all');
2
3
4
5
6
7
8
9
10
11
# 工具栏配置使用
在右上角工具栏增加操作
// 在右上角增加一个“设置”按钮,并以弹窗形式打开 /path/to/url
$grid->gridOperateAppend('<a href="javascript:;" data-dialog-request="/path/to/url" class="btn btn-primary">设置</a>');
2
# 批量操作配置使用
在批量操作中增加操作
// 在批量操作中增加批量操作按钮
$grid->batchOperatePrepend('<a href="javascript:;" data-custom-batch-xxx class="btn btn-primary">操作</a>');
// 增加批量操作事件绑定
$js = <<<JS
$(document).on("click","[data-custom-batch-xxx]",function(){
console.log("批量操作");
console.log("获取已勾选ID", __grids.get(0).getCheckedIds());
console.log("获取已勾选条目", __grids.get(0).getCheckedItems());
});
JS;
ModStart::script($js);
2
3
4
5
6
7
8
9
10
11
# 数据排序使用
默认按照ID倒序排序,可自定义列表排序
$grid->defaultOrder(['字段', 'asc或desc']);
# 字段使用基础
# 定义字段
$field = $grid->text('field', '名称');
# 字段可排序
定义后在 Grid 顶端会出现上下箭头的可点击实现 正序、倒序、默认 三种排序方式
$field->sortable(true);
# 字段宽度
$field->width(100);
# 自定义渲染
$field->hookRendering(function (AbstractField $field, $item, $index) {
return '<span>自定义内容:'.$item->field.'</span>';
});
2
3
# 列浮动与固定
表格的ID、操作通常会固定在表格的左侧或右侧,可通过如下方式固定字段显示。
// 固定在左侧
$field->gridFixed('left');
// 固定在右侧
$field->gridFixed('right');
2
3
4
# 组件自定义hook
有两种方式修改字段的行为
① 直接继承 ModStart\Field\AbstractField
类,实现以下方法
class XxxField extends \ModStart\Field\AbstractField
{
// 字段值序列化
// 数据从存储系统(如数据库)读取出来,会调用此方法转换为字段 $value 值
public function unserializeValue($value, AbstractField $field)
{
return $value;
}
// 字段值序列化
// 数据提交到存储系统(如数据库)时,会调用此方法转换为存储值
public function serializeValue($value, $model)
{
return $value;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
② 或者也可以在使用时动态的修改方法的行为
// 字段值序列化
$field->hookValueUnserialize(function($value, AbstractField $field){
return $value;
})/
// 字段值序列化
$field->hookValueSerialize(function($value, $model){
return $value;
})
2
3
4
5
6
7
8
# 使用JavaScript操作数据表
所有数据表格操作相关逻辑都在
vendor/modstart/modstart/resources/asset/src/common/gridManager.js
文件。
# 获取数据表格对象
// 获取页面的第一个表格对象
var grid = __grids.get(0)
2
# 获取所有选中的数据
// 获取所有选中的ID
var ids = grid.getCheckedIds()
// 获取所有选中的行数据
var items = grid.getCheckedItems()
2
3
4
# 其他属性
// 数据表格 dom 对象
grid.$lister
// 监听 dom 事件
grid.$lister.on('click','tr[data-index]',function(){
// 可以通过DOM获取相关内容,完成操作
var $tr = $(this);
});
2
3
4
5
6
7
# 字段组件库
# areaChina 中国地区
$grid->areaChina('field', '字段名');
# audio 音频
$grid->audio('field', '字段名');
# captcha 验证码
$grid->captcha('field', '字段名');
# checkbox 多选
$grid->checkbox('field', '名称');
# code 代码
$grid->code('field', '名称');
# color 颜色
$grid->color('field', '字段名');
# currency 货币
$grid->currency('field', '字段名');
# date 日期
$grid->date('field', '字段名');
# datetime 日期时间
$grid->datetime('field', '字段名');
# decimal 小数
$field = $grid->decimal('field', '字段名');
// 是否显示颜色(正数绿色,负数红色)
$field->autoColor(true);
// 是否总是显示正负号
$field->signShow(true);
2
3
4
5
6
# display 显示
// 基础使用
$field = $grid->display('field','名称');
// 显示为链接
$field->asLink(modstart_web_url('doc/{id}'), $openInBlank = true);
2
3
4
5
# file 文件
$grid->file('field', '字段名');
# fileTemp 临时文件
临时路径指上传到临时表 data_temp
中的图片,正式保存时会将临时图片移动到正式表 data
中。
$grid->fileTemp('field', '字段名');
# files 多文件
$grid->files('field', '字段名');
# hidden 隐藏域
$grid->hidden('field', '字段名');
# html HTML
$grid->html('field', '字段名');
# icon 图标
$grid->icon('field', '字段名');
# id ID
$grid->id('field', '字段名');
# image 单张图片
$grid->image('field', '字段名');
# images 多张图片
$grid->images('field', '字段名');
# imagesTemp 多张图片(临时路径)
临时路径指上传到临时表 data_temp
中的图片,正式保存时会将临时图片移动到正式表 data
中。
$grid->imagesTemp('field', '字段名');
# jsonIdItems 条目列表
字段存储的是 JSON 格式的 ID 列表,通过 ID 列表获取对应的条目名称
$grid->jsonIdItems('field', '字段名');
// 条目选择接口
->selectUrl(modstart_admin_url('path/to/select'))
// 指定预览接口
->previewUrl(modstart_admin_url('path/to/preview'))
// 指定条目样式,ITEM_STYLE_TITLE、ITEM_STYLE_COVER_TITLE
->itemStyle(JsonIdItems::ITEM_STYLE_TITLE);
2
3
4
5
6
7
条目选择接口需要返回
{
"code": 0,
"data": {
"records": [
{"id": 1, "title": "选项1", "cover": "http://xxx.com/xxx.jpg"},
{"id": 2, "title": "选项2", "cover": "http://xxx.com/xxx.jpg"}
]
}
}
2
3
4
5
6
7
8
9
条目预览接口接收 ids
参数,该参数使用 ,
分隔的多个ID,返回的数据格式如下
{
"code": 0,
"data": {
"records": [
{"id": 1, "title": "选项1", "cover": "http://xxx.com/xxx.jpg"},
{"id": 2, "title": "选项2", "cover": "http://xxx.com/xxx.jpg"}
]
}
}
2
3
4
5
6
7
8
9
# keyValueList 键值对列表
$grid->keyValueList('field', '字段名');
# link 链接
$grid->link('field', '字段名');
# markdown Markdown
$grid->markdown('field', '字段名');
# multiSelect 下拉多选
$grid->multiSelect('field', '字段名')->options([
'a' => '选项1',
'b' => '选项2',
'c' => '选项3',
]);
2
3
4
5
# number 数字
$field = $grid->number('field', '字段名');
// 是否显示颜色(正数绿色,负数红色)
$field->autoColor(true);
// 是否总是显示正负号
$field->signShow(true);
2
3
4
5
6
# password 密码
$grid->password('field', '字段名');
# percent 百分比
$grid->percent('field', '字段名');
# radio 单选
$grid->radio('field', '字段名');
# richHtml 富文本
$grid->richHtml('field', '字段名');
# select 下拉
// 基础使用
$field = $grid->select('field', '字段名');
// 使用Type作为备选项,XxxType是继承BaseType的类
$field->optionType(XxxType::class);
// 使用数组作为备选项
$field->options(['1' => '选项1', '2' => '选项2']);
// 使用数组作为备选项
$field->optionArray([['id' => 1, 'name' => '选项1'], ['id' => 2, 'name' => '选项2']],'id','name');
// 使用模型作为备选项
$field->optionModel('forum_category','id','title');
// 使用模型作为备选项(简单条件筛选)
$field->optionModel('forum_category','id','title',['xxx'=>'xxx']);
// 使用模型作为备选项,并渲染为树状结构
$field->optionModelTree('forum_category','id','title');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# selectRemote 下拉(远程)
$grid->selectRemote('seriesId', '剧集')
// 指定远程数据源
->server(modstart_admin_url('path/to/select_remote'))
// 显示时查找的数据字段
->viewWithModel(XxxModel::class,'id','title');
2
3
4
5
远程数据源接口需要返回
{
"code": 0,
"data": {
"options": [
{"value": 1, "label": "选项1"},
{"value": 2, "label": "选项2"}
]
}
}
2
3
4
5
6
7
8
9
系统封装好了参数可以直接试用,远程数据源可以直接调用以下方法返回
class XxxController extends Controller
{
public function selectRemote()
{
return SelectRemote::handleModel(XxxModel::class,'id','title');
}
}
2
3
4
5
6
7
# switch 开关
// 基础使用
$field = $grid->switch('field', '字段名');
// 在表格中快速编辑
$field->gridEditable(true);
2
3
4
5
# tags 标签
$grid->tags('field', '名称');
# text 单行文本
$grid->text('field', '名称')
# textarea 多行文本
$grid->textarea('field', '字段名');
# time 时间
$grid->time('field', '字段名');
# tree 树状组件
$grid->tree('field', '名称');
# type 类型
// 基础使用
$field = $grid->type('field', '字段名');
// 在表格中快速编辑
$field->gridEditable(true);
// 定义BaseType,同时指定类型颜色
$field->type(XxxStatus::class, [
XxxStatus::SUCCESS => 'success',
XxxStatus::FAIL => 'danger',
])
2
3
4
5
6
7
8
9
10
# values 多值
$grid->values('field', '字段名');
# video 视频
$grid->video('field', '字段名');
更多内置组件请参照 ModStart\Support\Manager\FieldManager
中的定义