Browse Source

add editor radio other

fix style
old
wangqing 5 years ago
parent
commit
17632466e8
  1. 7
      src/assets/styles/form/home.scss
  2. 67
      src/components/parser/Parser.vue
  3. 43
      src/components/render/render.js
  4. 30
      src/components/render/slots/el-checkbox-group.js
  5. 30
      src/components/render/slots/el-radio-group.js
  6. 3
      src/components/tinymce/index.vue
  7. 2
      src/router/modules/root.js
  8. 1
      src/utils/convert.js
  9. 228
      src/views/form/DraggableItem.vue
  10. 2
      src/views/form/ProjectForm.vue
  11. 1969
      src/views/form/RightPanel.vue
  12. 2
      src/views/form/editor.vue
  13. 7
      src/views/project/MyProject.vue
  14. 28
      src/views/test.vue

7
src/assets/styles/form/home.scss

@ -1,5 +1,5 @@
$selectedColor: #f5f8ff; $selectedColor: #fafafa;
$lighterBlue: #4aa0fa; $lighterBlue: #e4efff;
.form-edit-container { .form-edit-container {
position: relative; position: relative;
width: 100%; width: 100%;
@ -55,7 +55,7 @@ $lighterBlue: #4aa0fa;
left: 40px; left: 40px;
top: 0; top: 0;
height: 100vh; height: 100vh;
//background-color: rgba(255, 255, 255, 100);
} }
.el-menu.el-menu--horizontal { .el-menu.el-menu--horizontal {
border-bottom: none; border-bottom: none;
@ -65,6 +65,7 @@ $lighterBlue: #4aa0fa;
overflow: hidden; overflow: hidden;
margin: 5px; margin: 5px;
border-radius: 7px; border-radius: 7px;
background-color: rgba(255, 255, 255, 100);
//text-align: center; //text-align: center;
box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.4); box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 100); border: 1px solid rgba(255, 255, 255, 100);

67
src/components/parser/Parser.vue

