Commit 472536c2 by lanyulei Committed by GitHub

Merge pull request #34 from lanyulei/dev

添加子表单功能。
parents 60ba12b2 ba7cfd53
...@@ -41,15 +41,15 @@ ...@@ -41,15 +41,15 @@
"@antv/util": "1.3.1", "@antv/util": "1.3.1",
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
"ace-builds": "^1.4.12", "ace-builds": "^1.4.12",
"axios": "0.18.1", "axios": "^0.20.0",
"clipboard": "2.0.4", "clipboard": "^2.0.6",
"codemirror": "5.45.0", "codemirror": "^5.58.1",
"core-js": "^2.6.11", "core-js": "^2.6.11",
"driver.js": "0.9.5", "driver.js": "0.9.5",
"dropzone": "5.5.1", "dropzone": "5.5.1",
"e-icon-picker": "^1.0.7", "e-icon-picker": "^1.0.7",
"echarts": "^4.8.0", "echarts": "^4.8.0",
"element-ui": "2.11.1", "element-ui": "^2.13.2",
"file-saver": "2.0.1", "file-saver": "2.0.1",
"form-making": "^1.2.8", "form-making": "^1.2.8",
"fuse.js": "3.4.4", "fuse.js": "3.4.4",
...@@ -69,18 +69,20 @@ ...@@ -69,18 +69,20 @@
"sortablejs": "1.8.4", "sortablejs": "1.8.4",
"tui-editor": "1.3.3", "tui-editor": "1.3.3",
"viewerjs": "^1.6.1", "viewerjs": "^1.6.1",
"vue": "2.6.10", "vue": "^2.6.12",
"vue-codemirror": "^4.0.6", "vue-codemirror": "^4.0.6",
"vue-codemirror-lite": "^1.0.4", "vue-codemirror-lite": "^1.0.4",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-cropper": "^0.5.0", "vue-cropper": "^0.5.0",
"vue-i18n": "^5.0.3", "vue-i18n": "^5.0.3",
"vue-loader": "^15.9.3",
"vue-particles": "^1.0.9", "vue-particles": "^1.0.9",
"vue-quill-editor": "^3.0.6", "vue-quill-editor": "^3.0.6",
"vue-router": "3.0.2", "vue-router": "3.0.2",
"vue-splitpane": "1.0.4", "vue-splitpane": "1.0.4",
"vue2-editor": "^2.10.2", "vue2-editor": "^2.10.2",
"vuedraggable": "2.20.0", "vuedraggable": "2.20.0",
"vueify": "^9.4.1",
"vuex": "3.1.0", "vuex": "3.1.0",
"xlsx": "0.14.1" "xlsx": "0.14.1"
}, },
...@@ -116,7 +118,7 @@ ...@@ -116,7 +118,7 @@
"serve-static": "^1.13.2", "serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3", "svg-sprite-loader": "4.1.3",
"svgo": "1.2.0", "svgo": "1.2.0",
"vue-template-compiler": "2.6.10" "vue-template-compiler": "^2.6.12"
}, },
"engines": { "engines": {
"node": ">=8.9", "node": ">=8.9",
......
...@@ -55,29 +55,34 @@ ...@@ -55,29 +55,34 @@
:prop="item.model" :prop="item.model"
> >
<el-table <el-table
:data="tableData" :data="models[item.model]"
border border
style="width: 100%" style="width: 100%"
:header-cell-style="{padding: '5px 0'}"
> >
<el-table-column <el-table-column
v-if="!preview"
fixed
width="50" width="50"
> >
<template slot="header"> <template slot="header">
<i style="font-size: 25px; color: #409EFF;cursor:pointer;" class="el-icon-circle-plus" @click="addCol(item)" /> <i style="font-size: 25px; color: #409EFF;cursor:pointer;" class="el-icon-circle-plus" @click="addCol(item)" />
</template> </template>
<template> <template slot-scope="scope">
<i style="font-size: 25px; color: red" class="el-icon-remove" /> <i style="font-size: 25px; color: red" class="el-icon-remove" @click="delCol(item, scope.$index)" />
</template> </template>
</el-table-column> </el-table-column>
<template v-for="(c, i) in item.columns">
<div :key="i">
<el-table-column <el-table-column
v-for="v in item.columns.list" v-for="v in c.list"
:key="v.key" :key="v.key"
:prop="v.key" :prop="v.modal"
:label="v.name" :label="v.name"
width="250" min-width="250"
> >
<template> <template slot-scope="scope">
<genetate-form-item <genetate-form-item
:preview="preview" :preview="preview"
:models.sync="models" :models.sync="models"
...@@ -87,10 +92,13 @@ ...@@ -87,10 +92,13 @@
:data="data" :data="data"
:disabled="disabled" :disabled="disabled"
:is-label="false" :is-label="false"
@input-change="onSubformInputChange" :subform-index="scope.$index"
:subform-model="item.model"
/> />
</template> </template>
</el-table-column> </el-table-column>
</div>
</template>
</el-table> </el-table>
</el-form-item> </el-form-item>
</template> </template>
...@@ -128,7 +136,8 @@ export default { ...@@ -128,7 +136,8 @@ export default {
return { return {
tableData: [], tableData: [],
models: {}, models: {},
rules: {} rules: {},
subformFields: {}
} }
}, },
watch: { watch: {
...@@ -152,9 +161,16 @@ export default { ...@@ -152,9 +161,16 @@ export default {
}, },
methods: { methods: {
addCol(item) { addCol(item) {
var j = {} var subformFields = {}
j["id"] = this.tableData.length + 1 for (var c of item.columns) {
this.tableData.push(j) for (var l of c.list) {
subformFields[l.model] = ""
}
}
this.models[item.model].push(subformFields)
},
delCol(item, index) {
this.models[item.model].splice(index, 1)
}, },
generateModle(genList) { generateModle(genList) {
for (let i = 0; i < genList.length; i++) { for (let i = 0; i < genList.length; i++) {
...@@ -162,14 +178,14 @@ export default { ...@@ -162,14 +178,14 @@ export default {
genList[i].columns.forEach(item => { genList[i].columns.forEach(item => {
this.generateModle(item.list) this.generateModle(item.list)
}) })
} else if (genList[i].type === 'subform') {
// this.generateModle(genList[i].columns.list)
} else { } else {
if (this.value && Object.keys(this.value).indexOf(genList[i].model) >= 0) { if (this.value && Object.keys(this.value).indexOf(genList[i].model) >= 0) {
this.models[genList[i].model] = this.value[genList[i].model] this.models[genList[i].model] = this.value[genList[i].model]
} else { } else {
if (genList[i].type === 'blank') { if (genList[i].type === 'blank') {
this.$set(this.models, genList[i].model, genList[i].options.defaultType === 'String' ? '' : (genList[i].options.defaultType === 'Object' ? {} : [])) this.$set(this.models, genList[i].model, genList[i].options.defaultType === 'String' ? '' : (genList[i].options.defaultType === 'Object' ? {} : []))
} if (genList[i].type === 'subform') {
this.$set(this.models, genList[i].model, [])
} else { } else {
this.models[genList[i].model] = genList[i].options.defaultValue this.models[genList[i].model] = genList[i].options.defaultValue
} }
...@@ -209,11 +225,8 @@ export default { ...@@ -209,11 +225,8 @@ export default {
reset() { reset() {
this.$refs.generateForm.resetFields() this.$refs.generateForm.resetFields()
}, },
onSubformInputChange(value, field) {
this.$emit('on-change', field, value, this.models)
},
onInputChange(value, field) { onInputChange(value, field) {
this.$emit('on-change', field, value, this.models) // this.$emit('on-change', field, value, this.models)
}, },
refresh() { refresh() {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
:label-width="isLabel===false||!widget.options.labelWidthStatus?'0px': widgetLabelWidth + 'px'" :label-width="isLabel===false||!widget.options.labelWidthStatus?'0px': widgetLabelWidth + 'px'"
:label="isLabel===false||widget.type==='divider' || !widget.options.labelWidthStatus?'':widget.name" :label="isLabel===false||widget.type==='divider' || !widget.options.labelWidthStatus?'':widget.name"
:prop="widget.model" :prop="widget.model"
:style="subformIndex !== undefined?{'margin-bottom': '0'}: {}"
> >
<template v-if="preview"> <template v-if="preview">
<template v-if="widget.type === 'color'"> <template v-if="widget.type === 'color'">
...@@ -323,11 +324,11 @@ export default { ...@@ -323,11 +324,11 @@ export default {
FileUpload FileUpload
}, },
/* eslint-disable */ /* eslint-disable */
props: ['widget', 'models', 'rules', 'remote', 'data', 'disabled', 'preview', 'isLabel'], props: ['widget', 'models', 'rules', 'remote', 'data', 'disabled', 'preview', 'isLabel', 'subformIndex', 'subformModel'],
data() { data() {
return { return {
widgetLabelWidth: '', widgetLabelWidth: '',
dataModel: this.models[this.widget.model], dataModel: this.subformIndex===undefined?this.models[this.widget.model]:this.models[this.subformModel][this.subformIndex][this.widget.model],
tableData: [] tableData: []
} }
}, },
...@@ -335,6 +336,15 @@ export default { ...@@ -335,6 +336,15 @@ export default {
dataModel: { dataModel: {
deep: true, deep: true,
handler(val) { handler(val) {
if (val !== undefined) {
if (this.subformIndex !== undefined) {
this.models[this.subformModel][this.subformIndex][this.widget.model] = val
this.$emit('update:models', {
...this.models,
[this.subformModel]: this.models[this.subformModel]
})
this.$emit('input-change', val, this.widget.model, this.subformIndex)
} else {
this.models[this.widget.model] = val this.models[this.widget.model] = val
this.$emit('update:models', { this.$emit('update:models', {
...this.models, ...this.models,
...@@ -342,11 +352,17 @@ export default { ...@@ -342,11 +352,17 @@ export default {
}) })
this.$emit('input-change', val, this.widget.model) this.$emit('input-change', val, this.widget.model)
} }
}
}
}, },
models: { models: {
deep: true, deep: true,
handler(val) { handler(val) {
if (this.subformIndex === undefined) {
this.dataModel = val[this.widget.model] this.dataModel = val[this.widget.model]
} else {
this.dataModel = val[this.subformModel][this.subformIndex][this.widget.model]
}
} }
} }
}, },
......
...@@ -531,12 +531,14 @@ export default { ...@@ -531,12 +531,14 @@ export default {
}, },
methods: { methods: {
handleInitHeaders() { handleInitHeaders() {
if (this.data.options) {
for (var key in this.data.options.headers) { for (var key in this.data.options.headers) {
this.headers.push({ this.headers.push({
key: key, key: key,
value: this.data.options.headers[key] value: this.data.options.headers[key]
}) })
} }
}
}, },
handleAddHeader() { handleAddHeader() {
this.headers.push({ this.headers.push({
......
...@@ -64,9 +64,11 @@ ...@@ -64,9 +64,11 @@
</template> </template>
<!-- 子表单 --> <!-- 子表单 -->
<template v-else-if="element.type == 'subform'"> <template v-else-if="element.type == 'subform'">
<el-form-item <el-row
v-if="element && element.key" v-if="element && element.key"
:key="element.key" :key="element.key"
>
<el-form-item
class="widget-col widget-view" class="widget-col widget-view"
:label-width="element.options.labelWidthStatus?data.config.labelWidth + 'px': '0px'" :label-width="element.options.labelWidthStatus?data.config.labelWidth + 'px': '0px'"
:class="{active: selectWidget.key === element.key, 'is_req': element.options.required}" :class="{active: selectWidget.key === element.key, 'is_req': element.options.required}"
...@@ -80,13 +82,13 @@ ...@@ -80,13 +82,13 @@
:justify="element.options.justify" :justify="element.options.justify"
:align="element.options.align" :align="element.options.align"
> >
<el-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
<draggable <draggable
v-model="element.columns.list" v-model="col.list"
:no-transition-on-drag="true" :no-transition-on-drag="true"
v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}" v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
@end="handleMoveEnd" @end="handleMoveEnd"
@add="handleSubformWidgetAdd($event, element)" @add="handleWidgetColAdd($event, element, colIndex)"
> >
<transition-group <transition-group
name="fade" name="fade"
...@@ -94,18 +96,17 @@ ...@@ -94,18 +96,17 @@
class="widget-col-list" class="widget-col-list"
style="min-height: 131px;overflow-x: auto; white-space: nowrap;" style="min-height: 131px;overflow-x: auto; white-space: nowrap;"
> >
<template v-for="(el, i) in element.columns.list"> <template v-for="(el, i) in col.list">
<div <div
v-if="el && el.key" v-if="el && el.key"
:key="el.key" :key="el.key"
:style="{width: '249px', 'display': 'inline-block', 'vertical-align': 'top'}" @click="handleSelectWidget(i)"
@click.native="handleSelectWidget(i)"
> >
<widget-form-item <widget-form-item
:element="el" :element="el"
:select.sync="selectWidget" :select.sync="selectWidget"
:index="i" :index="i"
:data="element.columns" :data="col"
:data-config="data" :data-config="data"
:is-label="true" :is-label="true"
:is-table="true" :is-table="true"
...@@ -114,9 +115,9 @@ ...@@ -114,9 +115,9 @@
</template> </template>
</transition-group> </transition-group>
</draggable> </draggable>
</el-col>
<div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action"> <div v-if="selectWidget.key == element.key" class="widget-view-action widget-col-action">
<i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" /> <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
</div> </div>
...@@ -125,6 +126,7 @@ ...@@ -125,6 +126,7 @@
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
</el-row>
</template> </template>
<template v-else> <template v-else>
<widget-form-item <widget-form-item
...@@ -216,68 +218,15 @@ export default { ...@@ -216,68 +218,15 @@ export default {
}) })
} }
if (this.data.list[newIndex].type === 'grid') { if (this.data.list[newIndex].type === 'grid' || this.data.list[newIndex].type === 'subform') {
this.$set(this.data.list, newIndex, { this.$set(this.data.list, newIndex, {
...this.data.list[newIndex], ...this.data.list[newIndex],
columns: this.data.list[newIndex].columns.map(item => ({ ...item })) columns: this.data.list[newIndex].columns.map(item => ({ ...item }))
}) })
} }
if (this.data.list[newIndex].type === 'subform') {
this.$set(this.data.list, newIndex, {
...this.data.list[newIndex],
columns: this.data.list[newIndex].columns = {
span: 24,
list: []
}
})
}
this.selectWidget = this.data.list[newIndex] this.selectWidget = this.data.list[newIndex]
}, },
handleSubformWidgetAdd($event, row) {
const newIndex = $event.newIndex
const oldIndex = $event.oldIndex
const item = $event.item
// 防止布局元素的嵌套拖拽
if (item.className.indexOf('data-grid') >= 0) {
// 如果是列表中拖拽的元素需要还原到原来位置
item.tagName === 'DIV' && this.data.list.splice(oldIndex, 0, row.columns.list[newIndex])
row.columns.list.splice(newIndex, 1)
return false
}
const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
this.$set(row.columns.list, newIndex, {
...row.columns.list[newIndex],
options: {
...row.columns.list[newIndex].options,
remoteFunc: 'func_' + key
},
key,
// 绑定键值
model: row.columns.list[newIndex].type + '_' + key,
rules: []
})
if (row.columns.list[newIndex].type === 'radio' || row.columns.list[newIndex].type === 'checkbox' || row.columns.list[newIndex].type === 'select') {
this.$set(row.columns.list, newIndex, {
...row.columns.list[newIndex],
options: {
...row.columns.list[newIndex].options,
options: row.columns.list[newIndex].options.options.map(item => ({
...item
}))
}
})
}
this.selectWidget = row.columns.list[newIndex]
},
handleWidgetColAdd($event, row, colIndex) { handleWidgetColAdd($event, row, colIndex) {
const newIndex = $event.newIndex const newIndex = $event.newIndex
const oldIndex = $event.oldIndex const oldIndex = $event.oldIndex
......
...@@ -363,10 +363,13 @@ export const advanceComponents = [ ...@@ -363,10 +363,13 @@ export const advanceComponents = [
{ {
type: 'subform', type: 'subform',
icon: 'icon-table', icon: 'icon-table',
columns: { columns: [{
span: 24, span: 12,
list: [] list: []
}, }, {
span: 12,
list: []
}],
options: { options: {
gutter: 0, gutter: 0,
justify: 'start', justify: 'start',
......
...@@ -40,7 +40,6 @@ Vue.use(VueEditor) ...@@ -40,7 +40,6 @@ Vue.use(VueEditor)
import iconPicker from 'e-icon-picker' import iconPicker from 'e-icon-picker'
import 'e-icon-picker/dist/index.css'// 基础样式 import 'e-icon-picker/dist/index.css'// 基础样式
import 'e-icon-picker/dist/main.css' // fontAwesome 图标库样式 import 'e-icon-picker/dist/main.css' // fontAwesome 图标库样式
Vue.use(iconPicker) Vue.use(iconPicker)
// 全局方法挂载 // 全局方法挂载
......
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
upload upload
generate-code generate-code
generate-json generate-json
:advance-fields="['editor', 'imgupload', 'file']" :advance-fields="['editor', 'imgupload', 'file', 'subform']"
> >
<template slot="action" /> <template slot="action" />
</fm-making-form> </fm-making-form>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment