效果
功能
自定義組合表單項, 適用於需要自定義表單項的場景
安裝
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 協議》,轉載必須註明作者和本文連結