@ -160,19 +160,44 @@ function setValue(event, config, scheme) {
setValueLabel.call(this, event, config, scheme) setValueLabel.call(this, event, config, scheme)
} }
/**
* radio checkbox 其他输入框值处理
*/
function setOtherValueLabel(event, config) {
let value = this[this.formConf.formModel][config.__vModel__]
this.$set(this[this.formConf.labelFormModel], `${config.__vModel__}other`, event)
setValueLabel.call(this, value, config.__config__, config)
}
/**
* 保存选项的label值
* @param event
* @param config
* @param scheme
*/
function setValueLabel(event, config, scheme) { function setValueLabel(event, config, scheme) {
let tagOptionKey = processType[config.tag] let tagOptionKey = processType[config.tag]
if (tagOptionKey) { if (tagOptionKey) {
if (event instanceof Array) { if (event instanceof Array) {
let labelStr = '' let labelArr = new Array()
event.forEach(item => { event.forEach(item => {
let {label} = getObject(_.get(scheme, tagOptionKey), 'value', item) //
labelStr += label + ',' if (item === 0) {
labelArr.push(this[this.formConf.labelFormModel][`${scheme.__vModel__}other`])
}else{
let {label} = getObject(_.get(scheme, tagOptionKey), 'value', item)
labelArr.push(label)
}
}) })
this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, labelStr) this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, labelArr.join(','))
} else { } else {
let item = _.find(_.get(scheme, tagOptionKey), {'value': event}) //
this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, item.label) if (event == 0) {
this.$set(this[this.formConf.labelFormModel], `${config.__vModel__}`, this[this.formConf.labelFormModel][`${config.__vModel__}other`])
} else {
let item = _.find(_.get(scheme, tagOptionKey), {'value': event})
this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, item.label)
}
} }
} else if (config.tag === 'el-upload') { } else if (config.tag === 'el-upload') {
this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, event) this.$set(this[this.formConf.labelFormModel], scheme.__vModel__, event)
@ -206,7 +231,7 @@ function buildListeners(scheme) {
listeners.input = event => setValue.call(this, event, config, scheme) listeners.input = event => setValue.call(this, event, config, 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)
return listeners return listeners
} }
@ -328,3 +353,31 @@ export default {
} }
} }
</script> </script>
<style scoped>
/deep/ .el-radio-group {
margin-left: 10px;
}
/deep/ .el-radio {
display: block;
height: 23px;
line-height: 23px;
}
/deep/ .el-checkbox-group {
margin-left: 10px;
}
/deep/ .el-checkbox {
display: block;
}
/deep/ .item-other-input {
margin-left: 20px;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
/deep/ .item-other-input:focus {
outline: none;
}
</style>

43
src/components/render/render.js

@ -26,29 +26,28 @@ function vModel(dataObject, defaultValue) {
this.$emit('deleteUpload', file, fileList) this.$emit('deleteUpload', file, fileList)
} }
dataObject.attrs['on-exceed'] = (files, fileList) => { dataObject.attrs['on-exceed'] = (files, fileList) => {
this.$message.error(`最多上传${config.limit}个文件`); this.$message.error(`最多上传${config.limit}个文件`)
}, },
dataObject.attrs['before-upload'] = (file) => { dataObject.attrs['before-upload'] = (file) => {
let sizeUnitNum = 1 let sizeUnitNum = 1
//文件大小判断 //文件大小判断
switch (config.sizeUnit) { switch (config.sizeUnit) {
case 'KB': case 'KB':
sizeUnitNum = 1024 sizeUnitNum = 1024
break break
case 'MB': case 'MB':
sizeUnitNum = 1024 * 1024 sizeUnitNum = 1024 * 1024
break break
case 'GB': case 'GB':
sizeUnitNum = 1024 * 1024 * 1024 sizeUnitNum = 1024 * 1024 * 1024
break break
}
let totalSize = config.fileSize * sizeUnitNum
if (file.size > totalSize) {
this.$message.error(`上传图片大小不能超过${config.fileSize}${config.sizeUnit}`)
return false
}
} }
let totalSize= config.fileSize*sizeUnitNum
if (file.size> totalSize) {
this.$message.error(`上传图片大小不能超过${config.fileSize}${config.sizeUnit}`);
return false
}
console.log(dataObject)
}
} else { } else {
dataObject.props.value = defaultValue dataObject.props.value = defaultValue
@ -65,7 +64,7 @@ function mountSlotFlies(h, confClone, children) {
Object.keys(childObjs).forEach(key => { Object.keys(childObjs).forEach(key => {
const childFunc = childObjs[key] const childFunc = childObjs[key]
if (confClone.__slot__ && confClone.__slot__[key]) { if (confClone.__slot__ && confClone.__slot__[key]) {
children.push(childFunc(h, confClone, key)) children.push(childFunc(h, confClone, key, this))
} }
}) })
} }

30
src/components/render/slots/el-checkbox-group.js

@ -1,13 +1,21 @@
export default { export default {
options(h, conf, key) { options(h, conf, key, that) {
const list = [] const list = []
conf.__slot__.options.forEach(item => { conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') { if (conf.__config__.optionType === 'button') {
list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>) list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
} else { } else {
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>) if (item.value == 0) {
} list.push(<el-checkbox label={item.value}
}) border={conf.border}>{item.label}
return list <input class='item-other-input' onChange={event => {
} that.$emit('selectOtherChange', event.target.value, conf)
}}/></el-checkbox>)
} else {
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
}
}
})
return list
}
} }

30
src/components/render/slots/el-radio-group.js

@ -1,13 +1,21 @@
export default { export default {
options(h, conf, key) { options(h, conf, key, that) {
const list = [] const list = []
conf.__slot__.options.forEach(item => { conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') { if (conf.__config__.optionType === 'button') {
list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>) list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
} else { } else {
list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>) if (item.value == 0) {
} list.push(<el-radio label={item.value} border={conf.border} >
}) {item.label}<input class='item-other-input' onChange={event => {
return list that.$emit('selectOtherChange', event.target.value,conf)
} }}/>
</el-radio>)
} else {
list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
}
}
})
return list
}
} }

3
src/components/tinymce/index.vue

