diff --git a/build/webpack.dev.config.js b/build/webpack.dev.config.js index 00d2bf9c..dfced552 100644 --- a/build/webpack.dev.config.js +++ b/build/webpack.dev.config.js @@ -44,12 +44,13 @@ module.exports = { contentBase: [path.resolve("dev/projects")] }, entry: { - full: path.resolve("dev", "projects", "full", "main.js"), basic: path.resolve("dev", "projects", "basic", "main.js"), - mselect: path.resolve("dev", "projects", "multiselect", "main.js"), + checklist: path.resolve("dev", "projects", "checklist", "main.js"), + custom: path.resolve("dev", "projects", "custom", "main.js"), + full: path.resolve("dev", "projects", "full", "main.js"), grouping: path.resolve("dev", "projects", "grouping", "main.js"), + mselect: path.resolve("dev", "projects", "multiselect", "main.js"), multi: path.resolve("dev", "projects", "multi", "main.js"), - checklist: path.resolve("dev", "projects", "checklist", "main.js"), picker: path.resolve("dev", "projects", "picker", "main.js") }, diff --git a/dev/projects/custom/app.vue b/dev/projects/custom/app.vue new file mode 100644 index 00000000..d08fef52 --- /dev/null +++ b/dev/projects/custom/app.vue @@ -0,0 +1,251 @@ + + + + + diff --git a/dev/projects/custom/index.html b/dev/projects/custom/index.html new file mode 100644 index 00000000..22dec0f7 --- /dev/null +++ b/dev/projects/custom/index.html @@ -0,0 +1,18 @@ + + + + + + vue-form-generator multiple forms demo + + + + + +
+
+ + + + diff --git a/dev/projects/custom/main.js b/dev/projects/custom/main.js new file mode 100644 index 00000000..b63543ee --- /dev/null +++ b/dev/projects/custom/main.js @@ -0,0 +1,9 @@ +import Vue from "vue"; +import VueFormGenerator from "../../../src"; +Vue.use(VueFormGenerator); + +import App from "./app.vue"; + +new Vue({ + ...App +}).$mount("#app"); diff --git a/dev/projects/full/app.vue b/dev/projects/full/app.vue index cbc5b439..a7a041f0 100644 --- a/dev/projects/full/app.vue +++ b/dev/projects/full/app.vue @@ -22,7 +22,9 @@ {{ item.error }} - + + +

diff --git a/dev/projects/full/schema.js b/dev/projects/full/schema.js
index 3ba4aa64..c104c61f 100644
--- a/dev/projects/full/schema.js
+++ b/dev/projects/full/schema.js
@@ -43,7 +43,7 @@ export default {
 			required: true,
 			help: "First name of user",
 			validator: validators.string,
-			fieldClasses: "half-width",
+			styleClasses: "half-width col-xs-12 col-sm-6",
 			fieldOptions: {
 				inputType: "text"
 			},
@@ -61,7 +61,7 @@ export default {
 			placeholder: "User's last name",
 			featured: true,
 			required: true,
-			fieldClasses: "half-width",
+			styleClasses: "half-width col-xs-12 col-sm-6",
 			fieldOptions: {
 				inputType: "text"
 			},
diff --git a/package-lock.json b/package-lock.json
index f7f16a62..f4b3d0d3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3404,7 +3404,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         },
@@ -3662,7 +3662,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         },
@@ -3842,7 +3842,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         },
@@ -4798,6 +4798,12 @@
         "tapable": "0.2.8"
       }
     },
+    "entities": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+      "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+      "dev": true
+    },
     "eonasdan-bootstrap-datetimepicker": {
       "version": "4.17.47",
       "resolved": "https://registry.npmjs.org/eonasdan-bootstrap-datetimepicker/-/eonasdan-bootstrap-datetimepicker-4.17.47.tgz",
@@ -6674,7 +6680,8 @@
         "jsbn": {
           "version": "0.1.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "json-schema": {
           "version": "0.2.3",
@@ -7378,7 +7385,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         },
@@ -7547,7 +7554,7 @@
         },
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         },
@@ -7955,6 +7962,12 @@
       "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
       "dev": true
     },
+    "highlight.js": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz",
+      "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=",
+      "dev": true
+    },
     "hmac-drbg": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -9514,6 +9527,15 @@
       "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==",
       "dev": true
     },
+    "katex": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz",
+      "integrity": "sha1-EkGOCRIcBckgQbazuftrqyE8tvM=",
+      "dev": true,
+      "requires": {
+        "match-at": "0.1.1"
+      }
+    },
     "killable": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
@@ -9575,6 +9597,15 @@
         "type-check": "0.3.2"
       }
     },
+    "linkify-it": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz",
+      "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=",
+      "dev": true,
+      "requires": {
+        "uc.micro": "1.0.5"
+      }
+    },
     "load-json-file": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
@@ -10080,6 +10111,106 @@
         "object-visit": "1.0.1"
       }
     },
