├── .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 | 
6 | 
7 | 
8 |
9 | 
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 |
2 |
8 |
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 |
2 |
3 |
4 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
54 |
55 |
92 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ currentField.buttonText }}
4 |
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementCarousel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
20 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
33 |
34 |
39 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementDatePicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementDatetimePicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementHtml.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementLongTextInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
20 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementNumberInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
35 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementRadioButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
33 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementRating.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
28 |
29 |
34 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementSelectList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
82 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementSwitch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
20 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Add
5 | Delete
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{ scope.row[column.prop] }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
67 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementTextInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ currentField.prepend }}
5 | {{ currentField.append }}
6 |
7 |
8 |
9 |
10 |
48 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementTimePicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
--------------------------------------------------------------------------------
/src/components/form_elements/FormElementUpload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Click to upload
5 | jpg/png files with a size less than 500kb
6 |
7 |
8 |
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 |
2 |
3 |
4 |
6 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/HtmlAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{activeField.htmlContent}}
4 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/NumberInputAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/OptionsAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{activeField.htmlContent}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Fetch Data
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
75 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/Properties.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{activeField.label}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | {{activeField.placeholder}}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {{activeField.buttonText}}
51 |
52 |
53 |
54 |
55 |
56 | {{activeField.fieldText}}
57 |
58 |
59 |
60 |
61 |
67 |
68 |
69 |
70 | {{activeField.activeText}}
71 |
72 |
73 |
74 |
75 | {{activeField.inActiveText}}
76 |
77 |
78 |
79 |
80 |
81 | {{activeField.uploadURL}}
82 |
83 |
84 |
85 |
86 |
87 |
88 | {{item.url}}
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Add more
100 |
101 |
102 |
103 |
104 |
105 | -
106 |
107 |
108 | Label
109 |
110 |
111 | Value
112 |
113 |
114 |
115 |
116 |
117 | -
118 |
119 |
120 | {{item.optionLabel}}
121 |
122 |
123 | {{item.optionValue}}
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 | Add more
136 |
137 |
138 |
139 |
140 |
141 | -
142 |
143 |
144 | Prop
145 |
146 |
147 | Label
148 |
149 |
150 | Width
151 |
152 |
153 |
154 |
155 |
156 | -
157 |
158 |
159 | {{column.prop}}
160 |
161 |
162 | {{column.label}}
163 |
164 |
165 | {{column.width}}
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 | Add more
178 |
179 |
180 |
181 |
182 | {{activeField.htmlContent}}
183 |
184 |
185 |
186 | Advanced Options
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
289 |
290 |
300 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/RatingAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
80 |
81 |
91 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/SelectListAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
65 |
--------------------------------------------------------------------------------
/src/components/form_elements/properties/TextInputAdvancedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
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 |
2 |
3 |
4 |
5 |
59 |
60 |
61 |
62 |
75 |
76 |
77 |
78 |
79 |
129 |
130 |
131 |
229 |
--------------------------------------------------------------------------------
/src/views/Preview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ eachFormObj.title }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
64 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | publicPath: process.env.NODE_ENV === "production" ? "./" : "/"
3 | };
4 |
--------------------------------------------------------------------------------