@ -42,10 +42,11 @@ export default {
menubar: 'false', menubar: 'false',
skin_url: '/tinymce/skins/ui/tduck', skin_url: '/tinymce/skins/ui/tduck',
content_css : '/tinymce/skins/content/tduck' , content_css : '/tinymce/skins/content/tduck' ,
toolbar_mode:'floating',
cache_suffix: '?v='+new Date(), cache_suffix: '?v='+new Date(),
plugins, plugins,
toolbar, toolbar,
toolbar_drawer:'sliding',
toolbar_mode:'sliding',
height: 200, height: 200,
// fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt", // fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
branding: false, branding: false,

2
src/router/modules/root.js

@ -2,7 +2,7 @@ export default [
{ {
path: '/test', path: '/test',
meta: {requireLogin: false}, meta: {requireLogin: false},
component: () => import(/* webpackChunkName: 'root' */ '@/components/tinymce/example/Index') component: () => import(/* webpackChunkName: 'root' */ '@/views/test')
}, },
{ {
path: '/redirect/:type', path: '/redirect/:type',

1
src/utils/convert.js

@ -54,6 +54,7 @@ export function dbDataConvertForItemJson(data) {
_.set(jsonItem, param[key], value) _.set(jsonItem, param[key], value)
}) })
} }
jsonItem.sort = data.sort
jsonItem.typeId = data.type jsonItem.typeId = data.type
jsonItem.__config__.formId = data.formItemId jsonItem.__config__.formId = data.formItemId
jsonItem.__config__.label = data.label jsonItem.__config__.label = data.label

228
src/views/form/DraggableItem.vue

