DcatAdmin 扩展: 自定义表单(动态表单)
效果
功能
自定义组合表单项, 适用于需要自定义表单项的场景
安装
composer require slowlyo/dcat-diy-form
使用
// form() 中
$form->diyForm('field_name');
// detail() 中
$show->field('filed_name')->diyForm();
扩展项
为了方便扩展, 组件中提供了一些方法
默认组件类型包括:
- input
- textarea
- radio
- checkbox
- select
- upload-image
- upload-vedio
themeColor()
// themeColor() 方法可以设置组件的主题色, 默认取Dcat的主题色(primary)
// 参数为色号或者颜色名称, 如果不生效, 那就是识别不了
$form->diyForm('field_name')->themeColor('red');
subComponentType()
// subComponentType() 方法可以移除指定的组件类型
$form->diyForm('field_name')->subComponentType('textarea');
subComponentTypes()
// 与 subComponentType() 作用相同, 图个方便
$form->diyForm('field_name')->subComponentTypes(['textarea', 'input']);
addComponentType()
// addComponentType() 方法可以添加额外的组件类型
$form->diyForm('name', 'DiyForm')->addComponentType([
// 组件名称 (必须包含此项)
'name' => '文本域',
// 组件类型, 可以理解为标识符, 建议英文 (必须包含此项)
'type' => 'textarea',
// 表单项的label (必须包含此项)
'label' => '',
// 是否必填 1必填 0非必填 (必须包含此项)
'required' => 0,
// 组件的额外属性
'props_items' => [
// 一个数组为一项, 都是用input填写
[
// 属性名称
'label' => '显示行',
// 对应的组件数据中的key
'bind' => 'rows',
],
],
// 默认值 (必须包含此项)
'default_value' => '',
// radio/checkbox 等多选组件 的选项数据
'options' => [
// 这个是选项名称, 一般应该不用改
'label' => '选项',
// 这里是默认值, [''] 的作用是默认提供一个输入框
'values' => [''],
],
// 组件的额外属性, 用于保存数据
'rows' => 3,
// js 数据校验, 如有需要可以给这个键放个js的闭包, 需要用如下的方法处理
'validate_handler' => \Dcat\Admin\Support\JavaScript::make(<<<JS
// 一个js闭包, data与你的自定义项一致, 包括name/type/label....
(data) => {
// 这里只能做数据校验
if(!data.rows){
// 返回提示信息, js会停止往下执行, 并以 Dcat.error() 的方式弹出提示
return '请输入显示行'
}
// 数据校验通过可以不作处理, 或者返个null/false...
}
JS
),
]);
addComponentTypes()
// 与 addComponentType() 作用相同, 图个方便 +1
$form->diyForm('field_name')->subComponentTypes([['自定义组件一的数据'], ['自定义组件二的数据'], ...]);
addPreviewHtml()
// addPreviewHtml() 方法可以添加一段html代码到预览卡片中, 用于自定义组件的显示
$form->diyForm('field_name')->addPreviewHtml(<<<HTML
<!-- 此处以radio为例, 基本这些类名都需要, 不然样式不统一 -->
<div class="preview-item" v-if="item.type == 'radio'" :class="'animate-item-' + index">
<!--表单的label-->
<label class="d-flex justify-content-between">
<!--label文字-->
<div>
<!-- 如果勾选了必填, 在label前面会有个红色的 * -->
<span class="text-danger" v-if="item.required == 1">* </span>
<!--label 文字-->
@{{ item.label }}
</div>
<!--这里是操作-->
<div>
<!--将当前项往上移-->
<span class="move-item hover-line"
v-if="index != 0"
v-on:click="previewItemGoUp(index)">
<i class="feather icon-arrow-up"></i>
</span>
<!--将当前项往下移-->
<span class="move-item hover-line"
v-if="index != contents.length - 1"
v-on:click="previewItemGoDown(index)">
<i class="feather icon-arrow-down"></i>
</span>
<!--删除当前项-->
<span class="text-danger cursor-pointer hover-line"
v-on:click="subPreviewItem(index)">
移除
</span>
</div>
</label>
<!--这里是显示的表单内容, 就自由发挥吧...-->
<div class="">
<div class="custom-control custom-radio custom-control-inline"
v-for="(opt, opt_key) in item.options.values"
:key="opt_key">
<input type="radio"
:id="'radio_item_' + index + opt_key"
:name="'radio_' + index"
:checked="opt == item.default_value"
class="custom-control-input">
<label class="custom-control-label" :for="'radio_item_' + index + opt_key">
@{{ opt }}
</label>
</div>
</div>
</div>
HTML
);
还有一点
// 在detail()中使用时, 提供了两个参数
// 第一个是额外的预览html代码, 就是addPreviewHtml()方法传的那个
// 第二个参数是个bool 默认为true 如果为false 则可以在详情页中操作添加的表单
$show->field('filed_name', 'DiyForm')->diyForm($perview_html, $show_mask);
注意事项
- 这个组件用的vue.js结合blade
- 列表显示没写, 有点麻烦 (一般也不会有人把这玩意放列表上吧)
- 自定义组件类型可能有些不好写, 不过默认的应该能满足大部分需求了
- 有什么问题可以直接看源码, 写的挺简单的
- 保存的是个json字符串, 结构和 addComponentType() 那里一样
- 一般来说 varchar 是存不下的, 对应字段类型应该使用text或longtext
本作品采用《CC 协议》,转载必须注明作者和本文链接
:+1: :+1: :+1:
:+1:
:sweat_smile: :sweat_smile: :sweat_smile:
composer 安装之后为啥报错 Field type [diyForm] does not exist?
:+1: :+1: :+1: :+1: :+1:
大佬,怎么使用啊? $form 从哪来啊?