表单组件

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

公共方法

设置保存值

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

设置默认值

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

设置help信息

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

设置属性

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

设置placeholder

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

设置必填

  1. $form->text('title')->required();

设置pattern

  1. $form->text('title')->pattern('[A-z]{3}');

设置readonly

  1. $form->text('title')->readonly();

设置disable

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

设置autofocus

  1. $form->text('title')->autofocus();

model-form-tab

如果表单元素太多,会导致form页面太长, 这种情况下可以使用tab来分隔form:

  1. $form->tab('Basic info', function ($form) {
  2. $form->text('username');
  3. $form->email('email');
  4. })->tab('Profile', function ($form) {
  5. $form->image('avatar');
  6. $form->text('address');
  7. $form->mobile('phone');
  8. })->tab('Jobs', function ($form) {
  9. $form->hasMany('jobs', function () {
  10. $form->text('company');
  11. $form->date('start_date');
  12. $form->date('end_date');
  13. });
  14. })

设置表单项组合

用来将表单项分组显示

  1. $form->fieldset('用户信息', function (Form $form) {
  2. $form->text('username');
  3. $form->email('email');
  4. });

文本输入框

  1. $form->text($column, [$label]);
  2. // 添加提交验证规则
  3. $form->text($column, [$label])->rules('required|min:10');
  4. // 设置FontAwesome图标
  5. $form->text($column, [$label])->icon('fa-pencil');
  6. // 设置datalist
  7. $form->text($column, [$label])->datalist(['key' => 'value']);
  8. // 设置inputmask, see https://github.com/RobinHerbots/Inputmask
  9. $form->text('code')->inputmask(['mask' => '99-9999999']);

select选择框

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

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

  1. $form->select($column[, $label])->options('/api/users');

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

  1. [
  2. {
  3. "id": 9,
  4. "text": "xxx"
  5. },
  6. {
  7. "id": 21,
  8. "text": "xxx"
  9. },
  10. ...
  11. ]

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

  1. $form->select('user_id')->options(function ($id) {
  2. $user = User::find($id);
  3. if ($user) {
  4. return [$user->id => $user->name];
  5. }
  6. })->ajax('/admin/api/users');

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

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

接口返回的数据结构为

  1. {
  2. "total": 4,
  3. "per_page": 15,
  4. "current_page": 1,
  5. "last_page": 1,
  6. "next_page_url": null,
  7. "prev_page_url": null,
  8. "from": 1,
  9. "to": 3,
  10. "data": [
  11. {
  12. "id": 9,
  13. "text": "xxx"
  14. },
  15. {
  16. "id": 21,
  17. "text": "xxx"
  18. },
  19. {
  20. "id": 42,
  21. "text": "xxx"
  22. },
  23. {
  24. "id": 48,
  25. "text": "xxx"
  26. }
  27. ]
  28. }

select 联动

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

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

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

  1. [
  2. {
  3. "id": 9,
  4. "text": "xxx"
  5. },
  6. {
  7. "id": 21,
  8. "text": "xxx"
  9. },
  10. ...
  11. ]

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

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

多选框

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

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

  1. class Post extends Models
  2. {
  3. public function tags()
  4. {
  5. return $this->belongsToMany(Tag::class);
  6. }
  7. }
  8. $form->multipleSelect('tags')->options(Tag::all()->pluck('name', 'id'));

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

比如字段tags以字符串的形式存储,并且以逗号,分隔,那么像下面一样定义它的访问器和修改器:

  1. class Post extends Model
  2. {
  3. public function getTagsAttribute($value)
  4. {
  5. return explode(',', $value);
  6. }
  7. public function setTagsAttribute($value)
  8. {
  9. $this->attributes['tags'] = implode(',', $value);
  10. }
  11. }

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

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

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

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

接口返回的数据结构为

  1. {
  2. "total": 4,
  3. "per_page": 15,
  4. "current_page": 1,
  5. "last_page": 1,
  6. "next_page_url": null,
  7. "prev_page_url": null,
  8. "from": 1,
  9. "to": 3,
  10. "data": [
  11. {
  12. "id": 9,
  13. "text": "xxx"
  14. },
  15. {
  16. "id": 21,
  17. "text": "xxx"
  18. },
  19. {
  20. "id": 42,
  21. "text": "xxx"
  22. },
  23. {
  24. "id": 48,
  25. "text": "xxx"
  26. }
  27. ]
  28. }

listbox

使用方法和multipleSelect类似

  1. $form->listbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
  2. // 设置高度
  3. $form->listbox($column[, $label])->height(200);

textarea输入框

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