@ -3,118 +3,154 @@ import draggable from 'vuedraggable'
import render from '@/components/render/render' import render from '@/components/render/render'
const components = { const components = {
itemBtns(h, currentItem, index, list) { itemBtns(h, currentItem, index, list) {
const { copyItem, deleteItem } = this.$listeners const {copyItem, deleteItem} = this.$listeners
return [ return [
<span class="drawing-item-copy" title="复制" onClick={event => { <span class="drawing-item-copy" title="复制" onClick={event => {
copyItem(currentItem, list); event.stopPropagation() copyItem(currentItem, list)
}}> event.stopPropagation()
<i class="el-icon-copy-document" /> }}>
<i class="el-icon-copy-document"/>
</span>, </span>,
<span class="drawing-item-delete" title="删除" onClick={event => { <span class="drawing-item-delete" title="删除" onClick={event => {
deleteItem(index, list); event.stopPropagation() deleteItem(index, list)
}}> event.stopPropagation()
<i class="el-icon-delete" /> }}>
<i class="el-icon-delete"/>
</span> </span>
] ]
} }
} }
const layouts = { const layouts = {
colFormItem(h, currentItem, index, list) { colFormItem(h, currentItem, index, list) {
const { activeItem, changeLabel } = this.$listeners const {activeItem, changeLabel} = this.$listeners
const config = currentItem.__config__ const config = currentItem.__config__
const child = renderChildren.apply(this, arguments) const child = renderChildren.apply(this, arguments)
let className = this.activeId === config.formId ? 'drawing-item active-from-item' : 'drawing-item' let className = this.activeId === config.formId ? 'drawing-item active-from-item' : 'drawing-item'
if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered' if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0' if (config.showLabel === false) labelWidth = '0'
return ( return (
<el-col span={config.span} class={className} <el-col span={config.span} class={className}
nativeOnClick={event => { activeItem(currentItem); event.stopPropagation() }}> nativeOnClick={event => {
<el-form-item label-width={labelWidth} activeItem(currentItem)
label={config.showLabel ? config.label : ''} required={config.required}> event.stopPropagation()
<render key={config.renderKey} conf={currentItem} onInput={ event => { }}>
this.$set(config, 'defaultValue', event) <el-form-item label-width={labelWidth}
}}> label={config.showLabel ? config.label : ''} required={config.required}>
{child} <render key={config.renderKey} conf={currentItem} onInput={event => {
</render> this.$set(config, 'defaultValue', event)
</el-form-item> }}>
{components.itemBtns.apply(this, arguments)} {child}
</el-col> </render>
) </el-form-item>
}, {components.itemBtns.apply(this, arguments)}
rowFormItem(h, currentItem, index, list) { </el-col>
const { activeItem } = this.$listeners )
const config = currentItem.__config__ },
const className = this.activeId === config.formId rowFormItem(h, currentItem, index, list) {
? 'drawing-row-item active-from-item' const {activeItem} = this.$listeners
: 'drawing-row-item' const config = currentItem.__config__
let child = renderChildren.apply(this, arguments) const className = this.activeId === config.formId
if (currentItem.type === 'flex') { ? 'drawing-row-item active-from-item'
child = <el-row type={currentItem.type} justify={currentItem.justify} align={currentItem.align}> : 'drawing-row-item'
{child} let child = renderChildren.apply(this, arguments)
if (currentItem.type === 'flex') {
child = <el-row type={currentItem.type} justify={currentItem.justify} align={currentItem.align}>
{child}
</el-row> </el-row>
} }
return ( return (
<el-col span={config.span}> <el-col span={config.span}>
<el-row gutter={config.gutter} class={className} <el-row gutter={config.gutter} class={className}
nativeOnClick={event => { activeItem(currentItem); event.stopPropagation() }}> nativeOnClick={event => {
<span class="component-name">{config.componentName}</span> activeItem(currentItem)
<draggable list={config.children || []} animation={340} event.stopPropagation()
group="componentsGroup" class="drag-wrapper"> }}>
<span class="component-name">{config.componentName}</span>
<draggable list={config.children || []} animation={340}
group="componentsGroup" class="drag-wrapper">
{child}
</draggable>
{components.itemBtns.apply(this, arguments)}
</el-row>
</el-col>
)
},
raw(h, currentItem, index, list) {
const config = currentItem.__config__
const child = renderChildren.apply(this, arguments)
return <render key={config.renderKey} conf={currentItem} onInput={event => {
this.$set(config, 'defaultValue', event)
}}>
{child} {child}
</draggable> </render>
{components.itemBtns.apply(this, arguments)} }
</el-row>
</el-col>
)
},
raw(h, currentItem, index, list) {
const config = currentItem.__config__
const child = renderChildren.apply(this, arguments)
return <render key={config.renderKey} conf={currentItem} onInput={ event => {
this.$set(config, 'defaultValue', event)
}}>
{child}
</render>
}
} }
function renderChildren(h, currentItem, index, list) { function renderChildren(h, currentItem, index, list) {
const config = currentItem.__config__ const config = currentItem.__config__
if (!Array.isArray(config.children)) return null if (!Array.isArray(config.children)) return null
return config.children.map((el, i) => { return config.children.map((el, i) => {
const layout = layouts[el.__config__.layout] const layout = layouts[el.__config__.layout]
if (layout) { if (layout) {
return layout.call(this, h, el, i, config.children) return layout.call(this, h, el, i, config.children)
} }
return layoutIsNotFound.call(this) return layoutIsNotFound.call(this)
}) })
} }
function layoutIsNotFound() { function layoutIsNotFound() {
throw new Error(`没有与${this.currentItem.__config__.layout}匹配的layout`) throw new Error(`没有与${this.currentItem.__config__.layout}匹配的layout`)
} }
export default { export default {
components: { components: {
render, render,
draggable draggable
}, },
props: [ props: [
'currentItem', 'currentItem',
'index', 'index',
'drawingList', 'drawingList',
'activeId', 'activeId',
'formConf' 'formConf'
], ],
render(h) { render(h) {
const layout = layouts[this.currentItem.__config__.layout] const layout = layouts[this.currentItem.__config__.layout]
if (layout) { if (layout) {
return layout.call(this, h, this.currentItem, this.index, this.drawingList) return layout.call(this, h, this.currentItem, this.index, this.drawingList)
}
return layoutIsNotFound.call(this)
} }
return layoutIsNotFound.call(this)
}
} }
</script> </script>
<style scoped>
/deep/ .el-radio-group {
margin-left: 10px;
}
/deep/ .el-radio {
display: block;
height: 23px;
line-height: 23px;
}
/deep/ .el-checkbox-group {
margin-left: 10px;
}
/deep/ .el-checkbox {
display: block;
}
/deep/ .item-other-input {
margin-left: 20px;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
/deep/ .item-other-input:focus {
outline: none;
}
</style>

2
src/views/form/ProjectForm.vue

@ -17,7 +17,7 @@
</h4> </h4>
<div <div
v-show="projectTheme.showDescribe" v-show="projectTheme.showDescribe"
class="form-name-text" v-html="formConf.description" > class="form-name-text" v-html="formConf.description">
</div> </div>
<el-divider> <el-divider>
</el-divider> </el-divider>

1969
src/views/form/RightPanel.vue

File diff suppressed because it is too large

2
src/views/form/editor.vue

@ -280,9 +280,9 @@ export default {
this.activeData = tempActiveData this.activeData = tempActiveData
this.activeId = this.idGlobal this.activeId = this.idGlobal
} }
this.onItemEnd(obj)
}, },
onItemEnd(obj) { onItemEnd(obj) {
console.log(obj)
let params = {'projectKey': this.projectKey} let params = {'projectKey': this.projectKey}
if (this.drawingList[obj.newIndex - 1]) { if (this.drawingList[obj.newIndex - 1]) {
let sort1 = this.drawingList[obj.newIndex - 1].sort let sort1 = this.drawingList[obj.newIndex - 1].sort

7
src/views/project/MyProject.vue

@ -69,6 +69,7 @@
<div v-if="dataShowType=='gird'" class="project-grid-container"> <div v-if="dataShowType=='gird'" class="project-grid-container">
<div <div
v-if="projectList.length" v-if="projectList.length"
v-loading="projectListLoading"
class="project-grid-view" class="project-grid-view"
> >
<div v-for="p in projectList" :key="p.id" class="project-grid-item-view pointer" :span="4"> <div v-for="p in projectList" :key="p.id" class="project-grid-item-view pointer" :span="4">
@ -194,6 +195,7 @@
</template> </template>
<script> <script>
import DataEmpty from '@/components/DataEmpty' import DataEmpty from '@/components/DataEmpty'
let projectStatusList = [ let projectStatusList = [
{code: 1, name: '未发布', color: '#006EFF'}, {code: 1, name: '未发布', color: '#006EFF'},
{code: 2, name: '收集中', color: '#34C82A'}, {code: 2, name: '收集中', color: '#34C82A'},
@ -216,7 +218,8 @@ export default {
status: null status: null
}, },
projectStatusList: projectStatusList, projectStatusList: projectStatusList,
projectList: [] projectList: [],
projectListLoading: true
} }
}, },
computed: { computed: {
@ -241,6 +244,7 @@ export default {
this.$router.push({path: '/project/form', query: {key: key, active: type}}) this.$router.push({path: '/project/form', query: {key: key, active: type}})
}, },
queryProjectPage() { queryProjectPage() {
this.$api.get('/user/project/page', { this.$api.get('/user/project/page', {
params: this.queryParams params: this.queryParams
}).then(res => { }).then(res => {
@ -248,6 +252,7 @@ export default {
this.projectList = records this.projectList = records
this.total = total this.total = total
this.queryParams.size = size this.queryParams.size = size
this.projectListLoading = false
}) })
} }
} }

28
src/views/test.vue

@ -1,23 +1,26 @@
<template> <template>
<div> <div>
<Verify <el-radio-group v-model="radio">
ref="verify" <el-radio :label="3">备选项</el-radio>
:mode="'pop'" <el-radio :label="6">备选项</el-radio>
:captcha-type="'blockPuzzle'" <el-radio :label="9">备选项</el-radio>
:img-size="{ width: '330px', height: '155px' }" <el-radio :label="0">其他<input/>
@success="success" </el-radio>
/> </el-radio-group>
<button @click="useVerify">调用验证组件</button>
</div> </div>
</template> </template>
<script> <script>
// //
import Verify from '@/components/verifition/Verify' // import Verify from '@/components/verifition/Verify'
export default { export default {
name: 'App', name: 'App',
components: { components: {
Verify },
data() {
return {
radio: 3
}
}, },
created() { created() {
}, },
@ -34,3 +37,8 @@ export default {
} }
} }
</script> </script>
<style scoped>
.el-radio {
display: block;
}
</style>

Loading…
Cancel
Save