소스 검색

自定义表单动态表格

yuhan 1 년 전
부모
커밋
c38403a922

+ 3 - 1
itdmWeb/src/components/Container.vue

@@ -214,7 +214,7 @@ export default {
     },
     basicFields: {
       type: Array,
-      default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text']
+      default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text', 'dynamicTable']
     },
     advanceFields: {
       type: Array,
@@ -290,6 +290,7 @@ export default {
   },
   methods: {
     _loadComponents () {
+      console.log(this.basicComponents)
       this.basicComponents = this.basicComponents.map(item => {
         return {
           ...item,
@@ -428,6 +429,7 @@ export default {
       deep: true,
       handler: function (val) {
         console.log(this.$refs.widgetForm)
+        
       }
     },
     '$i18n.locale': function (val) {

+ 3 - 0
itdmWeb/src/components/GenerateForm.vue

@@ -73,12 +73,14 @@ export default {
     }
   },
   created () {
+    console.log(this.data)
     this.generateModle(this.data.list)
   },
   mounted () {
   },
   methods: {
     generateModle (genList) {
+      console.log(genList)
       for (let i = 0; i < genList.length; i++) {
         if (genList[i].type === 'grid') {
           genList[i].columns.forEach(item => {
@@ -118,6 +120,7 @@ export default {
       }
     },
     getData () {
+      console.log(this.models)
       return new Promise((resolve, reject) => {
         this.$refs.generateForm.validate(valid => {
           if (valid) {

+ 59 - 0
itdmWeb/src/components/GenerateFormItem.vue

@@ -162,6 +162,30 @@
       ></el-slider>
     </template>
 
+    <template v-if="widget.type=='dynamicTable'">
+      <el-table :data="models[widget.model]" style="width: 100%" class="u-dynamic-table" stripe border>
+        <el-table-column
+          v-for="item in widget.options.tableColumns"
+          :key="item.prop"
+          :fixed="item.fixed"
+          align="center"
+          :prop="item.prop"
+          :min-width="item.minWidth"
+          :width="item.width"
+          :show-overflow-tooltip="item.tooltip"
+          :resizable="item.resizable"
+          :label="item.label"
+        >
+          <template slot-scope="scope">
+            <el-form-item :prop="[widget.model]+ '.'+scope.$index+ '.'+item.prop">
+              <el-input v-model="scope.row[item.prop]" placeholder="请输入" />
+            </el-form-item>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="btn" @click="handleAddTableRow"><i class="el-icon-plus"></i>新增</div>
+    </template>
+
     <template v-if="widget.type=='imgupload'">
       <fm-upload
         v-model="dataModel"
@@ -206,6 +230,7 @@
     <template v-if="widget.type == 'text'">
       <span>{{dataModel}}</span>
     </template>
+
   </el-form-item>
 </template>
 
@@ -242,25 +267,59 @@ export default {
     }
   },
   methods: {
+    handleAddTableRow(){
+      if(this.widget.type === 'dynamicTable'){
+        console.log(this.widget)
+        var arr = this.widget.options.tableColumns.reduce((p, c) => Object.assign(p, { [c.prop]: '' }), {})
+        console.log(arr)
+        this.models[this.widget.model].push(arr)
+        // console.log(this.widget.options.tableData)
+      }
+    }
   },
   watch: {
     dataModel: {
       deep: true,
       handler (val) {
+        // val和this.dataModel当前改变的数据值;this.widget创建的组件的json代码;this.widget.model = key
+        // this.models数据值存放位置
         this.models[this.widget.model] = val
         this.$emit('update:models', {
           ...this.models,
           [this.widget.model]: val
         })
         this.$emit('input-change', val, this.widget.model)
+        // console.log(this.dataModel, this.models)
+        // console.log(val, this.widget)
+
       }
     },
     models: {
       deep: true,
       handler (val) {
+        // console.log(val, val[this.widget.model])
         this.dataModel = val[this.widget.model]
+        // console.log(this.dataModel)
       }
     }
   }
 }
 </script>
+<style lang="less">
+.u-dynamic-table{
+  .el-table__cell{
+    padding: 0;
+    .cell{
+      padding-left: 0 !important;
+      padding-right: 0;
+    }
+  }
+  // 当加入校验时需要判断设置
+  .el-form-item{
+    margin-bottom: 0;
+  }
+  .el-input__inner{
+    border: none;
+  }
+}
+</style>

+ 33 - 0
itdmWeb/src/components/WidgetConfig.vue

@@ -137,6 +137,23 @@
 
       </el-form-item>
 
+      <el-form-item :label="$t('fm.config.widget.option')" v-if="data.type=='dynamicTable'">
+        <draggable tag="ul" :list="data.options.tableColumns"
+          v-bind="{group:{ name:'options'}, ghostClass: 'ghost',handle: '.drag-item'}"
+          handle=".drag-item"
+        >
+          <li v-for="(item, index) in data.options.tableColumns" :key="index" style="display: flex;">
+            <el-input :style="{'width': data.options.showLabel? '90px': '180px' }" size="mini" v-model="item.label"></el-input>
+            <el-input :style="{'width': data.options.showLabel? '90px': '180px' }" size="mini" v-model="item.prop"></el-input>
+            <i class="drag-item" style="font-size: 16px;margin: 0 5px;cursor: move;"><i class="iconfont icon-icon_bars"></i></i>
+            <el-button @click="handleOptionsRemove(index)" circle plain type="danger" size="mini" icon="el-icon-minus" style="padding: 4px;margin-left: 5px;"></el-button>
+          </li>
+          <div style="margin-left: 22px;">
+            <el-button type="text" @click="handleAddTableColumn">{{$t('fm.actions.addOption')}}</el-button>
+          </div>
+        </draggable>
+      </el-form-item>
+
       <el-form-item :label="$t('fm.config.widget.remoteData')" v-if="data.type=='cascader'">
         <div>
           <el-input size="mini" style="" v-model="data.options.remoteFunc">
@@ -377,12 +394,15 @@ export default {
     handleOptionsRemove (index) {
       if (this.data.type === 'grid') {
         this.data.columns.splice(index, 1)
+      } else if (this.data.type === 'dynamicTable'){
+        this.data.options.tableColumns.splice(index, 1)
       } else {
         this.data.options.options.splice(index, 1)
       }
 
     },
     handleAddOption () {
+      console.log(this.data.options)
       if (this.data.options.showLabel) {
         this.data.options.options.push({
           value: this.$t('fm.config.widget.newOption'),
@@ -395,6 +415,19 @@ export default {
       }
 
     },
+    handleAddTableColumn () {
+      this.data.options.tableColumns.push({
+        prop: this.$t('fm.config.widget.newColumnProp'),
+        label: this.$t('fm.config.widget.newColumnLabel')
+      })
+      // if (this.data.options.showLabel) {
+      // } else {
+      //   this.data.options.tableColumns.push({
+      //     value: this.$t('fm.config.widget.newOption')
+      //   })
+      // }
+
+    },
     handleAddColumn () {
       this.data.columns.push({
         span: '',

+ 17 - 0
itdmWeb/src/components/WidgetFormItem.vue

@@ -149,6 +149,23 @@
           ></el-slider>
         </template>
 
+        <template v-if="element.type=='dynamicTable'">
+          <el-table :data="element.options.tableData" style="width: 100%" stripe border>
+            <el-table-column
+              v-for="item in element.options.tableColumns"
+              :key="item.prop"
+              :fixed="item.fixed"
+              align="center"
+              :prop="item.prop"
+              :min-width="item.minWidth"
+              :width="item.width"
+              :show-overflow-tooltip="item.tooltip"
+              :resizable="item.resizable"
+              :label="item.label"
+            />
+          </el-table>
+        </template>
+
         <template v-if="element.type=='imgupload'">
           <fm-upload
             v-model="element.options.defaultValue"

+ 24 - 0
itdmWeb/src/components/componentsConfig.js

@@ -227,6 +227,30 @@ export const basicComponents = [
       defaultValue: 'This is a text',
       customClass: '',
     }
+  },
+  {
+    type: 'dynamicTable',
+    icon: 'icon-wenzishezhi-',
+    options: {
+      tableData: [],
+      columns1: [
+        { prop: 'date', label: '日期', minWidth: '120', align: 'center', tooltip: true, resizable: true },
+        { prop: 'age', label: '年龄', minWidth: '120', align: 'center', tooltip: true, resizable: true },
+        { prop: 'gender', label: '性别', minWidth: '120', align: 'center', tooltip: true, resizable: true },
+        { prop: 'name', label: '姓名', minWidth: '120', align: 'center', tooltip: true, resizable: true },
+        { prop: 'address', label: '地址', minWidth: '120', align: 'center', tooltip: true, resizable: true }
+      ],
+      // showLabel: false,
+      // width: '',
+      // remote: false,
+      tableColumns: [
+        {
+          prop: 'prop',
+          label: '列1',
+        },
+      ],
+      defaultValue: []
+    }
   }
 ]
 

+ 3 - 0
itdmWeb/src/lang/en-US.js

@@ -15,6 +15,7 @@ export default {
         switch: 'Switch',
         slider: 'Slider',
         text: 'Text',
+        dynamicTable: 'dynamicTable',
         blank: 'Custom',
         fileupload: 'File',
         imgupload: 'Image',
@@ -170,6 +171,8 @@ export default {
         required: 'Required',
         patternPlaceholder: 'Fill in the regular expressions',
         newOption: 'New Option',
+        newColumnProp: '',
+        newColumnLabel: 'New Label',
         tab: 'Tab',
         validatorRequired: 'Required',
         validatorType: 'Invaild format',

+ 3 - 0
itdmWeb/src/lang/zh-CN.js

@@ -15,6 +15,7 @@ export default {
         switch: '开关',
         slider: '滑块',
         text: '文字',
+        dynamicTable: '动态表格',
         blank: '自定义区域',
         fileupload: '文件',
         imgupload: '图片',
@@ -170,6 +171,8 @@ export default {
         required: '必填',
         patternPlaceholder: '填写正则表达式',
         newOption: '新选项',
+        newColumnProp: '',
+        newColumnLabel: '新列',
         tab: '标签页',
         validatorRequired: '必须填写',
         validatorType: '格式不正确',