+    "markdown-it": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz",
+      "integrity": "sha1-ztA39Ec+6fUVOsQU933IPJG6knw=",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.9",
+        "entities": "1.1.1",
+        "linkify-it": "1.2.4",
+        "mdurl": "1.0.1",
+        "uc.micro": "1.0.5"
+      }
+    },
+    "markdown-it-abbr": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
+      "integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g=",
+      "dev": true
+    },
+    "markdown-it-deflist": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz",
+      "integrity": "sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw==",
+      "dev": true
+    },
+    "markdown-it-emoji": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
+      "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=",
+      "dev": true
+    },
+    "markdown-it-footnote": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-2.0.0.tgz",
+      "integrity": "sha1-FOnE9o/xLPNU+jZa43gnboEEypQ=",
+      "dev": true
+    },
+    "markdown-it-ins": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz",
+      "integrity": "sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM=",
+      "dev": true
+    },
+    "markdown-it-katex": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz",
+      "integrity": "sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk=",
+      "dev": true,
+      "requires": {
+        "katex": "0.6.0"
+      }
+    },
+    "markdown-it-mark": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz",
+      "integrity": "sha1-RqGqlHEFrtgYiXjgoBYXnkBPQsc=",
+      "dev": true
+    },
+    "markdown-it-sub": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
+      "integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g=",
+      "dev": true
+    },
+    "markdown-it-sup": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
+      "integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M=",
+      "dev": true
+    },
+    "markdown-it-task-lists": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
+      "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==",
+      "dev": true
+    },
+    "markdown-it-toc-and-anchor": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/markdown-it-toc-and-anchor/-/markdown-it-toc-and-anchor-4.1.2.tgz",
+      "integrity": "sha1-snH2lKcL9xnmtygFbXvZMdNkIU0=",
+      "dev": true,
+      "requires": {
+        "clone": "2.1.2",
+        "uslug": "1.0.4"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "dev": true
+        }
+      }
+    },
+    "match-at": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/match-at/-/match-at-0.1.1.tgz",
+      "integrity": "sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q==",
+      "dev": true
+    },
     "matched": {
       "version": "0.4.4",
       "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
@@ -10177,6 +10308,12 @@
         "inherits": "2.0.3"
       }
     },
+    "mdurl": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+      "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+      "dev": true
+    },
     "media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -17849,6 +17986,12 @@
         }
       }
     },
+    "uc.micro": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz",
+      "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==",
+      "dev": true
+    },
     "uglify-js": {
       "version": "2.8.29",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
@@ -17947,6 +18090,12 @@
       "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
       "dev": true
     },
+    "unorm": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz",
+      "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=",
+      "dev": true
+    },
     "unpipe": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -18161,6 +18310,15 @@
         }
       }
     },
+    "uslug": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
+      "integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
+      "dev": true,
+      "requires": {
+        "unorm": "1.4.1"
+      }
+    },
     "util": {
       "version": "0.10.4",
       "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
@@ -18308,6 +18466,27 @@
         "vue-template-es2015-compiler": "1.6.0"
       }
     },
+    "vue-markdown": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/vue-markdown/-/vue-markdown-2.2.4.tgz",
+      "integrity": "sha512-hoTX/W1UIdHZrp/b0vpHSsJXAEfWsafaQLgtE2VX4gY8O/C3L2Gabqu95gyG429rL4ML1SwGv+xsPABX7yfFIQ==",
+      "dev": true,
+      "requires": {
+        "highlight.js": "9.12.0",
+        "markdown-it": "6.1.1",
+        "markdown-it-abbr": "1.0.4",
+        "markdown-it-deflist": "2.0.3",
+        "markdown-it-emoji": "1.4.0",
+        "markdown-it-footnote": "2.0.0",
+        "markdown-it-ins": "2.0.0",
+        "markdown-it-katex": "2.0.3",
+        "markdown-it-mark": "2.0.0",
+        "markdown-it-sub": "1.0.0",
+        "markdown-it-sup": "1.0.0",
+        "markdown-it-task-lists": "2.1.1",
+        "markdown-it-toc-and-anchor": "4.1.2"
+      }
+    },
     "vue-multiselect": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.0.tgz",
diff --git a/package.json b/package.json
index 95988d5b..b43b9b7b 100644
--- a/package.json
+++ b/package.json
@@ -106,6 +106,7 @@
 		"url-loader": "1.1.1",
 		"vue": "2.5.17",
 		"vue-loader": "14.2.2",
+		"vue-markdown": "^2.2.4",
 		"vue-multiselect": "2.1.0",
 		"vue-style-loader": "4.1.2",
 		"vue-template-compiler": "2.5.17",
diff --git a/src/fields/abstractField.js b/src/fields/abstractField.js
index 84a32842..b9d0afd5 100644
--- a/src/fields/abstractField.js
+++ b/src/fields/abstractField.js
@@ -46,6 +46,7 @@ export default {
 		const fieldUID = uniqueId(this.fieldID + "_");
 		return {
 			fieldUID,
+			touched: false,
 			errors: [],
 			debouncedValidateFunc: null,
 			debouncedFormatFunction: null
@@ -75,6 +76,8 @@ export default {
 			},
 
 			set(newValue) {
+				this.touch();
+
 				let oldValue = this.value;
 				newValue = this.formatValueToModel(newValue);
 
@@ -133,6 +136,8 @@ export default {
 			}
 		},
 		validate() {
+			this.touch();
+
 			this.clearValidationErrors();
 			let validateAsync = objGet(this.formOptions, "validateAsync", false);
 
@@ -277,6 +282,13 @@ export default {
 
 		formatValueToModel(value) {
 			return value;
+		},
+
+		touch() {
+			if (!this.touched) {
+				this.touched = true;
+				this.$emit("field-touched");
+			}
 		}
 	},
 	created() {
diff --git a/src/formElement.vue b/src/formElement.vue
index 600c5f46..4bec410d 100644
--- a/src/formElement.vue
+++ b/src/formElement.vue
@@ -1,25 +1,24 @@