Browse Source

完成表单分页

old
wangqing 4 years ago
parent
commit
ac14e470ef
  1. 32
      src/components/form/ProvinceCity/index.vue
  2. 1
      src/components/form/ProvinceCity/level.min.json
  3. 4
      src/components/form/pagination/index.vue
  4. 112
      src/components/generator/config.js
  5. 74
      src/components/parser/Parser.vue
  6. 5
      src/components/render/render.js
  7. 75
      src/views/form/ProjectForm.vue
  8. 10
      src/views/form/editor.vue
  9. 3
      src/views/test.vue

32
src/components/form/ProvinceCity/index.vue

@ -0,0 +1,32 @@
<template>
<div>
<el-cascader
v-model="value"
:options="options"
:props="props"
@change="changeHandle"
/>
</div>
</template>
<script>
import city from './level.min.json'
export default {
name: 'ProvinceCity',
data() {
return {
options: city,
props: {
label: 'n',
value: 'n',
children: 'd'
}
}
}, methods: {
changeHandle(val) {
this.$emit('input', val)
}
}
}
</script>

1
src/components/form/ProvinceCity/level.min.json

File diff suppressed because one or more lines are too long

4
src/components/form/pagination/index.vue

@ -6,8 +6,8 @@
> >
上一页 上一页
</el-button> </el-button>
<el-button size="mini" type="primary"> <el-button v-if="currPageNum!==totalPageNum" size="mini" type="primary" @click="nextClick">
下一页<i class="el-icon-arrow-right el-icon--right" @click="nextClick" /> 下一页<i class="el-icon-arrow-right el-icon--right" />
</el-button> </el-button>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">

112
src/components/generator/config.js

@ -665,3 +665,115 @@ export const assistComponents = [
style: {width: '100%'} style: {width: '100%'}
} }
] ]
// 个人信息组件
export const personalInfoComponents = [
{
typeId: 'INPUT',
__config__: {
label: '手机号',
labelWidth: null,
showLabel: true,
changeTag: false,
tag: 'el-input',
tagIcon: 'input',
defaultValue: undefined,
required: true,
layout: 'colFormItem',
span: 24,
showRegList: false,
document: 'https://element.eleme.cn/#/zh-CN/component/input',
// 正则校验规则
regList: [{
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
message: '手机号格式错误'
}]
},
// 组件的插槽属性
__slot__: {
prepend: '',
append: ''
},
placeholder: '请输入手机号',
style: { width: '100%' },
clearable: true,
'prefix-icon': 'el-icon-mobile',
'suffix-icon': '',
maxlength: 11,
'show-word-limit': true,
readonly: false,
disabled: false
},
{
typeId: 'INPUT',
__config__: {
label: '邮箱',
labelWidth: null,
showLabel: true,
changeTag: false,
tag: 'el-input',
tagIcon: 'input',
defaultValue: undefined,
required: true,
layout: 'colFormItem',
span: 24,
showRegList: false,
document: 'https://element.eleme.cn/#/zh-CN/component/input',
// 正则校验规则
regList: [{
pattern: '/^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$/',
message: '邮箱格式错误'
}]
},
// 组件的插槽属性
__slot__: {
prepend: '',
append: ''
},
placeholder: '请输入邮箱',
style: { width: '100%' },
clearable: true,
'prefix-icon': 'el-icon-message',
'suffix-icon': '',
maxlength: 24,
'show-word-limit': true,
readonly: false,
disabled: false
},
{
typeId: 'INPUT',
__config__: {
label: '身份证',
labelWidth: null,
showLabel: true,
changeTag: false,
tag: 'el-input',
tagIcon: 'input',
defaultValue: undefined,
required: true,
layout: 'colFormItem',
span: 24,
showRegList: false,
document: 'https://element.eleme.cn/#/zh-CN/component/input',
// 正则校验规则
regList: [{
pattern: '/(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)/',
message: '身份证格式错误'
}]
},
// 组件的插槽属性
__slot__: {
prepend: '',
append: ''
},
placeholder: '请输入身份证',
style: { width: '100%' },
clearable: true,
'prefix-icon': 'el-icon-postcard',
'suffix-icon': '',
maxlength: 20,
'show-word-limit': true,
readonly: false,
disabled: false
}
]

