字段的使用

未匹配的标注
本文档最新版为 2.x,旧版本可能放弃维护,推荐阅读最新版!

表单字段的使用

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

公共方法

设置表单值 (value)

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

设置默认值 (default)

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

Since v1.7.1

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

$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->mutipleFile('files')->saving(function ($paths) {
    $paths = Helper::array($paths);

    // 获取数据库当前行的其他字段
    $username = $this->username;

    // 最终转化为json保存到数据库
    return json_encode($paths);
});

格式化待渲染的数据 (customFormat)

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

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

use Dcat\Admin\Support\Helper;

$form->mutipleFile('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->textare('contents')->hideInDialog();

文本 (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');

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"
        }
    ]
}

下拉选框联动

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')]);
}

下拉选框多选 (multipleSelect)

注入这个字段的数据(从数据库查出来的)可以是一个以,隔开的字符串,也可以是json字符串或array数组。

$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->multipleSelect('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"
        }
    ]
}

弹窗选择器 (selectResource)

此功能即将在 2.0 版本中废弃,请使用 selectTable 功能代替。

通过selectResource表单可以构建一个弹窗选择器,可以从弹窗里面选择表格数据,并且支持数据筛选等操作。

注入这个字段的数据(从数据库查出来的)可以是一个以,隔开的字符串,也可以是json字符串或array数组。

 $form->selectResource('user')
    ->path('auth/users') // 设置表格页面链接
    ->options(function ($v) { // 显示已选中的数据
        if (!$v) return $v;
        $userModel = config('admin.database.users_model');

        return $userModel::find($v)->pluck('name', 'id');
    });

// 设置为多选
 $form->selectResource('user')
    ->path('auth/users') 
    ->multiple() // 设置为多选
    ->options(function ($v) {
        ...
    });  

// 限制最大选择数量
 $form->selectResource('user')
    ->path('auth/users') 
    ->multiple(3) // 最多选择3个选项
    ->options(function ($v) {
        ...
    });       

然后设置你的路由app/Admin/routes.php

这里的添加路由只是示例,如果是新增的控制器需要加路由,如果路由已经存在则不需要再添加。

$router->resource('auth/users', 'UserController');

auth/users页面实现代码如下:

<?php

use Dcat\Admin\Models\Administrator;
use Dcat\Admin\IFrameGrid;
use Dcat\Admin\Grid;
use Dcat\Admin\Controllers\AdminController;

class UserController extends AdminController
{
    protected function iFrameGrid()
    {
        $grid = new IFrameGrid(new Administrator());

        // 指定行选择器选中时显示的值的字段名称
        // 指定行选择器选中时显示的值的字段名称
        // 指定行选择器选中时显示的值的字段名称
        // 如果表格数据中带有 “name”、“title”或“username”字段,则可以不用设置
        $grid->rowSelector()->titleColumn('username');

        $grid->id->sortable();
        $grid->username;
        $grid->name;

        $grid->filter(function (Grid\Filter $filter) {
            $filter->equal('id');
            $filter->like('username');
            $filter->like('name');
        });

        return $grid;
    }
}

效果

表格选择器 (selectTable)

Since v1.7.0

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(new Administrator(), function (Grid $grid) {
            $grid->column('id');
            $grid->column('username');
            $grid->column('name');
            $grid->column('created_at');
            $grid->column('updated_at');

            // 指定行选择器选中时显示的值的字段名称
            // 指定行选择器选中时显示的值的字段名称
            // 指定行选择器选中时显示的值的字段名称
            // 如果表格数据中带有 “name”、“title”或“username”字段,则可以不用设置
            $grid->rowSelector()->titleColumn('username');

            $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);
            });
        });
    }
}

效果

多选盒 (listbox)

使用方法和multipleSelect类似。

注入这个字段的数据(从数据库查出来的)可以是一个以,隔开的字符串,也可以是json字符串或array数组。

$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);
    });

Since v1.7.0

启用选中全部功能

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

邮箱 (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)

Since v1.7.0

$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)

Since v1.5.3

$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');

多图和多文件上传

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

注入这个字段的数据(从数据库查出来的)可以是一个以,隔开的字符串,也可以是json字符串或array数组。

// 多图
$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('images')
    ->customFormat(function ($paths) {
        return collect($paths)->map(function ($value) {
            return explode('|', $value);
        })->flatten()->toArray();
    })
    ->saving(function ($paths) {
        return implode('|', $paths);
    });

Since v1.3.0 - 增加可排序功能支持

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

富文本编辑器 (editor)

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

Since v1.1.0

基本使用

$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编辑器。

Since v1.2.0

基本使用

$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::collectAssets();

使用

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

滑动条 (slider)

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

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

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

仅显示 (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 或其它功能。

Since v1.6.0

如果选项过多,可通过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($permissionModel->allNodes()) // 设置所有节点
    ->customFormat(function ($v) { // 格式化外部注入的值
        if (!$v) return [];

        return array_column($v, 'id');
    });

// 修改节点的字段名称
// 默认 “id” “name” “parent_id”
$form->tree('permissions')
    ->nodes($permissionModel->allNodes())
    ->columnNames('id', 'title', 'parent'); 

// 默认是不保存父节点的值的,因为一般来说父节点只是作为标题的形式存在
// 禁止过滤父节点的值
$form->tree('permissions')
    ->nodes($permissionModel->allNodes())
    ->disableFilterParents();

表格表单 (table)

Since v1.3.4版本起支持图片以及文件上传表单。

如果某一个字段存储的是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)

Since v1.3.4版本起支持图片以及文件上传表单。

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

有两张表是一对多关系:

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) {
        ...
    });
});

效果

表格模式 (table)

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

use Dcat\Admin\Support\Helper;

$form->hasMany('paintings', function (Form\NestedForm $form) {
     ...
})->useTable();

效果

内嵌 (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) {
    ...
});

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

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 6
发起讨论 只看当前版本


蒙挚
Dcat的多选功能使用问题---
3 个点赞 | 1 个回复 | 问答 | 课程版本 2.x
claystone
xuchunyang
Dcat Admin 的富文本编辑器 $form->editor 图片上传路径问题
0 个点赞 | 1 个回复 | 问答 | 课程版本 2.x
chenyifaer
关联表的数据再次提交的时候没有修改而是重复添加
0 个点赞 | 1 个回复 | 问答 | 课程版本 2.x
周小云
dcat admin 一对多 里面的checkbox怎么使用啊 不知道为啥
0 个点赞 | 0 个回复 | 问答 | 课程版本 2.x