├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── deploy.sh ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── fetch-data.js │ └── index.js ├── assets │ ├── 1.gif │ ├── 2.gif │ ├── 3.gif │ ├── 4.gif │ ├── logo.png │ └── scss │ │ ├── _styles.scss │ │ ├── _var.scss │ │ └── main.scss ├── components │ └── form_elements │ │ ├── Elements.vue │ │ ├── FormElementButton.vue │ │ ├── FormElementCarousel.vue │ │ ├── FormElementCheckbox.vue │ │ ├── FormElementDatePicker.vue │ │ ├── FormElementDatetimePicker.vue │ │ ├── FormElementHtml.vue │ │ ├── FormElementLongTextInput.vue │ │ ├── FormElementNumberInput.vue │ │ ├── FormElementRadioButton.vue │ │ ├── FormElementRating.vue │ │ ├── FormElementSelectList.vue │ │ ├── FormElementSwitch.vue │ │ ├── FormElementTable.vue │ │ ├── FormElementTextInput.vue │ │ ├── FormElementTimePicker.vue │ │ ├── FormElementUpload.vue │ │ ├── formbuilder.js │ │ └── properties │ │ ├── CarouselAdvancedProp.vue │ │ ├── HtmlAdvancedProps.vue │ │ ├── NumberInputAdvancedProps.vue │ │ ├── OptionsAdvancedProps.vue │ │ ├── Properties.vue │ │ ├── RatingAdvancedProps.vue │ │ ├── SelectListAdvancedProps.vue │ │ └── TextInputAdvancedProps.vue ├── main.js ├── router.js ├── store.js └── views │ ├── Home.vue │ └── Preview.vue └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-formbuilder2.0 2 | 3 | Basic code was clone from https://github.com/jmeei/vue-formbuilder, and did some improve. 4 | 5 | ![alt text](https://github.com/qiaoxun/vue-formbuilder/blob/master/src/assets/1.gif) 6 | ![alt text](https://github.com/qiaoxun/vue-formbuilder/blob/master/src/assets/2.gif) 7 | ![alt text](https://github.com/qiaoxun/vue-formbuilder/blob/master/src/assets/3.gif) 8 | 9 | ![alt text](https://github.com/qiaoxun/vue-formbuilder/blob/master/src/assets/4.gif) 10 | 11 | ## Project setup 12 | ``` 13 | npm install 14 | ``` 15 | 16 | ### Compiles and hot-reloads for development 17 | ``` 18 | npm run serve 19 | ``` 20 | 21 | ### Compiles and minifies for production 22 | ``` 23 | npm run build 24 | ``` 25 | 26 | ### Run your tests 27 | ``` 28 | npm run test 29 | ``` 30 | 31 | ### Lints and fixes files 32 | ``` 33 | npm run lint 34 | ``` 35 | 36 | ### Customize configuration 37 | See [Configuration Reference](https://cli.vuejs.org/config/). 38 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # build 3 | npm run build 4 | 5 | # cd to dist folder 6 | cd dist 7 | 8 | # push code to gh-pages branch 9 | git init 10 | git add . 11 | git commit -m "gh-pages" 12 | 13 | git push -f git@github.com:qiaoxun/vue-formbuilder.git master:gh-pages -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-formbuilder2.0", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.18.1", 12 | "core-js": "^2.6.5", 13 | "element-ui": "^2.8.2", 14 | "vue": "^2.6.10", 15 | "vue-lodash": "^2.0.2", 16 | "vue-router": "^3.0.3", 17 | "vue-stash": "^2.0.1-beta", 18 | "vuedraggable": "^2.20.0" 19 | }, 20 | "devDependencies": { 21 | "@vue/cli-plugin-babel": "^3.7.0", 22 | "@vue/cli-plugin-eslint": "^3.7.0", 23 | "@vue/cli-service": "^3.7.0", 24 | "babel-eslint": "^10.0.1", 25 | "css-loader": "^2.1.1", 26 | "eslint": "^5.16.0", 27 | "eslint-plugin-vue": "^5.0.0", 28 | "node-sass": "^4.12.0", 29 | "sass-loader": "^7.1.0", 30 | "tar": "^4.4.8", 31 | "vue-loader": "^15.7.0", 32 | "vue-style-loader": "^4.1.2", 33 | "vue-template-compiler": "^2.5.21" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-formbuilder2.0 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /src/api/fetch-data.js: -------------------------------------------------------------------------------- 1 | import {fetch} from "./index"; 2 | 3 | export default { 4 | getJsonData(url, params){ 5 | return fetch(url, params); 6 | }, 7 | fetchOptionsData(url, labelField, valueField, params) { 8 | let promise = fetch(url, params).then((data) => { 9 | if (data && data.length > 0) { 10 | let options = []; 11 | data.forEach((ele) => { 12 | let obj = {}; 13 | obj.optionLabel = ele[labelField]; 14 | obj.optionValue = ele[valueField]; 15 | obj.disabled = ele.disabled; 16 | options.push(obj); 17 | }); 18 | return options; 19 | } 20 | }); 21 | return promise; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | // response time 4 | axios.defaults.timeout = 20000; 5 | // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; 6 | // axios.defaults.baseURL = '/'; //Base URL 7 | 8 | // axios.interceptors.request.use((config) => { 9 | // //before send 10 | // if (config.method === 'post') { 11 | // config.data = qs.stringify(config.data, { 12 | // arrayFormat: 'repeat' 13 | // }); 14 | // } 15 | // return config; 16 | // }, (error) => { 17 | // this.$message.error('Oops, this is a error.'); 18 | // return Promise.reject(error); 19 | // }); 20 | 21 | axios.interceptors.response.use((res) => { 22 | if (res.status != 200) { 23 | // _.toast(res.data.msg); 24 | return Promise.reject(res); 25 | // var exception = new CommonException('HTTP Error', 1); 26 | // throw exception; 27 | } 28 | return res; 29 | }, (error) => { 30 | console.log(error.status); 31 | if (error.response) { 32 | if (error.response.status == 401) { 33 | this.$message.error('Oops, this is a error.'); 34 | return; 35 | } 36 | } else { 37 | // Something happened in setting up the request that triggered an Error 38 | console.log('Error', error.message); 39 | } 40 | return reject(error); 41 | }); 42 | //return Promise 43 | export function fetch(url, params) { 44 | return new Promise((resolve, reject) => { 45 | axios.post(url, params) 46 | .then(response => { 47 | if (response) resolve(response.data); 48 | }, err => { 49 | console.log(err); 50 | }) 51 | .catch((error) => { 52 | console.log(error); 53 | reject(error) 54 | }) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /src/assets/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/src/assets/1.gif -------------------------------------------------------------------------------- /src/assets/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/src/assets/2.gif -------------------------------------------------------------------------------- /src/assets/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/src/assets/3.gif -------------------------------------------------------------------------------- /src/assets/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/src/assets/4.gif -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaoxun/vue-formbuilder/f9bf903329c24b13e1907d3898ba4497ac990bc4/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/scss/_styles.scss: -------------------------------------------------------------------------------- 1 | // Reset css 2 | // html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote{&:before,&:after{content:'';content:none}}q{&:before,&:after{content:'';content:none}}table{border-collapse:collapse;border-spacing:0} 3 | // Layout 4 | 5 | body { 6 | font-family: 'Roboto', monospace; 7 | } 8 | 9 | 10 | .app-wrapper { 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | position: relative; 15 | } 16 | 17 | .el-main { 18 | padding: 0; 19 | overflow: hidden; 20 | } 21 | 22 | .wrapper--snippet { 23 | height: 19vh; 24 | background: #6cf2ce; 25 | overflow: auto; 26 | 27 | pre { 28 | padding: 20px; 29 | color: #6cf2ce; 30 | line-height: 1.3; 31 | } 32 | } 33 | 34 | // Forms 35 | 36 | .wrapper--forms { 37 | padding: 30px; 38 | position: relative; 39 | height: 90%; 40 | overflow: auto; 41 | } 42 | 43 | // Sidebar 44 | 45 | .wrapper--sidebar { 46 | padding: 30px; 47 | 48 | .el-tabs { 49 | min-height: 450px; 50 | border-bottom: 0; 51 | } 52 | 53 | .el-tabs__header { 54 | margin-bottom: 0; 55 | } 56 | 57 | .el-tabs__content { 58 | padding: 0; 59 | } 60 | 61 | .el-tabs__inner { 62 | padding: 20px; 63 | } 64 | 65 | .el-tabs__nav { 66 | float: none; 67 | 68 | .el-tabs__item { 69 | width: 33.33%; 70 | text-align: center; 71 | } 72 | } 73 | 74 | .el-tabs--border-card { 75 | border: 1px solid gray; 76 | } 77 | 78 | .el-form-item__label { 79 | line-height: 1; 80 | } 81 | } 82 | 83 | .el-input-number { 84 | width: auto !important; 85 | } 86 | 87 | .el-date-editor.el-input, .el-date-editor.el-input__inner { 88 | width: auto !important; 89 | } 90 | 91 | // Preview 92 | .preview__wrapper { 93 | max-width: 600px; 94 | margin-left: auto; 95 | margin-right: auto; 96 | } 97 | 98 | .el-form-item { 99 | padding: 10px; 100 | margin-bottom: 0; 101 | } 102 | -------------------------------------------------------------------------------- /src/assets/scss/_var.scss: -------------------------------------------------------------------------------- 1 | /* theme color */ 2 | $--color-primary: #409EFF; 3 | 4 | /* icon font path, required */ 5 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 6 | 7 | /* component background*/ 8 | // $--background: #ECF5FF; 9 | 10 | /* component border-color*/ 11 | // $--border-color: #409EFF; 12 | 13 | /* component font color*/ 14 | // $--color: #3A8EE6 15 | 16 | /* transition time */ 17 | $animationDuration: 0.1s; 18 | 19 | // the :export directive is the magic sauce for webpack 20 | // https://blog.bluematador.com/posts/how-to-share-variables-between-js-and-sass/ 21 | // :export { 22 | // whitecolor: $--color-primary; 23 | // } 24 | -------------------------------------------------------------------------------- /src/assets/scss/main.scss: -------------------------------------------------------------------------------- 1 | // Base - by Element UI 2 | @import "_var"; 3 | 4 | // Styles 5 | @import "_styles"; 6 | // @import "_theming"; 7 | -------------------------------------------------------------------------------- /src/components/form_elements/Elements.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 54 | 55 | 92 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementButton.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementCarousel.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 20 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementCheckbox.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 33 | 34 | 39 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementDatePicker.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 23 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementDatetimePicker.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 23 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementHtml.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementLongTextInput.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 20 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementNumberInput.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 35 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementRadioButton.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 33 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementRating.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 28 | 29 | 34 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementSelectList.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 82 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementSwitch.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 20 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementTable.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 67 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementTextInput.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 48 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementTimePicker.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 24 | -------------------------------------------------------------------------------- /src/components/form_elements/FormElementUpload.vue: -------------------------------------------------------------------------------- 1 | 9 | 34 | -------------------------------------------------------------------------------- /src/components/form_elements/formbuilder.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | import draggable from 'vuedraggable' 4 | 5 | import TextInput from '@/components/form_elements/FormElementTextInput' 6 | import LongTextInput from '@/components/form_elements/FormElementLongTextInput' 7 | import NumberInput from '@/components/form_elements/FormElementNumberInput' 8 | import SelectList from '@/components/form_elements/FormElementSelectList' 9 | import RadioButton from '@/components/form_elements/FormElementRadioButton' 10 | import Checkbox from '@/components/form_elements/FormElementCheckbox' 11 | import TimePicker from '@/components/form_elements/FormElementTimePicker' 12 | import DatePicker from '@/components/form_elements/FormElementDatePicker' 13 | import DatetimePicker from '@/components/form_elements/FormElementDatetimePicker' 14 | import Rating from '@/components/form_elements/FormElementRating' 15 | import Button from '@/components/form_elements/FormElementButton' 16 | import Carousel from '@/components/form_elements/FormElementCarousel' 17 | import Upload from '@/components/form_elements/FormElementUpload' 18 | import ElSwitch from '@/components/form_elements/FormElementSwitch' 19 | import TableComponent from '@/components/form_elements/FormElementTable' 20 | import HtmlComponent from '@/components/form_elements/FormElementHtml' 21 | 22 | import Elements from '@/components/form_elements/Elements' 23 | import Properties from '@/components/form_elements/properties/Properties' 24 | 25 | import vm from '@/main' 26 | 27 | export const FormBuilder = new Vue({ 28 | components: { 29 | Elements, 30 | Properties, 31 | draggable, 32 | TextInput, 33 | LongTextInput, 34 | NumberInput, 35 | SelectList, 36 | RadioButton, 37 | Checkbox, 38 | TimePicker, 39 | DatePicker, 40 | DatetimePicker, 41 | Rating, 42 | Button, 43 | Carousel, 44 | Upload, 45 | ElSwitch, 46 | TableComponent, 47 | HtmlComponent 48 | }, 49 | data() { 50 | return { 51 | fields: [{ 52 | fieldType: 'TextInput', 53 | label: 'Text', 54 | text: 'Text', 55 | group: 'form', //form group 56 | isRequired: false, 57 | isHelpBlockVisible: false, 58 | isPlaceholderVisible: true, 59 | isUnique: false, 60 | span: 8, 61 | labelWidth: 100, 62 | advancedOptions: true, 63 | showPassword: false, 64 | disabled: false, 65 | clearable: false, 66 | prepend: '', 67 | append: '', 68 | maxlength: 10, 69 | showWordLimit: false 70 | }, 71 | { 72 | fieldType: 'LongTextInput', 73 | label: 'Long Text', 74 | text: 'Long Text', 75 | group: 'form', 76 | isRequired: false, 77 | isHelpBlockVisible: false, 78 | isPlaceholderVisible: true, 79 | isUnique: false, 80 | span: 24, 81 | labelWidth: 100 82 | }, 83 | { 84 | fieldType: 'NumberInput', 85 | label: 'Number', 86 | text: 'Number', 87 | group: 'form', 88 | isRequired: false, 89 | isHelpBlockVisible: false, 90 | isPlaceholderVisible: false, 91 | isUnique: false, 92 | span: 8, 93 | labelWidth: 100, 94 | advancedOptions: true, 95 | disabled: false, 96 | stepStrictly: false, 97 | step: 1, 98 | hasMinValue: false, 99 | min: 1, 100 | hasMaxValue: false, 101 | max: 10, 102 | }, 103 | { 104 | fieldType: 'SelectList', 105 | label: 'Select', 106 | text: 'Select', 107 | group: 'form', 108 | isRequired: false, 109 | isHelpBlockVisible: false, 110 | isPlaceholderVisible: false, 111 | isUnique: false, 112 | span: 8, 113 | labelWidth: 100, 114 | isFromUrl: false, 115 | dataUrl: '', 116 | options: [{ 117 | optionLabel: "Option Label 1", 118 | optionValue: "Option 1" 119 | }, 120 | { 121 | optionLabel: "Option Label 2", 122 | optionValue: "Option 2" 123 | } 124 | ], 125 | advancedOptions: true, 126 | dataUrl: '', 127 | labelField: 'label', 128 | valueField: 'value', 129 | disabled: false, 130 | clearable: false, 131 | multiple: false, 132 | filterable: false, 133 | remote: false 134 | }, 135 | { 136 | fieldType: 'RadioButton', 137 | label: 'Radio', 138 | text: 'Radio', 139 | group: 'form', 140 | isRequired: false, 141 | isHelpBlockVisible: false, 142 | isPlaceholderVisible: false, 143 | isUnique: false, 144 | span: 8, 145 | labelWidth: 100, 146 | isFromUrl: false, 147 | options: [{ 148 | optionLabel: "Option Label 1", 149 | optionValue: "Option 1" 150 | }, 151 | { 152 | optionLabel: "Option Label 2", 153 | optionValue: "Option 2" 154 | } 155 | ], 156 | advancedOptions: true, 157 | dataUrl: '', 158 | labelField: 'label', 159 | valueField: 'value' 160 | }, 161 | { 162 | fieldType: 'Checkbox', 163 | label: 'Checkbox', 164 | text: 'Checkbox', 165 | group: 'form', 166 | isRequired: false, 167 | isHelpBlockVisible: false, 168 | isPlaceholderVisible: false, 169 | isUnique: false, 170 | span: 8, 171 | labelWidth: 100, 172 | isFromUrl: false, 173 | options: [{ 174 | optionLabel: "Option Label 1", 175 | optionValue: "Option 1" 176 | }, 177 | { 178 | optionLabel: "Option Label 2", 179 | optionValue: "Option 2" 180 | } 181 | ], 182 | advancedOptions: true, 183 | dataUrl: '', 184 | labelField: 'label', 185 | valueField: 'value' 186 | }, 187 | { 188 | fieldType: 'TimePicker', 189 | label: 'Time', 190 | text: 'Time', 191 | group: 'form', 192 | isRequired: false, 193 | isHelpBlockVisible: false, 194 | isPlaceholderVisible: false, 195 | isUnique: false, 196 | span: 8, 197 | labelWidth: 100 198 | }, 199 | { 200 | fieldType: 'DatePicker', 201 | label: 'Date', 202 | text: 'Date', 203 | group: 'form', 204 | isRequired: false, 205 | isHelpBlockVisible: false, 206 | isPlaceholderVisible: false, 207 | isUnique: false, 208 | span: 8, 209 | labelWidth: 100 210 | }, 211 | { 212 | fieldType: 'DatetimePicker', 213 | label: 'Date time', 214 | text: 'Date-Time', 215 | group: 'form', 216 | isRequired: false, 217 | isHelpBlockVisible: false, 218 | isPlaceholderVisible: false, 219 | isUnique: false, 220 | span: 8, 221 | labelWidth: 100 222 | }, 223 | { 224 | fieldType: 'Rating', 225 | label: 'Rating', 226 | text: 'Rating', 227 | group: 'form', 228 | isRequired: false, 229 | isHelpBlockVisible: false, 230 | isPlaceholderVisible: false, 231 | isUnique: false, 232 | span: 8, 233 | labelWidth: 100, 234 | advancedOptions: true, 235 | rateValue: 0, 236 | showText: true, 237 | disabled: false, 238 | showScore: false, 239 | scoreUnit: 'points', 240 | colors: ['#AAAAAA', '#F7BA2A', '#FF9900'], 241 | texts: ['oops', 'disappointed', 'normal', 'good', 'great'] 242 | }, 243 | { 244 | fieldType: 'ElSwitch', 245 | label: 'Switch', 246 | text: 'Switch', 247 | group: 'form', 248 | isUnique: false, 249 | span: 8, 250 | labelWidth: 100, 251 | activeText: '', 252 | inActiveText: '' 253 | }, 254 | { 255 | fieldType: 'Button', 256 | text: 'Button', 257 | group: 'button', 258 | buttonText: 'Submit your form', 259 | isRequired: false, 260 | isHelpBlockVisible: false, 261 | isPlaceholderVisible: false, 262 | isUnique: true, 263 | span: 8, 264 | labelWidth: 100 265 | }, 266 | { 267 | fieldType: 'Carousel', 268 | text: 'Carousel', 269 | group: 'static', 270 | isUnique: false, 271 | span: 24, 272 | labelWidth: 100, 273 | controlHeight: 150, 274 | itemsNumber: 4, 275 | items: [{ 276 | url:'' 277 | }] 278 | }, 279 | { 280 | fieldType: 'Upload', 281 | text: 'UploadFiles', 282 | group: 'form', 283 | isUnique: false, 284 | span: 24, 285 | uploadURL: 'https://jsonplaceholder.typicode.com/posts/' 286 | }, 287 | { 288 | fieldType: 'TableComponent', 289 | text: 'Table', 290 | group: 'form', 291 | isUnique: false, 292 | span: 24, 293 | tableColumns: [{ 294 | prop: 'date', 295 | label: 'Date', 296 | width: 180 297 | }, { 298 | prop: 'name', 299 | label: 'Name', 300 | width: 180 301 | }, { 302 | prop: 'address', 303 | label: 'Address' 304 | }], 305 | tableDatas: [{ 306 | id: 1, 307 | edit: false, 308 | date: '2016-05-03', 309 | name: 'Tom', 310 | address: 'No. 189, Grove St, Los Angeles' 311 | }] 312 | }, 313 | { 314 | fieldType: 'HtmlComponent', 315 | text: 'Html', 316 | group: 'static', 317 | isUnique: false, 318 | span: 24, 319 | htmlContent: '