radio选择

  1. $form->radio($column[, $label])->options(['m' => 'Female', 'f'=> 'Male'])->default('m');
  2. // 竖排
  3. $form->radio($column[, $label])->options(['m' => 'Female', 'f'=> 'Male'])->stacked();

checkbox选择

checkbox能处理两种数据存储情况,参考多选框

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

  1. $form->checkbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
  2. // 竖排
  3. $form->checkbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name'])->stacked();
  4. // 通过闭包设置options
  5. $form->checkbox($column[, $label])->options(function () {
  6. return [1 => 'foo', 2 => 'bar', 'val' => 'Option name'];
  7. });
  8. // 如果选项太多的话,可以在上面增加一个全选checkbox
  9. $form->checkbox($column[, $label])->options([])->canCheckAll();

email输入框

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

密码输入框

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

url输入框

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

IP输入框

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

电话号码输入框

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

颜色选择框

  1. $form->color($column[, $label])->default('#ccc');

时间输入框

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

日期输入框

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

日期时间输入框

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

时间范围选择框

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

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

日期范围选框

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

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

时间日期范围选择框

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

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

货币输入框

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

数字输入框

  1. $form->number($column[, $label]);
  2. // 设置最大值
  3. $form->number($column[, $label])->max(100);
  4. // 设置最小值
  5. $form->number($column[, $label])->min(10);

比例输入框

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

图片上传

使用图片上传功能之前需要先完成上传配置,请参考:图片/文件上传.

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

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

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

  1. $form->image($column[, $label]);
  2. // 修改图片上传路径和文件名
  3. $form->image($column[, $label])->move($dir, $name);
  4. // 剪裁图片
  5. $form->image($column[, $label])->crop(int $width, int $height, [int $x, int $y]);
  6. // 加水印
  7. $form->image($column[, $label])->insert($watermark, 'center');
  8. // 添加图片删除按钮
  9. $form->image($column[, $label])->removable();
  10. // 删除数据时保留图片
  11. $form->image($column[, $label])->retainable();
  12. // 增加一个下载按钮,可点击下载
  13. $form->image($column[, $label])->downloadable();

上传图片之后生成缩略图, Since v1.7.2

  1. // 上传图片的同时生成缩略图
  2. $form->image($column[, $label])->thumbnail('small', $width = 300, $height = 300);
  3. // 或者多张缩略图
  4. $form->image($column[, $label])->thumbnail([
  5. 'small' => [100, 100],
  6. 'small' => [200, 200],
  7. 'small' => [300, 300],
  8. ]);

在模型中使用缩略图

  1. class Photo extends Model
  2. {
  3. use \Encore\Admin\Traits\Resizable;
  4. }
  5. // To access thumbnail
  6. $photo->thumbnail('small', 'photo_column');

文件上传

使用图片上传功能之前需要先完成上传配置,请参考:图片/文件上传.

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

  1. $form->file($column[, $label]);
  2. // 修改文件上传路径和文件名
  3. $form->file($column[, $label])->move($dir, $name);
  4. // 并设置上传文件类型
  5. $form->file($column[, $label])->rules('mimes:doc,docx,xlsx');
  6. // 添加文件删除按钮
  7. $form->file($column[, $label])->removable();
  8. // 删除数据时保留文件
  9. $form->file($column[, $label])->retainable();
  10. // 增加一个下载按钮,可点击下载
  11. $form->file($column[, $label])->downloadable();

多图/文件上传

  1. // 多图
  2. $form->multipleImage($column[, $label]);
  3. // 添加删除按钮
  4. $form->multipleImage($column[, $label])->removable();
  5. // 多文件
  6. $form->multipleFile($column[, $label]);
  7. // 添加删除按钮
  8. $form->multipleFile($column[, $label])->removable();
  9. // 可拖动排序 since v1.6.12
  10. $form->multipleImage('pictures')->sortable();

多图/文件上传的时候提交的数据为文件路径数组,可以直接用mysql的JSON类型字段存储,如果用mongodb的话也能直接存储,但是如果用字符串类型来存储的话,就需要指定数据的存储格式了,比如,如果要用json字符串来存储文件数据,就需要在模型中定义字段的mutator,比如字段名为pictures,定义mutator:

  1. public function setPicturesAttribute($pictures)
  2. {
  3. if (is_array($pictures)) {
  4. $this->attributes['pictures'] = json_encode($pictures);
  5. }
  6. }
  7. public function getPicturesAttribute($pictures)
  8. {
  9. return json_decode($pictures, true);
  10. }

当然你也可以指定其它任何格式.

地图控件

地图组件在v1.7.0版本之后移除,请使用经纬度选择器插件代替

滑动选择控件

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

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

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

富文本编辑框

富文本编辑框组件在v1.7.0版本之后移除,请选择使用下面的富文本编辑器扩展:

