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 @@
+
+
+
Custom label, help, hint and errors (with grouping)
+
+
+
+
+
+ {{ field.label }}
+
+
+
+
+ Need help
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Custom errors
+
+
+
+
+ Index |
+ Error |
+
+
+
+
+ {{index}} |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
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 @@