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

Laravel框架
985
0
0
2022-10-31
标签   Dcat Admin

效果

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