Hello World

', 320 | advancedOptions: '' 321 | } 322 | ], 323 | 324 | sortElementOptions: { 325 | group: { 326 | name: 'formbuilder', 327 | pull: false, 328 | put: true 329 | }, 330 | sort: true 331 | }, 332 | 333 | dropElementOptions: { 334 | group: { 335 | name: 'formbuilder', 336 | pull: 'clone', 337 | put: false 338 | }, 339 | sort: false, 340 | filter: ".is-disabled" 341 | } 342 | } 343 | }, 344 | methods: { 345 | deleteElement(index, form) { 346 | vm.$store.activeField = []; 347 | vm.$store.activeTabForFields = "elements"; 348 | vm.$delete(form, index); 349 | }, 350 | 351 | cloneElement(index, field, form) { 352 | var cloned = _.cloneDeep(field) // clone deep lodash 353 | form.splice(index, 0, cloned) 354 | }, 355 | 356 | editElementProperties(field) { 357 | vm.$store.activeField = field; 358 | vm.$store.activeTabForFields = "properties"; 359 | } 360 | } 361 | }); 362 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/CarouselAdvancedProp.vue: -------------------------------------------------------------------------------- 1 | 4 | 6 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/HtmlAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/NumberInputAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 50 | 56 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/OptionsAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 36 | 75 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/Properties.vue: -------------------------------------------------------------------------------- 1 | 205 | 206 | 289 | 290 | 300 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/RatingAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 55 | 80 | 81 | 91 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/SelectListAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 65 | -------------------------------------------------------------------------------- /src/components/form_elements/properties/TextInputAdvancedProps.vue: -------------------------------------------------------------------------------- 1 | 49 | 72 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | 4 | // ================ 5 | // Use Element UI 6 | // ---------------- 7 | import Element from 'element-ui' 8 | import 'element-ui/lib/theme-chalk/index.css'; 9 | import locale from 'element-ui/lib/locale/lang/en' // Default lang is Chinese 10 | Vue.use(Element, { locale }) 11 | import './assets/scss/main.scss' 12 | 13 | import App from './App' 14 | 15 | 16 | // ================ 17 | // Lodash 18 | // ---------------- 19 | import VueLodash from 'vue-lodash' 20 | Vue.use(VueLodash) 21 | 22 | // ================ 23 | // Use Vue Router 24 | // ---------------- 25 | import router from './router' 26 | 27 | 28 | // ================ 29 | // Vue-stash aka simple vuex alternative 30 | // ---------------- 31 | import VueStash from 'vue-stash' 32 | import store from './store' 33 | Vue.use(VueStash) 34 | 35 | 36 | 37 | Vue.config.productionTip = false 38 | 39 | var vm = new Vue({ 40 | el: '#app', 41 | router, 42 | data: { store }, 43 | render: h => h(App) 44 | }).$mount('#app') 45 | 46 | export default vm; 47 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Home from './views/Home.vue' 4 | 5 | Vue.use(Router) 6 | 7 | export default new Router({ 8 | mode: 'history', 9 | base: process.env.BASE_URL, 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'home', 14 | component: Home 15 | }, 16 | { 17 | path: '/preview', 18 | name: 'preview', 19 | // route level code-splitting 20 | // this generates a separate chunk (about.[hash].js) for this route 21 | // which is lazy-loaded when the route is visited. 22 | component: () => import(/* webpackChunkName: "about" */ './views/Preview.vue') 23 | } 24 | ] 25 | }) 26 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | export default { 2 | forms: [], 3 | activeField: [], 4 | activeTabForFields: 'elements' 5 | } 6 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 78 | 79 | 129 | 130 | 131 | 229 | -------------------------------------------------------------------------------- /src/views/Preview.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 64 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publicPath: process.env.NODE_ENV === "production" ? "./" : "/" 3 | }; 4 | --------------------------------------------------------------------------------