扩展URL
wangEditorhttps://github.com/laravel-admin-extensions/wangEditor
wangEditor2https://github.com/laravel-admin-extensions/wangEditor2
UEditorhttps://github.com/laravel-admin-extensions/UEditor
Summernotehttps://github.com/laravel-admin-extensions/summernote
Quillhttps://github.com/laravel-admin-extensions/quill
CKEditorhttps://github.com/laravel-admin-extensions/ckeditor
Simditorhttps://github.com/laravel-admin-extensions/simditor

隐藏域

  1. $form->hidden($column);

开关选择

onoff对用开关的两个值10:

  1. $states = [
  2. 'on' => ['value' => 1, 'text' => '打开', 'color' => 'success'],
  3. 'off' => ['value' => 0, 'text' => '关闭', 'color' => 'danger'],
  4. ];
  5. $form->switch($column[, $label])->states($states);

显示字段

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

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

分割线

  1. $form->divider();
  2. // OR
  3. $form->divider('Title');

HTML

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

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

标签

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

  1. $form->tags('keywords');

图标

选择font-awesome图标

  1. $form->icon('icon');

时区选择

  1. $form->timezone('timezone');

table

since v.16.13

WX20190505-124413

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

  1. $form->table('extra', function ($table) {
  2. $table->text('key');
  3. $table->text('value');
  4. $table->text('desc');
  5. });

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

  1. public function getExtraAttribute($extra)
  2. {
  3. return array_values(json_decode($extra, true) ?: []);
  4. }
  5. public function setExtraAttribute($extra)
  6. {
  7. $this->attributes['extra'] = json_encode(array_values($extra));
  8. }

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

一对多

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

有两张表是一对多关系:

  1. CREATE TABLE `demo_painters` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  4. `bio` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  5. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  6. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9. CREATE TABLE `demo_paintings` (
  10. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  11. `painter_id` int(10) unsigned NOT NULL,
  12. `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  13. `body` text COLLATE utf8_unicode_ci NOT NULL,
  14. `completed_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  15. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  16. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  17. PRIMARY KEY (`id`),
  18. KEY painter_id (`painter_id`)
  19. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

表的模型为:

  1. <?php
  2. namespace App\Models\Demo;
  3. use Illuminate\Database\Eloquent\Model;
  4. class Painter extends Model
  5. {
  6. public function paintings()
  7. {
  8. return $this->hasMany(Painting::class, 'painter_id');
  9. }
  10. }
  11. <?php
  12. namespace App\Models\Demo;
  13. use Illuminate\Database\Eloquent\Model;
  14. class Painting extends Model
  15. {
  16. protected $fillable = ['title', 'body', 'completed_at'];
  17. public function painter()
  18. {
  19. return $this->belongsTo(Painter::class, 'painter_id');
  20. }
  21. }

构建表单代码如下:

  1. $form->display('id', 'ID');
  2. $form->text('username')->rules('required');
  3. $form->textarea('bio')->rules('required');
  4. $form->hasMany('paintings', function (Form\NestedForm $form) {
  5. $form->text('title');
  6. $form->image('body');
  7. $form->datetime('completed_at');
  8. });
  9. $form->display('created_at', 'Created At');
  10. $form->display('updated_at', 'Updated At');
  11. // 也可以设置label
  12. $form->hasMany('paintings', '画作', function (Form\NestedForm $form) {
  13. });

内嵌

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

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

  1. class Order extends Model
  2. {
  3. protected $casts = [
  4. 'extra' => 'json',
  5. ];
  6. }

然后在form中使用:

  1. $form->embeds('extra', function ($form) {
  2. $form->text('extra1')->rules('required');
  3. $form->email('extra2')->rules('required');
  4. $form->mobile('extra3');
  5. $form->datetime('extra4');
  6. $form->dateRange('extra5', 'extra6', '范围')->rules('required');
  7. });
  8. // 自定义标题
  9. $form->embeds('extra', '附加信息', function ($form) {
  10. ...
  11. });

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

List

用来设置JSON格式的一维数组:

  1. $form->list('list');
  2. // 设置校验规则
  3. $form->list('list')->rules('required|min:5'));
  4. // 设置最大和最小元素个数
  5. $form->list('list')->max(10)->min(5);

在模型里面需要设置该字段的json cast:

  1. protected $casts = [
  2. 'list' => 'json',
  3. ];

KeyValue

用来设置JSON格式的key-value数组:

  1. $form->keyValue('kv');
  2. // 设置校验规则
  3. $form->keyValue('kv')->rules('required|min:5'));

在模型里面需要设置该字段的json cast:

  1. protected $casts = [
  2. 'kv' => 'json',
  3. ];