Dcat Admin 文档 Help

表单字段的使用

model-form中内置了大量的form组件来帮助你快速的构建form表单

公共方法

设置表单值 (value)

$form->text('title')->value('text...');

设置默认值 (default)

$form->text('title')->default('text...');

此方法仅在新增页面有效,如果编辑页面也需要设置默认值,可以参考以下方法

$form->text('xxx')->default('默认值', true);

设置提示信息 (help)

$form->text('title')->help('help...');

设置属性 (attribute)

$form->text('title')->attribute(['data-title' => 'title...']); $form->text('title')->attribute('data-title', 'title...');

设置为必填 (required)

$form->text('title')->required(); // 不显示"*"号 $form->text('title')->required(false);

设置为不可编辑 (disable)

$form->text('title')->disable();

设置占位符 (placeholder)

$form->text('title')->placeholder('请输入。。。');

设置宽度 (width)

$form->text('title')->width(8, 2);

设置验证规则 (rules)

具体使用可参考表单验证

修改待保存的表单输入值 (saving)

通过saving方法可以更改待保存数据的格式。

use Dcat\Admin\Support\Helper; $form->multipleFile('files')->saving(function ($paths) { $paths = Helper::array($paths); // 获取数据库当前行的其他字段 $username = $this->username; // 最终转化为json保存到数据库 return json_encode($paths); });

修改表单数据显示 (customFormat)

通过customFormat方法可以改变从外部注入到表单的字段值。

如下例子中, multipleFile字段要求待渲染的字段值为数组格式,我们可以通过customFormat方法把从数据库查出的字段值转化为array格式

use Dcat\Admin\Support\Helper; $form->multipleFile('files')->saving(function ($paths) { $paths = Helper::array($paths); return json_encode($paths); })->customFormat(function ($paths) { // 获取数据库当前行的其他字段 $username = $this->username; // 转为数组 return Helper::array($paths); });

在弹窗中隐藏

如果不想在弹窗中显示某个字段,可以使用Form\Field::hideInDialog方法

$form->display('id'); $form->text('title'); $form->textarea('contents')->hideInDialog();

保存为字符串类型 saveAsString

saveAsString方法可以把表单值转化为string类型保存,当保存的数据库字段值不允许为null时非常有用;

$form->text('nickname')->saveAsString();

保存为json类型 saveAsJson

saveAsJson可以把表单值保存为json格式

$form->text('nickname')->saveAsJson();

文本 (text)

$form->text($column, [$label]); // 添加提交验证规则 $form->text($column, [$label])->rules('required|min:10');

隐藏字段 (hidden)

通过hidden方法可以给你的表单设置一个隐藏字段。

$form->hidden('author_id')->value(Admin::user()->getKey());

通常可以结合saving事件使用

$form->hidden('author_id'); $form->saving(function (Form $form) { $form->author_id = Admin::user()->getKey(); });

下拉选框单选 (select)

$form->select($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);

或者从api中获取选项列表:

$form->select($column[, $label])->options('/api/users'); // 使用ajax并显示所选项目 $form->select($column[, $label])->options(Model::class)->ajax('/api/users'); // 或指定名称和ID $form->select($column[, $label])->options(Model::class, 'name', 'id')->ajax('/api/users');

其中api接口的格式必须为下面格式:

[ { "id": 9, "text": "xxx" }, { "id": 21, "text": "xxx" }, ... ]

如果选项过多,可通过ajax方式动态分页载入选项:

$form->select('user_id')->options(function ($id) { $user = User::find($id); if ($user) { return [$user->id => $user->name]; } })->ajax('api/users');

使用model方法在編輯時載入資料:

$form->select('user_id')->model(User::class, 'id', 'name');

上面的代碼跟下面這個是一樣的

$form->select('user_id')->options(function ($id) { $user = User::find($id); if ($user) { return [$user->id => $user->name]; } });

API /admin/api/users接口的代码:

public function users(Request $request) { $q = $request->get('q'); return User::where('name', 'like', "%$q%")->paginate(null, ['id', 'name as text']); }

接口返回的数据结构为

{ "total": 4, "per_page": 15, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null, "from": 1, "to": 3, "data": [ { "id": 9, "text": "xxx" }, { "id": 21, "text": "xxx" }, { "id": 42, "text": "xxx" }, { "id": 48, "text": "xxx" } ] }

下拉选框联动 (load)

select组件支持父子关系的单向联动:

$form->select('province')->options(...)->load('city', '/api/city'); $form->select('city');

其中load('city', '/api/city');的意思是,在当前select的选项切换之后,会把当前选项的值通过参数q, 调用接口/api/city ,并把api返回的数据填充为city选择框的选项,其中api/api/city返回的数据格式必须符合:

[ { "id": 9, "text": "xxx" }, { "id": 21, "text": "xxx" }, ... ]

控制器action的代码示例如下:

public function city(Request $request) { $provinceId = $request->get('q'); return ChinaArea::city()->where('parent_id', $provinceId)->get(['id', DB::raw('name as text')]); }

selectTablemultipleSelectTableradiocheckbox也可以使用load方法联动selectmultipleSelect表单,用法和上面的示例一致。

联动多个字段 (loads)

使用loads方法可以联动多个字段,用法如下

$form->select('status') ->options(...) ->loads(['field1', 'field2'], ['/api/field1', '/api/field2']); $form->select('field1'); $form->select('field2');

api返回的数据格式与load方法一致, selectTablemultipleSelectTableradiocheckbox也可以使用loads方法联动。

下拉选框多选 (multipleSelect)

$form->multipleSelect($column[, $label]) ->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']) ->saving(function ($value) { // 转化成json字符串保存到数据库 return json_encode($value); }); // 使用ajax并显示所选项目: $form->multipleSelect($column[, $label])->options(Model::class)->ajax('ajax_url'); // 或指定名称和ID $form->multipleSelect($column[, $label])->options(Model::class, 'name', 'id')->ajax('ajax_url');

多选框可以处理两种情况,第一种是ManyToMany的关系。

class Post extends Models { public function tags() { return $this->belongsToMany(Tag::class); } } return Form::make(Post::with('tags'), function (Form $form) { ... $form->multipleSelect('tags') ->options(Tag::all()->pluck('name', 'id')) ->customFormat(function ($v) { if (! $v) { return []; } // 从数据库中查出的二维数组中转化成ID return array_column($v, 'id'); }); });

第二种是将选项数组存储到单字段中,如果字段是字符串类型,那就需要在模型里面为该字段定义访问器和修改器来存储和读取了。

如果选项过多,可通过ajax方式动态分页载入选项:

$form->select('friends')->options(function ($ids) { return User::find($ids)->pluck('name', 'id'); })->ajax('api/users');

API /admin/api/users接口的代码:

public function users(Request $request) { $q = $request->get('q'); return User::where('name', 'like', "%$q%")->paginate(null, ['id', 'name as text']); }

接口返回的数据结构为

{ "total": 4, "per_page": 15, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null, "from": 1, "to": 3, "data": [ { "id": 9, "text": "xxx" }, { "id": 21, "text": "xxx" }, { "id": 42, "text": "xxx" }, { "id": 48, "text": "xxx" } ] }

表格选择器 (selectTable)

use App\Admin\Renderable\UserTable; use Dcat\Admin\Models\Administrator; $form->selectTable($field) ->title('弹窗标题') ->dialogWidth('50%') // 弹窗宽度,默认 800px ->from(UserTable::make(['id' => $form->getKey()])) // 设置渲染类实例,并传递自定义参数 ->model(Administrator::class, 'id', 'name'); // 设置编辑数据显示 // 上面的代码等同于 $form->selectTable($field) ->from(UserTable::make(['id' => $form->getKey()])) // 设置渲染类实例,并传递自定义参数 ->options(function ($v) { // 设置编辑数据显示 if (! $v) { return []; } return Administrator::find($v)->pluck('name', 'id'); });

定义渲染类如下,需要继承Dcat\Admin\Grid\LazyRenderable

<?php namespace App\Admin\Renderable; use Dcat\Admin\Grid; use Dcat\Admin\Grid\LazyRenderable; use Dcat\Admin\Models\Administrator; class UserTable extends LazyRenderable { public function grid(): Grid { // 获取外部传递的参数 $id = $this->id; return Grid::make(Administrator::where('xxx_id', $id), function (Grid $grid) { $grid->column('id'); $grid->column('username'); $grid->column('name'); $grid->column('created_at'); $grid->column('updated_at'); $grid->quickSearch(['id', 'username', 'name']); $grid->paginate(10); $grid->disableActions(); $grid->filter(function (Grid\Filter $filter) { $filter->like('username')->width(4); $filter->like('name')->width(4); }); }); } }

效果

P5h z xiq aj9

设置选中后将保存到表单的字段和显示的字段

$form->selectTable($field) ->from(UserTable::make(['id' => $form->getKey()])) ->options(function ($v) { // 设置编辑数据显示 if (! $v) { return []; } return Administrator::find($v)->pluck('name', 'id'); }) ->pluck('name', 'id'); // 第一个参数为显示的字段,第二个参数为选中后将保存到表单的字段 // 上面的代码也可以简化为 $form->selectTable($field) ->from(UserTable::make(['id' => $form->getKey()])) ->model(Administrator::class, 'id', 'name'); // 设置编辑数据显示

多选 (multipleSelectTable)

多选的用法与上述selectTable方法一致

$form->multipleSelectTable($field) ->max(10) // 最多选择 10 个选项,不传则不限制 ->from(UserTable::make(['id' => $form->getKey()])) // 设置渲染类实例,并传递自定义参数 ->model(Administrator::class, 'id', 'name') // 设置编辑数据显示 ->saving(function ($v) { // $v 是表单提交的字段值,默认是数组类型,这里需要手动转换一下 // 保存为以 "," 隔开的字符串,如果是多对多关联关系,则不需要转换。 return implode(',', $v); });

多选盒 (listbox)

使用方法和multipleSelect类似。

$form->listbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);

长文本 (textarea)

$form->textarea($column[, $label])->rows(10);

单选 (radio)

$form->radio($column[, $label])->options(['m' => 'Female', 'f'=> 'Male'])->default('m');

多选 (checkbox)

options()方法用来设置选择项:

$form->checkbox($column[, $label]) ->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']) ->saving(function ($value) { // 转化成json字符串保存到数据库 return json_encode($value); });

启用选中全部功能

$form->checkbox('column')->canCheckAll();

autocomplete

此表单可以在填写表单时进行对表单值进行搜索,并把结果展示在下拉列表中,用法如下

$form->autocomplete($column[, $label])->options(['foo', 'bar', ...]); // 设置分组名称 $form->autocomplete($column[, $label])->groups([ [ 'label' => 'group name', 'options' => ['foo', 'bar', ...], ], ]);

效果如下 Ar vn sv chag

从远程API获取数据

也可以从远程API中获取数据

// ajax 函数的第一个参数为 ajax url, 第二个参数为 valueField(可选), 第三个参数为 groupField(可选) $form->autocomplete($column[, $label])->ajax('/countries', 'name', 'region');

远程API 服务端的请求参数为query,示例代码如下:

class CountryController extends AdminController { public function search() { $countries = Country::when(request('query'), function ($query, $value) { $query->where('name', 'like', "%{$value}%"); })->get(); return Admin::json($countries->toArray()); } }

自定义 autocomplete 的设置:

详细设置请参考: devbridge/jQuery-Autocomplete

$js = <<<JS function (suggestion) { alert('You selected: ' + suggestion.value + ', ' + suggestion.data); } JS; $form->autocomplete($column[, $label])->configs([ 'minChars' => 5, 'noCache' => true, 'onSelect' => JavaScript::make($js), ]);

configs 同样也支持闭包:

$form->autocomplete($column[, $label])->configs(function($model, $value){ return [ .... ]; });

表单联动

autocomplete 的联动逻辑和select的刚好相反。 depends 需要写在受影响的字段,不限上级字段类型,上级字段的值将同时上传到API。

$form->select('region')->options([ 'asia', 'Africa', 'America', 'Europe', ]); $form->autocomplete('country')->ajax('/countries', 'name', 'region'); // 将会发出 /states?query={query}&region={region}&country={country} 的请求 $form->autocomplete('addr')->ajax('/states', 'name')->depends(['region', 'country']);

邮箱 (email)

$form->email($column[, $label]);

密码 (password)

$form->password($column[, $label]);

链接 (url)

$form->url($column[, $label]);

IP地址 (ip)

$form->ip($column[, $label]);

手机 (mobile)

$form->mobile($column[, $label])->options(['mask' => '999 9999 9999']);

颜色选择器 (color)

$form->color($column[, $label]);

时间 (time)

$form->time($column[, $label]); // 设置时间格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form->time($column[, $label])->format('HH:mm:ss');

日期 (date)

$form->date($column[, $label]); // 设置日期格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form->date($column[, $label])->format('YYYY-MM-DD');

时间日期 (datetime)

$form->datetime($column[, $label]); // 设置日期格式,更多格式参考http://momentjs.com/docs/#/displaying/format/ $form->datetime($column[, $label])->format('YYYY-MM-DD HH:mm:ss');

时间范围 (timeRange)

$startTime$endTime为开始和结束时间字段:

$form->timeRange($startTime, $endTime, 'Time Range');

日期范围 (dateRange)

$startDate$endDate为开始和结束日期字段:

$form->dateRange($startDate, $endDate, 'Date Range');

时间日期范围 (datetimeRange)

$startDateTime$endDateTime为开始和结束时间日期:

$form->datetimeRange($startDateTime, $endDateTime, 'DateTime Range');

范围 (range)

$form->range('start_column', 'end_column', '范围');

文件上传 (file)

使用文件上传功能之前需要先完成上传配置。文件上传配置以及内置方法请参考: 图片/文件上传.

文件上传目录在文件config/admin.php中的upload.file中配置,如果目录不存在,需要创建该目录并开放写权限。

$form->file($column[, $label]); // 修改文件上传路径和文件名 $form->file($column[, $label])->move($dir, $name); // 并设置上传文件类型 $form->file($column[, $label])->rules('mimes:doc,docx,xlsx'); // 添加文件删除按钮 $form->file($column[, $label])->removable();

图片上传 (image)

使用图片上传功能之前需要先完成上传配置。图片上传配置以及内置方法请参考: 图片/文件上传.

图片上传目录在文件config/admin.php中的upload.image中配置,如果目录不存在,需要创建该目录并开放写权限。

可以使用压缩、裁切、添加水印等各种方法,需要先安装intervention/image

更多使用方法请参考[Intervention]:

$form->image($column[, $label]); // 修改图片上传路径和文件名 $form->image($column[, $label])->move($dir, $name); // 剪裁图片 $form->image($column[, $label])->crop(int $width, int $height, [int $x, int $y]); // 加水印 $form->image($column[, $label])->insert($watermark, 'center');

多图和多文件上传 (multipleImage/multipleFile)

多图片上传表单继承自单图上传表单,多文件上传表单继承自单文件上传表单。

// 多图 $form->multipleImage($column[, $label]); // 限制最大上传数量 $form->multipleImage($column[, $label])->limit(3); // 多文件 $form->multipleFile($column[, $label]); // 限制最大上传数量 $form->multipleFile($column[, $label])->limit(5);

多图/文件上传的时候提交的数据是一个array数组,你可以通过以下方式把数据在保存进数据库之前改为你想要的格式:

// 转化为json格式保存到数据库 $form->multipleFile($column[, $label])->saving(function ($paths) { // 可以转化为由 , 隔开的字符串格式 // return implode(',', $paths); // 也可以转化为json return json_encode($paths); });

当然,如果你想保存为其他任意格式都是可以的,只是如果要保存其他格式,需要通过用customFormat方法把数据转化为一维数组展示,如:

$form->multipleFile($column[, $label]) ->customFormat(function ($paths) { return collect($paths)->map(function ($value) { return explode('|', $value); })->flatten()->toArray(); }) ->saving(function ($paths) { return implode('|', $paths); });

启用可排序功能

$form->multipleImage('images')->sortable();

富文本编辑器 (editor)

系统集成了TinyMCE编辑器作为内置编辑器。

基本使用

$form->editor($column[, $label]);

设置语言包

默认支持简体中文和英文两种语言,如需其他语言可以通过以下方式设置语言包地址。

$form->editor('content')->languageUrl(url('TinyMCE/langs/de.js'));

编辑器配置

具体配置等的使用可以参考官方文档中文文档

<?php use Dcat\Admin\Support\JavaScript; $form->editor('content')->options([ 'toolbar' => [], 'setup' => JavaScript::make( <<<JS function (editor) { console.log('编辑器初始化成功', editor) } JS ), ]);

设置高度

默认值为400

$form->editor('content')->height('600');

只读

$form->editor('content')->readOnly(); // 或 $form->editor('content')->disable();

图片上传

设置图片上传disk配置,默认上传到admin.upload.disk指定的配置

// 上传到oss $form->editor('content')->disk('oss');

设置图片上传目录,默认为tinymce/images

$form->editor('content')->imageDirectory('editor/images');

自定义上传接口,接口返回格式需要是{"location": "图片url"}

$form->editor('content')->imageUrl('editor/upload-image');

全局设置

如果你需要对编辑器进行全局设置,可以在app\Admin\bootstrap.php加上以下代码

<?php use Dcat\Admin\Form\Field\Editor; Editor::resolving(function (Editor $editor) { // 设置默认配置 $editor->options([...]); // 设置编辑器图片默认上传到七牛云 $editor->disk('qiniu'); });

Markdown编辑器 (markdown)

系统集成了editor-md编辑器作为内置Markdown编辑器。

基本使用

$form->markdown($column[, $label]);

设置语言包

默认支持简体中文和英文两种语言,如需其他语言可以通过以下方式设置语言包地址。

$form->markdown('content')->languageUrl(admin_asset('@admin/dcat/plugins/editor-md/languages/zh-tw.js'));

编辑器配置

具体配置等的使用可以参考官方文档

<?php use Dcat\Admin\Support\JavaScript; $form->markdown('content')->options([ 'onpreviewing' => JavaScript::make( <<<JS function() { // console.log("onpreviewing =>", this, this.id, this.settings); // on previewing you can custom css .editormd-preview-active } JS ), ]);

设置高度

默认值为500

$form->markdown('content')->height('600');

只读

$form->markdown('content')->readOnly(); // 或 $form->markdown('content')->disable();

图片上传

设置图片上传disk配置,默认上传到admin.upload.disk指定的配置

// 上传到oss $form->markdown('content')->disk('oss');

设置图片上传目录,默认为markdown/images

$form->markdown('content')->imageDirectory('markdown/images');

自定义上传接口,接口返回格式需要是{"success": 1, "url": "图片url"}

$form->markdown('content')->imageUrl('markdown/upload-image');

全局设置

如果你需要对编辑器进行全局设置,可以在app\Admin\bootstrap.php加上以下代码

<?php use Dcat\Admin\Form\Field\Markdown; Markdown::resolving(function (Markdown $markdown) { // 设置默认配置 $markdown->options([...]); // 设置编辑器图片默认上传到七牛云 $markdown->disk('qiniu'); });

开关 (switch)

使用

$form->switch($column[, $label]);

开关表单保存到数据库的默认值为10 ,如果需要更改保存到数据库的值,可以这样使用

$form->switch($column[, $label]) ->customFormat(function ($v) { return $v == '打开' ? 1 : 0; }) ->saving(function ($v) { return $v ? '打开' : '关闭'; });

地图 (map)

地图控件,用来选择经纬度, $latitude, $longitude为经纬度字段。

使用这个功能需要在 config/admin.php 文件中修改 map_provider 的值(目前支持的地图为:"tencent", "google", "yandex",不同地图需要自己申请相应的 KEY 并在 .env 文件中配置,然后需要在app/Admin/bootstrap.php中加入以下代码

Form\Field\Map::requireAssets();

使用

$form->map($latitude, $longitude, $label);

滑动条 (slider)

可以用来数字类型字段的选择,比如年龄:

$form->slider($column[, $label])->options(['max' => 100, 'min' => 1, 'step' => 1, 'postfix' => 'years old']);

更多options请参考:https://github.com/IonDen/ion.rangeSlider#settings

仅显示 (display)

只显示字段,不做任何操作:

$form->display($column[, $label]); //更复杂的显示 $form->display($column[, $label])->with(function ($value) { return "<img src="$value" />"; });

单位符号 (currency)

$form->currency($column[, $label]); // 设置单位符号 $form->currency($column[, $label])->symbol('¥');

数字 (number)

$form->number($column[, $label]);

费率 (rate)

$form->rate($column[, $label]);

分割线 (divider)

$form->divider();

自定义内容 (html)

插入html内容,参数可以是实现了HtmlableRenderable或者实现了__toString()方法的类

$form->html('你的html内容', $label = '');

标签 (tags)

插入逗号(,)隔开的字符串tags

$form->tags('keywords');

tags同样支持ManyToMany的关系,示例如下:

$form->tags('tags', '文章标签') ->pluck('name', 'id') // name 为需要显示的 Tag 模型的字段,id 为主键 ->options(Tag::all());// 下拉框选项

注意:处理ManyToMany关系时必须调用pluck方法,指定显示的字段名和主键。 此外 options 方法传入一个Collection对象时, options会自动调用该对象的pluck方法转为['主键名' => '显示字段名'] 数组,作为下拉框选项。或者可以直接使用['主键名' => '显示字段名']这样的数组作为参数。

tags还支持saving方法用于处理提交的数据,示例如下:

$form->tags('tags', '文章标签') ->pluck('name', 'id') ->options(Tag::all()) ->saving(function ($value) { return $value; });

saving 方法接收一个「参数为 tags 的提交值,返回值为修改后的 tags 提交值」的闭包,可以用于实现自动创建新 tag 或其它功能。

如果选项过多,可通过ajax方式动态分页载入选项:

$form->tags('friends')->options(function ($ids) { return User::find((array) $ids)->pluck('name', 'id'); })->ajax('api/users');

API /admin/api/users接口的代码:

public function users(Request $request) { $q = $request->get('q'); return User::where('name', 'like', "%$q%")->paginate(null, ['id', 'name as text']); }

接口返回的数据结构为

{ "total": 4, "per_page": 15, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null, "from": 1, "to": 3, "data": [ { "id": 9, "text": "xxx" }, { "id": 21, "text": "xxx" }, { "id": 42, "text": "xxx" }, { "id": 48, "text": "xxx" } ] }

图标选择器 (icon)

选择font-awesome图标

$form->icon('icon');

树形选择器 (tree)

树形结构表单

$form->tree('permissions') ->nodes(Model::get()->toArray()) // 设置所有节点 ->customFormat(function ($v) { // 格式化外部注入的值 if (!$v) return []; return array_column($v, 'id'); }); // 修改节点的字段名称 // 默认 “id” “name” “parent_id” $form->tree('permissions') ->nodes($permissionModel->allNodes()) ->setIdColumn('id') ->setTitleColumn('title') ->setParentColumn('parent'); // 默认是不保存父节点的值的,因为一般来说父节点只是作为标题的形式存在 // 禁止过滤父节点的值 $form->tree('permissions') ->nodes($permissionModel->allNodes()) ->exceptParentNode(false); // 默认收缩子节点 $form->tree('permissions') ->nodes($permissionModel->allNodes()) ->expand(false);

tree表单默认不允许单独选中父节点,可以通过treeState(false)开启这个功能

$form->tree('xxx') ->treeState(false) # 允许单独选择父节点 ->setTitleColumn('title') ->nodes(...);

效果

O chwzky2bt

表格表单 (table)

如果某一个字段存储的是json格式的二维数组,可以使用table表单组件来实现快速的编辑:

$form->table('extra', function (NestedForm $table) { $table->text('key'); $table->text('value'); $table->text('desc'); });

同时在模型里面给这个字段增加访问器和修改器:

public function getExtraAttribute($extra) { return array_values(json_decode($extra, true) ?: []); } public function setExtraAttribute($extra) { $this->attributes['extra'] = json_encode(array_values($extra)); }

这个组件类似于hasMany组件,不过是用来处理单个字段的情况,适用于简单的二维数据。

一对多 (hasMany)

一对多内嵌表格,用于处理一对多的关系,下面是个简单的例子:

有两张表是一对多关系:

CREATE TABLE `demo_painters` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `bio` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `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; CREATE TABLE `demo_paintings` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `painter_id` int(10) unsigned NOT NULL, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `body` text COLLATE utf8_unicode_ci NOT NULL, `completed_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `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`), KEY painter_id (`painter_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

表的模型为:

<?php namespace App\Models\Demo; use Illuminate\Database\Eloquent\Model; class Painter extends Model { public function paintings() { return $this->hasMany(Painting::class, 'painter_id'); } }
<?php namespace App\Models\Demo; use Illuminate\Database\Eloquent\Model; class Painting extends Model { protected $fillable = ['title', 'body', 'completed_at']; public function painter() { return $this->belongsTo(Painter::class, 'painter_id'); } }

构建表单代码如下:

use App\Models\Demo\Painter; // 这里需要显式地指定关联关系 $builder = Painter::with('paintings'); // 如果你使用的是数据仓库,则可以这样指定关联关系 // $repository = new Painter(['paintings']); return Form::make($builder, function (Form $form) { $form->display('id', 'ID'); $form->text('username')->rules('required'); $form->textarea('bio')->rules('required'); $form->hasMany('paintings', function (Form\NestedForm $form) { $form->text('title'); $form->textarea('body'); $form->datetime('completed_at'); }); $form->display('created_at', 'Created At'); $form->display('updated_at', 'Updated At'); // 也可以设置label // $form->hasMany('paintings', '画作', function (Form\NestedForm $form) { // ... // }); });

效果

Has many

表格模式 (table)

如果你想要显示表格模式,可以这样使用

use Dcat\Admin\Support\Helper; $form->hasMany('paintings', function (Form\NestedForm $form) { ... })->useTable();

效果

Has many table

内嵌 (embeds)

用于处理mysqlJSON类型字段数据或者mongodbobject类型数据,也可以将多个field的数据值以JSON字符串的形式存储在mysql的字符串类型字段中

比如orders表中的JSON或字符串类型的extra字段,用来存储多个field的数据,先定义model:

class Order extends Model { protected $casts = [ 'extra' => 'json', ]; }

然后在form中使用:

$form->embeds('extra', function ($form) { $form->text('extra1')->rules('required'); $form->email('extra2')->rules('required'); $form->mobile('extra3'); $form->datetime('extra4'); $form->dateRange('extra5', 'extra6', '范围')->rules('required'); }); // 自定义标题 $form->embeds('extra', '附加信息', function ($form) { ... });

回调函数里面构建表单元素的方法调用和外面是一样的。

Last modified: 30 八月 2024