74
src/components/parser/Parser.vue

@ -34,7 +34,12 @@ const layouts = {
if (formConfCopy.showNumber) { if (formConfCopy.showNumber) {
label = scheme.serialNumber + ': ' + label label = scheme.serialNumber + ': ' + label
} }
this.$set(this[this.formConf.formModel], scheme.__vModel__, []) //
let value = _.get(this[this.formConf.formModel], scheme.__vModel__)
if (value) {
config.defaultValue = value
}
//
let colStyle = scheme.logicShow ? '' : 'display:none' let colStyle = scheme.logicShow ? '' : 'display:none'
let cidAttr = config.formId let cidAttr = config.formId
return ( return (
@ -165,6 +170,9 @@ function setValue(event, config, scheme) {
this.$set(this[this.formConf.formModel], scheme.__vModel__, event) this.$set(this[this.formConf.formModel], scheme.__vModel__, event)
setValueLabel.call(this, event, config, scheme) setValueLabel.call(this, event, config, scheme)
let logicShowRule = this.formConfCopy.logicShowRule let logicShowRule = this.formConfCopy.logicShowRule
if (!logicShowRule) {
return
}
// //
let rules = _.get(logicShowRule, config.formId) let rules = _.get(logicShowRule, config.formId)
if (rules && Array.isArray(rules)) { if (rules && Array.isArray(rules)) {
@ -180,6 +188,36 @@ function setValue(event, config, scheme) {
} }
} }
/**
* 分页下一页
*/
function nextPage(page) {
switchPage.call(this, 'next', page)
}
/**
* 分页上一页
*/
function prevPage(page) {
switchPage.call(this, 'prev', page)
}
/**
* 切换页
*/
function switchPage(eventName, page) {
this.$refs[this.formConf.formRef].validate(valid => {
if (!valid) {
setTimeout(() => {
let isError = document.getElementsByClassName('is-error')
isError[0].querySelector('input').focus()
}, 100)
return false
} else {
this.$emit(eventName, {page: page, formModel: this[this.formConf.formModel], labelFormModel: this[this.formConf.labelFormModel]})
}
return true
})
}
/** /**
* radio checkbox 其他输入框值处理 * radio checkbox 其他输入框值处理
*/ */
@ -252,6 +290,8 @@ function buildListeners(scheme) {
listeners.upload = (response, file, fileList) => setUpload.call(this, config, scheme, response, file, fileList) listeners.upload = (response, file, fileList) => setUpload.call(this, config, scheme, response, file, fileList)
listeners.deleteUpload = (file, fileList) => deleteUpload.call(this, config, scheme, file, fileList) listeners.deleteUpload = (file, fileList) => deleteUpload.call(this, config, scheme, file, fileList)
listeners.selectOtherChange = (event, config) => setOtherValueLabel.call(this, event, config) listeners.selectOtherChange = (event, config) => setOtherValueLabel.call(this, event, config)
listeners.prev = page => prevPage.call(this, page)
listeners.next = page => nextPage.call(this, page)
return listeners return listeners
} }
@ -263,13 +303,21 @@ export default {
formConf: { formConf: {
type: Object, type: Object,
required: true required: true
},
formModel: {
type: Object,
required: false
},
labelFormModel: {
type: Object,
required: false
} }
}, },
data() { data() {
const data = { const data = {
formConfCopy: deepClone(this.formConf), formConfCopy: deepClone(this.formConf),
[this.formConf.formModel]: {}, [this.formConf.formModel]: deepClone(this.formModel),
[this.formConf.labelFormModel]: {}, [this.formConf.labelFormModel]: deepClone(this.labelFormModel),
[this.formConf.formRules]: {} [this.formConf.formRules]: {}
} }
this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel]) this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel])
@ -277,23 +325,12 @@ export default {
this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules]) this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules])
return data return data
}, },
watch: {
formConf: {
handler(val) {
this.formConfCopy = val
this.initFormData(this.data.formConfCopy.fields, this.data[this.formConf.formModel])
this.initLabelFormData(this.data.formConfCopy.fields, this.data[this.formConf.labelFormModel])
this.buildRules(this.data.formConfCopy.fields, this.data[this.formConf.formRules])
},
deep: true
}
},
methods: { methods: {
initLabelFormData(componentList, formData) { initLabelFormData(componentList, formData) {
// //
componentList.forEach(cur => { componentList.forEach(cur => {
let temConfig = cur.__config__ let temConfig = cur.__config__
if (cur.__vModel__) { if (cur.__vModel__ && !formData[cur.__vModel__]) {
let tagOptionKey = processType[temConfig.tag] let tagOptionKey = processType[temConfig.tag]
let defaultValue = temConfig.defaultValue let defaultValue = temConfig.defaultValue
let labelStr = '' let labelStr = ''
@ -317,9 +354,12 @@ export default {
}, },
initFormData(componentList, formData) { initFormData(componentList, formData) {
// //
// eslint-disable-next-line no-debugger
debugger
componentList.forEach(cur => { componentList.forEach(cur => {
const config = cur.__config__ const config = cur.__config__
if (cur.__vModel__) { if (cur.__vModel__ && !formData[cur.__vModel__]) {
//
formData[cur.__vModel__] = config.defaultValue formData[cur.__vModel__] = config.defaultValue
} }
if (config.children) this.initFormData(config.children, formData) if (config.children) this.initFormData(config.children, formData)

5
src/components/render/render.js

@ -51,12 +51,13 @@ function vModel(dataObject, defaultValue) {
return false return false
} }
} }
// 分页组件
} else if (config.tag === 'pagination') { } else if (config.tag === 'pagination') {
dataObject.on.prev = val => { dataObject.on.prev = val => {
console.log(val) this.$emit('prev', val)
} }
dataObject.on.next = val => { dataObject.on.next = val => {
console.log(val) this.$emit('next', val)
} }
} else { } else {
dataObject.props.value = defaultValue dataObject.props.value = defaultValue

75
src/views/form/ProjectForm.vue

@ -23,7 +23,12 @@
class="form-name-text" v-html="formConf.description" class="form-name-text" v-html="formConf.description"
/> />
<el-divider /> <el-divider />
<parser v-if="startParser" :form-conf="formConf" @submit="submitForm" /> <parser v-if="startParser"
:key="parserKey"
:form-model="formModel"
:label-form-model="labelFormModel"
:form-conf="formConf" @next="nextPage" @prev="prevPage" @submit="submitForm"
/>
</div> </div>
</div> </div>
</template> </template>
@ -32,6 +37,7 @@
import Parser from '@/components/parser/Parser' import Parser from '@/components/parser/Parser'
import {dbDataConvertForItemJson} from '@/utils/convert' import {dbDataConvertForItemJson} from '@/utils/convert'
import {getExpression} from '@/utils/expression' import {getExpression} from '@/utils/expression'
import _ from 'lodash'
window.onload = function() { window.onload = function() {
document.addEventListener('touchstart', function(event) { document.addEventListener('touchstart', function(event) {
@ -59,12 +65,17 @@ export default {
return { return {
logicShowTriggerRule: {}, logicShowTriggerRule: {},
startParser: false, startParser: false,
formModel: {},
labelFormModel: {},
projectTheme: { projectTheme: {
headImgUrl: '', headImgUrl: '',
logoImg: '', logoImg: '',
showTitle: true, showTitle: true,
showDescribe: true showDescribe: true
}, },
parserKey: +new Date(),
//
perPageFields: {},
formConf: { formConf: {
fields: [], fields: [],
logicShowRule: {}, logicShowRule: {},
@ -137,7 +148,13 @@ export default {
serialNumber++ serialNumber++
return projectItem return projectItem
}) })
this.formConf.fields = fields this.pageShowHandle(fields)
if (_.keys(this.perPageFields).length != 0) {
this.formConf.fields = _.get(this.perPageFields, 1)
this.formConf.formBtns = false
} else {
this.formConf.fields = fields
}
if (res.data.project) { if (res.data.project) {
this.formConf.title = res.data.project.name this.formConf.title = res.data.project.name
this.formConf.description = res.data.project.describe this.formConf.description = res.data.project.describe
@ -157,6 +174,46 @@ export default {
}) })
}, },
methods: { methods: {
//
pageShowHandle(allFields) {
//
let index = allFields.findIndex(item => {
return item.typeId === 'PAGINATION'
})
if (index < 0) {
return
}
let curr = 1
//
let perPageFields = {}
//
let pageFields = {}
allFields.forEach(item => {
let fields = _.get(perPageFields, curr)
if (item.typeId === 'PAGINATION') {
_.set(pageFields, curr, item)
if (fields) {
item.currPageNum = curr++
}
} else {
if (!fields || fields == undefined) {
fields = new Array()
}
fields.push(item)
_.set(perPageFields, curr, fields)
}
})
let len = _.keys(perPageFields).length
//
_.keys(perPageFields).forEach(key => {
let pageItem = _.get(pageFields, key)
let fields = _.get(perPageFields, key)
pageItem.totalPageNum = len
fields.push(pageItem)
_.set(perPageFields, key, fields)
})
this.perPageFields = perPageFields
},
/** /**
* 处理逻辑显示数据 * 处理逻辑显示数据
*/ */
@ -189,6 +246,20 @@ export default {
}) })
}) })
}, },
prevPage(params) {
this.switchPage(params.page - 1, params)
},
nextPage(params) {
this.switchPage(params.page + 1, params)
},
switchPage(page, params) {
let {labelFormModel, formModel} = params
this.formModel = formModel
this.labelFormModel = labelFormModel
this.formConf.formBtns = _.keys(this.perPageFields).length == page
this.formConf.fields = _.get(this.perPageFields, page)
this.parserKey = +new Date()
},
submitForm(data) { submitForm(data) {
this.$emit('submit', data) this.$emit('submit', data)
} }

10
src/views/form/editor.vue

@ -115,7 +115,7 @@ import {
assistComponents, assistComponents,
formConf, formConf,
imageComponents, imageComponents,
inputComponents, inputComponents, personalInfoComponents,
selectComponents selectComponents
} from '@/components/generator/config' } from '@/components/generator/config'
import {deepClone} from '@/utils/index' import {deepClone} from '@/utils/index'
@ -136,7 +136,6 @@ export default {
}, },
data() { data() {
return { return {
idGlobal, idGlobal,
formConf: null, formConf: null,
editDescription: true, editDescription: true,
@ -155,6 +154,10 @@ export default {
saveIdGlobalDebounce: debounce(340, saveIdGlobal), saveIdGlobalDebounce: debounce(340, saveIdGlobal),
projectKey: null, projectKey: null,
leftComponents: [ leftComponents: [
{
title: '联系人组件',
list: personalInfoComponents
},
{ {
title: '输入型组件', title: '输入型组件',
list: inputComponents list: inputComponents
@ -267,7 +270,6 @@ export default {
let curr = 1 let curr = 1
this.drawingList.forEach((item, index) => { this.drawingList.forEach((item, index) => {
if (item.typeId === 'PAGINATION') { if (item.typeId === 'PAGINATION') {
console.log(index)
item.totalPageNum = length item.totalPageNum = length
item.currPageNum = curr++ item.currPageNum = curr++
this.$set(this.drawingList, index, item) this.$set(this.drawingList, index, item)
@ -277,6 +279,8 @@ export default {
queryProjectItems() { queryProjectItems() {
this.$api.get('/user/project/item/list', {params: {key: this.projectKey}}).then(res => { this.$api.get('/user/project/item/list', {params: {key: this.projectKey}}).then(res => {
this.drawingList = res.data.map(item => dbDataConvertForItemJson(item)) this.drawingList = res.data.map(item => dbDataConvertForItemJson(item))
//
this.updatePaginationList()
}) })
}, },
activeFormItem(currentItem) { activeFormItem(currentItem) {

3
src/views/test.vue

@ -2,15 +2,18 @@
<div> <div>
<sign-pad /> <sign-pad />
<pagination /> <pagination />
<province-city />
</div> </div>
</template> </template>
<script> <script>
import SignPad from '../components/form/SignPad' import SignPad from '../components/form/SignPad'
import pagination from '../components/form/pagination' import pagination from '../components/form/pagination'
import ProvinceCity from '@/components/form/ProvinceCity'
export default { export default {
name: 'App', name: 'App',
components: { components: {
ProvinceCity,
SignPad, SignPad,
pagination pagination
}, },

Loading…
Cancel
Save