DcatAdmin 扩展: 自定义表单(动态表单)

效果

DcatAdmin 自定义组件: 自定义表单(动态表单)

DcatAdmin 自定义组件: 自定义表单(动态表单)

DcatAdmin 自定义组件: 自定义表单(动态表单)

DcatAdmin 扩展: 自定义表单(动态表单)

功能

自定义组合表单项, 适用于需要自定义表单项的场景

安装

composer require slowlyo/dcat-diy-form

GitHub

使用

// 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 协议》,转载必须注明作者和本文链接
海到无涯天作案,山登绝顶我为峰
slowlyo
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 8

:+1: :+1: :+1:

1年前 评论

:sweat_smile: :sweat_smile: :sweat_smile:

1年前 评论

composer 安装之后为啥报错 Field type [diyForm] does not exist?

1年前 评论
slowlyo (楼主) 1年前

:+1: :+1: :+1: :+1: :+1:

1年前 评论

大佬,怎么使用啊? $form 从哪来啊?

1年前 评论
slowlyo (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!