├── .babelrc
├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── .prettierrc
├── README.md
├── book.json
├── docs
├── README.md
├── SUMMARY.md
├── api
│ ├── components.md
│ ├── options.md
│ ├── options
│ │ └── ajv.md
│ ├── schema.md
│ ├── ui-schema.md
│ ├── ui-schema
│ │ ├── field.md
│ │ └── field
│ │ │ ├── children.md
│ │ │ ├── component.md
│ │ │ ├── display-options.md
│ │ │ ├── dynamic-options.md
│ │ │ ├── error-handler.md
│ │ │ ├── error-options.md
│ │ │ ├── event-prop.md
│ │ │ ├── field-options.md
│ │ │ ├── field-options
│ │ │ ├── attrs.md
│ │ │ ├── class.md
│ │ │ ├── dom-props.md
│ │ │ ├── key.md
│ │ │ ├── native-on.md
│ │ │ ├── on.md
│ │ │ ├── props.md
│ │ │ ├── slot.md
│ │ │ └── style.md
│ │ │ ├── internal-model.md
│ │ │ ├── value-model.md
│ │ │ └── value-prop.md
│ └── vue-form-json-schema.md
├── getting-started.md
└── installation.md
├── examples
├── example-1
│ ├── example-one.js
│ └── index.html
├── example-2
│ ├── example-two.js
│ └── index.html
├── example-3
│ ├── example-three.js
│ ├── index.html
│ └── style.css
├── example-4
│ ├── example-four.js
│ └── index.html
├── example-5
│ ├── example-five.js
│ └── index.html
├── example-6
│ ├── example-six.js
│ ├── index.html
│ └── style.css
├── example-7
│ ├── example-seven.js
│ ├── index.html
│ └── style.css
├── example-8
│ ├── example-eight.js
│ ├── index.html
│ ├── style.css
│ └── use-form-fields.js
└── helpers
│ ├── pretty-print.css
│ └── pretty-print.js
├── package-lock.json
├── package.json
├── src
├── constants
│ └── index.js
├── index.js
├── plugin.js
├── vfjs-field-component
│ └── index.js
├── vfjs-field-mixin
│ ├── computed.js
│ ├── index.js
│ ├── methods
│ │ ├── getters.js
│ │ ├── helpers.js
│ │ ├── index.js
│ │ └── setters.js
│ └── props.js
├── vfjs-global-component
│ └── index.js
└── vfjs-global-mixin
│ ├── computed.js
│ ├── data.js
│ ├── index.js
│ ├── methods
│ ├── index.js
│ ├── vfjs-bus
│ │ ├── actions.js
│ │ └── index.js
│ ├── vfjs-helpers
│ │ └── index.js
│ ├── vfjs-lifecycle
│ │ └── index.js
│ ├── vfjs-model
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── setters.js
│ ├── vfjs-schema
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── setters.js
│ ├── vfjs-state
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── setters.js
│ ├── vfjs-ui
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── setters.js
│ └── vfjs-validation
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── setters.js
│ ├── props.js
│ └── watch.js
├── webpack.config.common.js
├── webpack.config.dev.js
└── webpack.config.prod.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["lodash"],
3 | "presets": [
4 | "@babel/env"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": "airbnb-base",
4 | "parser": "babel-eslint",
5 | "env": {
6 | "browser": true
7 | },
8 | "rules": {
9 | "max-len": [
10 | "error",
11 | {
12 | "code": 80,
13 | "ignoreComments": true
14 | }
15 | ],
16 | "arrow-parens": ["error", "always"],
17 | "no-unused-vars": [
18 | "error",
19 | {
20 | "vars": "all",
21 | "args": "none"
22 | }
23 | ],
24 | "no-plusplus": [
25 | "error",
26 | {
27 | "allowForLoopAfterthoughts": true
28 | }
29 | ],
30 | "operator-linebreak": [
31 | "error",
32 | "after",
33 | {
34 | "overrides": {
35 | "?": "before",
36 | ":": "before"
37 | }
38 | }
39 | ],
40 | "implicit-arrow-linebreak": 0,
41 | "function-paren-newline": 0
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | # Gitbook installation folder
3 | _book
4 | # Prewritten commit message
5 | COMMIT_MSG
6 | # Built files
7 | dist
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "arrowParens": "always",
4 | "singleQuote": true,
5 | "trailingComma": "all"
6 | }
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue Form JSON Schema
2 |
3 | > A [JSON schema](https://json-schema.org) based form generator, bring your components!
4 |
5 | ##### Use any Vue component or HTML element!
6 |
7 | There are *no prebuilt components* for you to puzzle your form together with. Instead you can use any component or element which emits an event, custom or native.
8 |
9 | > Note that essentially all Vue components that uses `v-model` emits an `input` (or similar) event. [See Vue's guide for more info](https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events)
10 |
11 | ## Installation
12 |
13 | ### Upgrading from v1? Check out the [v2 release notes](https://github.com/jarvelov/vue-form-json-schema/releases/tag/v2.0.0) to see if and how migration affects you.
14 |
15 | Install from npm
16 |
17 | `npm install vue-form-json-schema`
18 |
19 | Import to your app
20 |
21 | ```js
22 | import Vue from 'vue';
23 | import VueFormJsonSchema from 'vue-form-json-schema';
24 |
25 | Vue.component('vue-form-json-schema', VueFormJsonSchema);
26 | ```
27 |
28 | > Note if you're not using Webpack / Rollup and want to use the ESM version you need to import VueFormJsonSchema like this:
29 |
30 | ```js
31 | import VueFormJsonSchema from 'vue-form-json-schema/dist/vue-form-json-schema.esm.js';
32 | ```
33 |
34 | Check out the demos or see a minimal example in the [usage instructions](#usage) to get started.
35 |
36 | ### UMD
37 |
38 | > If you're using the UMD version you can find more examples in the `examples` folder of the [github repo](https://github.com/jarvelov/vue-form-json-schema/tree/master/examples) and the [UMD demo below](#umd-demos).
39 |
40 | If you want to use `vue-form-json-schema` directly in a browser you can do so by using the UMD version. The UMD version autoinstalls the `vue-form-json-schema` component if Vue is found on the window. The entire module is also available on `window.VueFormJsonSchema` where the named exports such as for example `vfjsFieldMixin` can be accessed.
41 |
42 | #### Hosted by unkpg
43 |
44 | ``
45 |
46 | You can substite `vue-form-json-schema@latest` to a fixed version, such as `vue-form-json-schema@2.3.0`
47 |
48 | #### Installed from npm
49 |
50 | ``
51 |
52 | ## Demo
53 |
54 | > Note that all demos use Bootstrap styling, but no styling is included in this package and it is up to you what styles should be used.
55 |
56 | ### [Minimal demo](https://py6611pr9m.codesandbox.io)
57 |
58 | The least amount of configuration to render an `input` element.
59 |
60 | ### [Nested UI demo](https://882w4v374l.codesandbox.io)
61 |
62 | Using Bootstrap classes to show how layout can be different for devices with different screen sizes.
63 | In this example two input fields will be wrapped inside a div with `col-12 col-sm-6` classes.
64 | Try resizing your browser window too see it in action.
65 |
66 | ### [Conditional visibility and Animation demo](https://k0q8wk946o.codesandbox.io/)
67 |
68 | Sometimes a field should only be shown if a condition is met. Uses `` to provide animation.
69 |
70 | ### [Vue components demo](https://z549j1vxx.codesandbox.io)
71 |
72 | See how to use your own or third party Vue components in `vue-form-json-schema`.
73 |
74 | ### [Vue async loading of form](https://2p51q8q14y.codesandbox.io)
75 |
76 | Loading the form from a backend? Check out this example.
77 |
78 | ### [Registration form with validation](https://4rykx7jj19.codesandbox.io)
79 |
80 | A more complete example with validation and error messages
81 |
82 | ### [Registration form example with nested properties](https://nxn8y.codesandbox.io/)
83 |
84 | The registration form above where the form model keys are nested under another key
85 |
86 | ### UMD demos
87 |
88 | All the examples above are replicated using the UMD version in the `examples` folder of this repo.
89 |
90 | [Online version of the first demo](https://jsfiddle.net/jarvelov/ewg6dfqL/)
91 |
92 | ## Features
93 |
94 | * Supports any HTML element or Vue component
95 | * Small (`32K` uncompressed, `6.5K` gzipped)
96 | * Standardized [JSON schema](json-schema.org) for annotation and validation (by [Ajv](https://github.com/epoberezkin/ajv))
97 | * Layout is independent from data structure
98 |
99 | ## Documentation
100 |
101 | [Gitbook](https://jarvelov.gitbook.io/vue-form-json-schema/)
102 |
103 | ## Usage
104 |
105 | ### Basic example with one field
106 |
107 | >For using the UMD version, check out the `examples` folder where all the demos above are replicated using the UMD version
108 |
109 | [See demo](https://codesandbox.io/s/py6611pr9m)
110 |
111 | ```js
112 |
113 |
118 |
119 |
120 |
121 |
153 | ```
154 |
155 | ### Dependencies
156 |
157 | #### Ajv
158 | For form validation using [JSON Schema](http://json-schema.org/) and internal validation
159 |
160 | #### Lodash
161 | `get`, `set` and `merge` are used throughout the package.
162 | Bundle size is very important though and is always considered and so we heavily strip down lodash to only include the absolute necessities
163 |
164 | #### Vue
165 |
166 | Tested with v2.5.9 but will probably work on any version >= v2.4.0
167 |
168 | ### TODO
169 |
170 | * Write tests
171 | * ~~Add i18n support~~
172 | * Added in 1.15.2 with `options.ajv.locale` setting
173 | * ~~Write this README~~
174 | * Use Ajv internally to validate:
175 | * `vfs-global` prop `ui-schema`
176 | * `vfs-component` prop `ui-schema`
177 | * ~~Write docs~~
178 | * ~~Publish with Gitbook~~
179 |
--------------------------------------------------------------------------------
/book.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "vue-form-json-schema",
3 | "root": "./docs",
4 | "gitbook": ">3.0.0",
5 | "plugins": ["edit-link", "github"],
6 | "pluginsConfig": {
7 | "edit-link": {
8 | "base": "https://github.com/jarvelov/vue-form-json-schema/edit/master/docs",
9 | "label": "Edit This Page"
10 | },
11 | "github": {
12 | "url": "https://github.com/jarvelov/vue-form-json-schema/"
13 | }
14 | },
15 | "links": {
16 | "sharing": {
17 | "facebook": false,
18 | "twitter": false
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Vue Form JSON Schema
2 |
3 | > A [JSON schema](https://json-schema.org) based form generator, bring your components!
4 |
5 | ##### Use any Vue component or HTML element!
6 |
7 | There are *no prebuilt components* for you to puzzle your form together with. Instead you can use any component or element which emits an event, custom or native.
8 |
9 | > Note that essentially all Vue components that uses `v-model` emits an `input` (or similar) event. [See Vue's guide for more info](https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events)
10 |
11 | ## Installation
12 |
13 | ### Upgrading from v1? Check out the [v2 release notes](https://github.com/jarvelov/vue-form-json-schema/releases/tag/v2.0.0) to see if and how migration affects you.
14 |
15 | Install from npm
16 |
17 | `npm install vue-form-json-schema`
18 |
19 | Import to your app
20 |
21 | ```js
22 | import Vue from 'vue';
23 | import VueFormJsonSchema from 'vue-form-json-schema';
24 |
25 | Vue.component('vue-form-json-schema', VueFormJsonSchema);
26 | ```
27 |
28 | Check out the demos or see a minimal example in the [usage instructions](#usage) to get started.
29 |
30 | ### UMD
31 |
32 | > If you're using the UMD version you can find more examples in the `examples` folder of the [github repo](https://github.com/jarvelov/vue-form-json-schema/tree/master/examples) and the [UMD demo below](#umd-demos).
33 |
34 | If you want to use `vue-form-json-schema` directly in a browser you can do so by using the UMD version. The UMD version autoinstalls the `vue-form-json-schema` component if Vue is found on the window. The entire module is also available on `window.VueFormJsonSchema` where the named exports such as for example `vfjsFieldMixin` can be accessed.
35 |
36 | #### Hosted by unkpg
37 |
38 | ``
39 |
40 | You can substite `vue-form-json-schema@latest` to a fixed version, such as `vue-form-json-schema@2.3.0`
41 |
42 | #### Installed from npm
43 |
44 | ``
45 |
46 | ## Demo
47 |
48 | > Note that all demos use Bootstrap styling, but no styling is included in this package and it is up to you what styles should be used.
49 |
50 | ### [Minimal demo](https://py6611pr9m.codesandbox.io)
51 |
52 | The least amount of configuration to render an `input` element.
53 |
54 | ### [Nested UI demo](https://882w4v374l.codesandbox.io)
55 |
56 | Using Bootstrap classes to show how layout can be different for devices with different screen sizes.
57 | In this example two input fields will be wrapped inside a div with `col-12 col-sm-6` classes.
58 | Try resizing your browser window too see it in action.
59 |
60 | ### [Conditional visibility and Animation demo](https://k0q8wk946o.codesandbox.io/)
61 |
62 | Sometimes a field should only be shown if a condition is met. Uses `` to provide animation.
63 |
64 | ### [Vue components demo](https://z549j1vxx.codesandbox.io)
65 |
66 | See how to use your own or third party Vue components in `vue-form-json-schema`.
67 |
68 | ### [Vue async loading of form](https://2p51q8q14y.codesandbox.io)
69 |
70 | Loading the form from a backend? Check out this example.
71 |
72 | ### [Registration form with validation](https://4rykx7jj19.codesandbox.io)
73 |
74 | A more complete example with validation and error messages
75 |
76 | ### UMD demos
77 |
78 | All the examples above are replicated using the UMD version in the `examples` folder of this repo.
79 |
80 | [Online version of the first demo](https://jsfiddle.net/jarvelov/ewg6dfqL/)
81 |
82 | ## Features
83 |
84 | * Supports any HTML element or Vue component
85 | * Small (`32K` uncompressed, `6.5K` gzipped)
86 | * Standardized [JSON schema](json-schema.org) for annotation and validation (by [Ajv](https://github.com/epoberezkin/ajv))
87 | * Layout is independent from data structure
88 |
89 | ## Documentation
90 |
91 | [Gitbook](https://jarvelov.gitbook.io/vue-form-json-schema/)
92 |
93 | ## Usage
94 |
95 | ### Basic example with one field
96 |
97 | >For using the UMD version, check out the `examples` folder where all the demos above are replicated using the UMD version
98 |
99 | [See demo](https://codesandbox.io/s/py6611pr9m)
100 |
101 | ```js
102 |
103 |
108 |
109 |
110 |
111 |
143 | ```
144 |
145 | ### Dependencies
146 |
147 | #### Ajv
148 | For form validation using [JSON Schema](http://json-schema.org/) and internal validation
149 |
150 | #### Lodash
151 | `get`, `set` and `merge` are used throughout the package.
152 | Bundle size is very important though and is always considered and so we heavily strip down lodash to only include the absolute necessities
153 |
154 | #### Vue
155 |
156 | Tested with v2.5.9 but will probably work on any version >= v2.4.0
157 |
158 | ### TODO
159 |
160 | * Write tests
161 | * ~~Add i18n support~~
162 | * Added in 1.15.2 with `options.ajv.locale` setting
163 | * ~~Write this README~~
164 | * Use Ajv internally to validate:
165 | * `vfs-global` prop `ui-schema`
166 | * `vfs-component` prop `ui-schema`
167 | * ~~Write docs~~
168 | * ~~Publish with Gitbook~~
169 |
--------------------------------------------------------------------------------
/docs/SUMMARY.md:
--------------------------------------------------------------------------------
1 | * [Installation](installation.md)
2 | * [Getting started](getting-started.md)
3 | * API
4 | * [vue-form-json-schema](api/vue-form-json-schema.md)
5 | * [components](api/components.md)
6 | * [options](api/options.md)
7 | * [ajv](api/options/ajv.md)
8 | * [schema](api/schema.md)
9 | * [uiSchema](api/ui-schema.md)
10 | * [field](api/ui-schema/field.md)
11 | * [component](api/ui-schema/field/component.md)
12 | * [children](api/ui-schema/field/children.md)
13 | * [displayOptions](api/ui-schema/field/display-options.md)
14 | * [dynamicOptions](api/ui-schema/field/dynamic-options.md)
15 | * [errorHandler](api/ui-schema/field/error-handler.md)
16 | * [errorOptions](api/ui-schema/field/error-options.md)
17 | * [eventProp](api/ui-schema/field/event-prop.md)
18 | * [fieldOptions](api/ui-schema/field/field-options.md)
19 | * [attrs](api/ui-schema/field/field-options/attrs.md)
20 | * [class](api/ui-schema/field/field-options/class.md)
21 | * [domProps](api/ui-schema/field/field-options/dom-props.md)
22 | * [key](api/ui-schema/field/field-options/key.md)
23 | * [nativeOn](api/ui-schema/field/field-options/native-on.md)
24 | * [on](api/ui-schema/field/field-options/on.md)
25 | * [props](api/ui-schema/field/field-options/props.md)
26 | * [slot](api/ui-schema/field/field-options/slot.md)
27 | * [style](api/ui-schema/field/field-options/style.md)
28 | * [internalModel](api/ui-schema/field/internal-model.md)
29 | * [valueModel](api/ui-schema/field/value-model.md)
30 | * [valueProp](api/ui-schema/field/value-prop.md)
31 |
--------------------------------------------------------------------------------
/docs/api/components.md:
--------------------------------------------------------------------------------
1 | # components
2 |
3 | With Vue one can use both locally and globally registered components. If not all the components you want to use are globally registered you can use the `components` property to pass in additional components to `vue-form-json-schema`.
4 |
5 | ## Provide locally registered components
6 |
7 | In this example we re-use the locally registered components and pass them along to `vue-form-json-schema`
8 |
9 | ```html
10 |
11 |
17 |
18 |
19 |
48 | ```
49 |
50 | ## Use components directly without registering them
51 |
52 | In this example we pass the components along to `vue-form-json-schema` without registering them first
53 |
54 | ```html
55 |
56 |
62 |
63 |
64 |
93 | ```
94 |
--------------------------------------------------------------------------------
/docs/api/options.md:
--------------------------------------------------------------------------------
1 | # Options
2 |
3 | | Property | Value | Description | Default |
4 | | -------------------------- | ------- | --------------------------------------------------------------- | -------------------------------- |
5 | | allowInvalidModel | Boolean | If `false` and validation fails the model will not be updated | true |
6 | | validate | Boolean | Enable/disable validation | true |
7 | | validateOnLoad | Boolean | Perform a validation after the component has loaded (`created`) | true |
8 | | showValidationErrors | Boolean | Show validation errors | false |
9 | | castToSchemaType | Boolean | Cast values to the type specified for the model in the schema. | false |
10 | | valueProp | String | Which prop will get passed the model | 'value' |
11 | | [ajv](options/ajv.md) | Object | Options for [Ajv](https://github.com/epoberezkin/ajv) | [See ajv](options/ajv.md) |
12 |
--------------------------------------------------------------------------------
/docs/api/options/ajv.md:
--------------------------------------------------------------------------------
1 | # ajv
2 |
3 | Options to configure `Ajv`. A list of all [supported options can be found here](https://ajv.js.org/options.html)
4 |
5 | ## Default value
6 |
7 | ```js
8 | {
9 | keywords: {},
10 | plugins: [],
11 | locale: null,
12 | options: {
13 | allErrors: true;
14 | }
15 | }
16 | ```
17 |
18 | > Ajv option `allErrors` is always set to true, there is no way to override this as it is used internally for validation
19 |
20 | ## Examples
21 |
22 | ### Enable $data references
23 |
24 | See [Ajv's documentation about $data references](https://ajv.js.org/guide/combining-schemas.html#data-reference) for more details.
25 | `$data` in this example can be substituted for any other [supported Ajv option](https://ajv.js.org/options.html)
26 |
27 | ```js
28 | data() {
29 | return {
30 | options: {
31 | ajv: {
32 | options: {
33 | $data: true
34 | }
35 | }
36 | },
37 | model: {
38 | ...
39 | },
40 | jsonSchema: {
41 | ...
42 | },
43 | uiSchema: [
44 | ...
45 | ]
46 | }
47 | }
48 | ```
49 |
50 | ```html
51 |
52 |
58 |
59 | ```
60 |
61 | ### Localize error messages
62 |
63 | This example uses [ajv-i18n](https://github.com/epoberezkin/ajv-i18n).
64 | Any errors will be translated using the locale function provided before the fields gets access to them.
65 |
66 | ```js
67 | // Import swedish localization
68 | const sv = require('ajv-i18n/localize/sv');
69 |
70 | export default {
71 | data() {
72 | return {
73 | options: {
74 | ajv: {
75 | locale: sv
76 | }
77 | },
78 | model: {
79 | ...
80 | },
81 | jsonSchema: {
82 | ...
83 | },
84 | uiSchema: [
85 | ...
86 | ]
87 | }
88 | }
89 | }
90 | ```
91 |
92 | ```html
93 |
94 |
100 |
101 | ```
102 |
103 | ### Add Ajv keywords
104 |
105 | In this example we will add a custom keyword which checks that the value of the input is not present in the `blacklist` array
106 |
107 | ```js
108 | // These values are forbidden
109 | const blacklist = ['forbidden', 'values'];
110 |
111 | export default {
112 | data() {
113 | return {
114 | options: {
115 | ajv: {
116 | keywords: {
117 | notBlackListed: {
118 | // Needs to be set to true for the validate function to be able to add custom errors
119 | errors: true,
120 | validate: (schema, value) => {
121 | // This is what Ajv wants, and it's terrible.
122 | // There is no way to add custom error messages without
123 | // modifying the validate function's `errors` property
124 | const self = this.options.ajv.keywords.notBlackListed.validate;
125 |
126 | // Create an empty array to hold any errors
127 | self.errors = [];
128 |
129 | if (this.blacklist.indexOf(value) >= 0) {
130 | // This value is blacklisted
131 | self.errors.push({
132 | message: 'Value is blacklisted!',
133 | keyword: 'uniqueLabel',
134 | params: {
135 | keyword: 'uniqueLabel',
136 | },
137 | });
138 | }
139 |
140 | // Ajv needs a boolean value returned to determine if the validation was a success
141 | // If true is returned, no error is generated, even if the errors array is populated
142 | return self.errors.length === 0;
143 | },
144 | },
145 | },
146 | },
147 | },
148 | model: {},
149 | jsonSchema: {
150 | type: 'object',
151 | properties: {
152 | myValue: {
153 | type: 'string',
154 | notBlackListed: true,
155 | },
156 | },
157 | },
158 | uiSchema: [
159 | {
160 | component: 'input',
161 | model: 'myValue',
162 | fieldOptions: {
163 | on: ['change'],
164 | },
165 | },
166 | // This component will output all the errors for myValue model
167 | {
168 | component: 'div',
169 | errorHandler: true,
170 | model: 'myValue',
171 | },
172 | ],
173 | };
174 | },
175 | };
176 | ```
177 |
178 | ```html
179 |
180 |
186 |
187 | ```
188 |
189 | ### Extend Ajv instance
190 |
191 | Note that this is neither tested nor supported but in theory this would give extra Ajv features such as [ajv-async](https://github.com/epoberezkin/ajv-async) and [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) access to the internal `Ajv` instance running inside `vue-form-json-schema`.
192 |
193 | By adding the required plugin to the `plugins` section in the ajv options it is possible to load and apply the required plugin to the ajv instance that is used by `vue-form-json-schema`. This comes in handy when custom error messages must be added with [ajv-errors](https://github.com/epoberezkin/ajv-errors).
194 |
195 | ```js
196 | // Import ajv-errors plugin
197 | const ajvErrors = require('ajv-errors');
198 |
199 | export default {
200 | data() {
201 | return {
202 | options: {
203 | ajv: {
204 | plugins: {
205 | ajvErrors
206 | }
207 | }
208 | },
209 | model: {
210 | ...
211 | },
212 | jsonSchema: {
213 | ...
214 | },
215 | uiSchema: [
216 | ...
217 | ]
218 | }
219 | }
220 | }
221 | ```
222 |
223 | ```html
224 |
225 |
231 |
232 | ```
233 |
--------------------------------------------------------------------------------
/docs/api/schema.md:
--------------------------------------------------------------------------------
1 | # schema
2 |
3 | Any valid [JSON Schema](http://json-schema.org).
4 |
5 | Good resources if you are new to JSON Schema is:
6 |
7 | * [Understanding JSON schema](https://spacetelescope.github.io/understanding-json-schema/)
8 | * [Online JSON schema validator](http://jsonschemavalidator.net)
9 | * [Ajv documentation (internal JSON schema validation engine)](https://epoberezkin.github.io/ajv/)
10 | * [Ajv github](https://github.com/epoberezkin/ajv)
11 |
--------------------------------------------------------------------------------
/docs/api/ui-schema.md:
--------------------------------------------------------------------------------
1 | # uiSchema
2 |
3 | An array of [fields](ui-schema/field.md).
4 |
5 | ## Example
6 |
7 | ```js
8 | data() {
9 | return {
10 | uiSchema: [
11 | {
12 | component: 'div',
13 | fieldOptions: {
14 | class: ['form-group']
15 | },
16 | children: [
17 | {
18 | component: 'input',
19 | model: 'firstName',
20 | fieldOptions: {
21 | on: ['input']
22 | }
23 | }
24 | ]
25 | }
26 | ]
27 | }
28 | }
29 | ```
30 |
31 | The example above will do essentially the same thing as the following Vue template:
32 |
33 | ```html
34 |
35 |
36 |
37 | ```
38 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field.md:
--------------------------------------------------------------------------------
1 | A `field` is an `object` and must have a [component](field/component.md) property.
2 |
3 | ## Type
4 |
5 | `Object`
6 |
7 | ## Properties
8 |
9 | * [component](field/component.md) \*
10 | * [children](field/children.md)
11 | * [displayOptions](field/display-options.md)
12 | * [dynamicOptions](field/dynamic-options.md)
13 | * [errorHandler](field/error-handler.md)
14 | * [errorOptions](field/error-options.md)
15 | * [eventProp](field/event-prop.md)
16 | * [fieldOptions](field/field-options.md)
17 | * [valueProp](field/value-prop.md)
18 |
19 | \* required
20 |
21 | ## Example
22 |
23 | ```js
24 | data() {
25 | return {
26 | uiSchema: [{
27 | // component is required
28 | component: 'div'
29 | // other optional properties
30 | fieldOptions: {
31 | domProps: {
32 | innerHTML: 'This is the first component!'
33 | }
34 | }
35 | }]
36 | }
37 | }
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/children.md:
--------------------------------------------------------------------------------
1 | # children
2 |
3 | An array of [fields](../field.md). The rendered children (vnodes) will be passed in the default slot to the `component`, unless a [slot](field-options/slot.md) is set.
4 |
5 | ```js
6 | data() {
7 | return {
8 | uiSchema: [{
9 | component: 'div',
10 | children: [
11 | {
12 | component: 'div',
13 | fieldOptions: {
14 | domProps: {
15 | innerHTML: 'The first second div'
16 | }
17 | }
18 | },
19 | {
20 | component: 'div',
21 | fieldOptions: {
22 | domProps: {
23 | innerHTML: 'The first second div'
24 | }
25 | }
26 | }
27 | ]
28 | }]
29 | }
30 | }
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/component.md:
--------------------------------------------------------------------------------
1 | # component
2 |
3 | The `component` property can refer to any [Vue component](https://vuejs.org/v2/guide/components.html) or [HTML element tag name](https://developer.mozilla.org/en-US/docs/Web/HTML/Element).
4 |
5 | ```js
6 | // Option 1 - HTML element tag
7 | data() {
8 | return {
9 | uiSchema: [{
10 | component: 'div'
11 | }]
12 | }
13 | }
14 | ```
15 |
16 | ```js
17 | // Option 2 - Globally registered component
18 | data() {
19 | return {
20 | uiSchema: [{
21 | component: 'my-custom-component'
22 | }]
23 | }
24 | }
25 | ```
26 |
27 | ```js
28 | // Option 3 - component object
29 | import MyCustomComponent from './my-custom-component'
30 |
31 | ...
32 |
33 | data() {
34 | return {
35 | uiSchema: [{
36 | component: MyCustomComponent
37 | }]
38 | }
39 | }
40 | ```
41 |
42 | ```js
43 | // Option 4 - Component from components prop
44 | import MyCustomComponent from './my-custom-component'
45 |
46 | ...
47 |
48 | data() {
49 | return {
50 | components: {
51 | MyCustomComponent
52 | },
53 | uiSchema: [{
54 | component: 'MyCustomComponent'
55 | }],
56 | model: { ... },
57 | schema: { ... }
58 | }
59 | }
60 |
61 | ....
62 |
63 |
64 |
70 |
71 | ```
72 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/display-options.md:
--------------------------------------------------------------------------------
1 | # displayOptions
2 |
3 | > Tip! This option plays nicely with `transition` and `transition-group`! See example at the bottom.
4 |
5 | Sometimes a field is only relevant if some condition is met. The `displayOptions` property uses JSON Schema to evaluate if a field should be visible or not. If there are no errors then the field is shown.
6 |
7 |
8 | There are 2 options: Full and Single.
9 |
10 | ## Full
11 |
12 | The full model uses the entire form model as data.
13 |
14 | ```js
15 | // Option 1 - full model
16 | data() {
17 | return {
18 | uiSchema: [{
19 | component: 'div',
20 | children: [{
21 | component: 'div',
22 | displayOptions: {
23 | schema: {
24 | type: object,
25 | properties: {
26 | firstName: {
27 | type: 'string',
28 | minLength: 3
29 | }
30 | },
31 | required: ['firstName']
32 | }
33 | }
34 | }]
35 | }]
36 | }
37 | }
38 | ```
39 |
40 | The above is essentially doing the following validation with [Ajv](https://github.com/epoberezkin/ajv)
41 |
42 | ```js
43 | const schema = {
44 | type: object,
45 | properties: {
46 | firstName: {
47 | type: 'string',
48 | minLength: 3
49 | }
50 | },
51 | required: ['firstName']
52 | };
53 |
54 | const data = {
55 | // Entire form model
56 | firstName,
57 | lastName,
58 | address,
59 | ...
60 | }
61 |
62 | // If there are no errors in ajv.errors then the field is shown
63 | ajv.validate(schema, data);
64 |
65 | ```
66 |
67 | ## Single
68 |
69 | The Full option can be a bit verbose when you only rely on a single field's model, and thus you set the `model` property on the `displayOptions` object to only use the value of that field's model.
70 |
71 | ```js
72 | // Option 2 - single model
73 | data() {
74 | return {
75 | uiSchema: [{
76 | component: 'div',
77 | children: [{
78 | component: 'div',
79 | displayOptions: {
80 | // Here we set to use the firstName model as the value to evaluate the schema against
81 | model: 'firstName',
82 | schema: {
83 | type: 'string',
84 | minLength: 3
85 | }
86 | }
87 | }]
88 | }]
89 | }
90 | }
91 | ```
92 |
93 | ## Usage with transitions
94 |
95 | To get some nice transitions all that is needed is to nest the component in a `transition` or `transition-group` field.
96 | Check out the [Vue.js guide on transitions](https://vuejs.org/v2/guide/transitions.html) for more info.
97 |
98 | ```js
99 | data() {
100 | return {
101 | uiSchema: [{
102 | component: 'transition',
103 | fieldOptions: {
104 | // Set the name prop to `fade`
105 | props: {
106 | name: 'fade',
107 | // Any transition props such as `enter-class`
108 | // enterClass: ''
109 | },
110 | on: {
111 | // Even javascript hooks are available
112 | enter: (el) => {
113 | console.log('hello!')
114 | },
115 | leave: (el) => {
116 | console.log('goodbye!');
117 | }
118 | }
119 | },
120 | children: [{
121 | component: 'div',
122 | displayOptions: {
123 | model: 'firstName'
124 | schema: {
125 | type: 'string',
126 | minLength: 3
127 | }
128 | }
129 | }]
130 | }]
131 | }
132 | }
133 | ```
134 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/dynamic-options.md:
--------------------------------------------------------------------------------
1 | # dynamicOptions
2 |
3 | Sometimes a field needs to have properties added/removed when a field has a certain value. This is where `dynamicOptions` comes into play.
4 | `dynamicOptions` can alter any of a [field's top level properties](../field.md), like `children`, `component`, `fieldOptions` etc. when the given `schema` is `true` or `false`. The behavior is the same as [displayOptions](displayOptions.md), however in contrast to `displayOptions` you can pass in an array of options by using an array.
5 |
6 | There are 2 options: Full and Single.
7 |
8 | ## Full
9 |
10 | The full model uses the entire form model as data.
11 |
12 | ```js
13 | // Option 1 - full JSON schema
14 | data() {
15 | return {
16 | uiSchema: [{
17 | component: 'div',
18 | children: [{
19 | component: 'div',
20 | dynamicOptions: {
21 | schema: {
22 | type: object,
23 | properties: {
24 | firstName: {
25 | type: 'string',
26 | minLength: 3
27 | }
28 | },
29 | required: ['firstName']
30 | },
31 | options: {
32 | // any of a field's top level property is valid here
33 | fieldOptions: {
34 | // any value that is valid in fieldOptions can be used here
35 | class: ['text-success']
36 | }
37 | }
38 | }
39 | }]
40 | }]
41 | }
42 | }
43 | ```
44 |
45 | ## Single
46 |
47 | The Full option can be a bit verbose when you only rely on a single field's model, and thus you set the `model` property on the `displayOptions` object to only use the value of that field's model.
48 |
49 | ```js
50 | // Option 2 - single schema
51 | data() {
52 | return {
53 | uiSchema: [{
54 | component: 'div',
55 | children: [{
56 | component: 'div',
57 | // Here we use an array of dynamic options, but you don't have to do that just to use the single schema
58 | // You can just as well use an object like in the "Full" example above.
59 | dynamicOptions: [
60 | {
61 | // Here we set to use the firstName model as the value to evaluate the schema against
62 | model: 'firstName',
63 | schema: {
64 | type: 'string',
65 | minLength: 3
66 | },
67 | options: {
68 | // any of a field's top level property is valid here
69 | fieldOptions: {
70 | // any value that is valid in fieldOptions can be used here
71 | class: ['text-success'],
72 | domProps: {
73 | innerHTML: 'Looking good, person with a first name with more than 3 characters!'
74 | }
75 | }
76 | }
77 | },
78 | {
79 | model: 'firstName',
80 | schema: {
81 | type: 'string',
82 | maxLength: 2
83 | },
84 | options: {
85 | // any of a field's top level property is valid here
86 | fieldOptions: {
87 | // any value that is valid in fieldOptions can be used here
88 | class: ['text-warning'],
89 | domProps: {
90 | innerHTML: 'Hey, that is cool! Your first name is less than or equal to 2 characters!'
91 | }
92 | }
93 | }
94 | }
95 | ]
96 | }]
97 | }]
98 | }
99 | }
100 | ```
101 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/error-handler.md:
--------------------------------------------------------------------------------
1 | # Error handler
2 |
3 | `errorHandler` is a Boolean, which is set to true for fields which should handle the error messages for a model.
4 | The component will get the the same props as any other component but it cannot receive any [children](children.md) as the default slot is populated by the rendered `errors`.
5 |
6 | The errors are passed as the default slot are rendered individually as a `
`.
7 | If you want to render them differently you can handle the errors in the `vfjsFieldErrors` prop yourself. This is an array of the [Ajv validation errors](https://github.com/epoberezkin/ajv#validation-errors)
8 |
9 | ## Example
10 |
11 | ```js
12 | data() {
13 | return {
14 | jsonSchema: {
15 | type: 'object',
16 | required: ['input1'],
17 | properties: {
18 | input1: {
19 | type: 'string',
20 | minLength: 1 // Value has to be at least 1 character
21 | }
22 | }
23 | },
24 | uiSchema: [{
25 | component: 'input',
26 | model: 'input1',
27 | fieldOptions: {
28 | // Optionally set the attributes on the dom element as well
29 | // This can be used to let the browser validate the form
30 | //
31 | // If you don't want the browser to validate the form
32 | // use the `novalidate` attribute on
33 | attrs: {
34 | // Set required attribute on the dom element
35 | required: true
36 | // Set minlength attribute
37 | minlength: 1
38 | },
39 | on: ['change']
40 | }
41 | }, {
42 | // This component takes care of the errors from `input1`
43 | // If the form is submitted with the input being empty the error handler
44 | // will render the errors inside it
45 | component: 'div',
46 | model: 'input1',
47 | errorHandler: true,
48 | fieldOptions: {
49 | class: ['bg-danger']
50 | }
51 | }]
52 | }
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/error-options.md:
--------------------------------------------------------------------------------
1 | # Error options
2 |
3 | Same API as [fieldOptions](field-options.md) but is only applied when the field has errors and has been modified.
4 |
5 | ## Example
6 |
7 | ```js
8 | data() {
9 | return {
10 | uiSchema: [{
11 | component: 'input',
12 | model: 'input1',
13 | errorOptions: {
14 | class: ['is-invalid']
15 | },
16 | fieldOptions: {
17 | class: ['form-control'],
18 | on: ['input']
19 | }
20 | }]
21 | }
22 | }
23 | ```
24 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/event-prop.md:
--------------------------------------------------------------------------------
1 | # Event prop
2 |
3 | Sets which property should be emitted as the field's value when the component emits an event which is based on the [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) interface. The property specified by `eventProp` is read from the event's `target` property, i.e. `event.target[eventProp]`. Default value is `value`, i.e. `event.target['value']`.
4 |
5 | ## Set globally for all fields
6 |
7 | ```js
8 | data() {
9 | return {
10 | options: {
11 | eventProp: 'target.href'
12 | }
13 | }
14 | }
15 | ```
16 |
17 | ## Set locally for one field
18 |
19 | ```js
20 | data() {
21 | return {
22 | uiSchema: [{
23 | component: 'input',
24 | model: 'isChecked',
25 | eventProp: 'checked',
26 | valueProp: 'checked',
27 | fieldOptions: {
28 | type: "checkbox",
29 | on: ['input']
30 | }
31 | }]
32 |
33 | }
34 | }
35 | ```
36 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options.md:
--------------------------------------------------------------------------------
1 | # Field options
2 |
3 | ## Available properties
4 |
5 | > See Vue's guide on render function's [Data Object In-Depth]( https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth) for more details on all available properties
6 |
7 | Since we're using Vue's [render functions](https://vuejs.org/v2/guide/render-function.html) to create the form elements basically any property that is supported in a render function can be used in the `fieldOptions` object.
8 |
9 | The following properties are tested and supported with `vue-form-json-schema`
10 |
11 | * [attrs](field-options/attrs.md)
12 | * [class](field-options/class.md)
13 | * [domProps](field-options/dom-props.md)
14 | * [key](field-options/key.md)
15 | * [nativeOn](field-options/native-on.md)
16 | * [on](field-options/on.md)
17 | * [props](field-options/props.md)
18 | * [slot](field-options/slot.md)
19 | * [style](field-options/style.md)
20 | * ref
21 |
22 | ## Example
23 |
24 | ```js
25 | data() {
26 | return {
27 | uiSchema: [{
28 | component: 'input',
29 | fieldOptions: {
30 | class: ['form-control'],
31 | on: ['input']
32 | }
33 | }]
34 | }
35 | }
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/attrs.md:
--------------------------------------------------------------------------------
1 | # attrs
2 |
3 | Essentially any normal html attributes
4 |
5 | ```js
6 | // Normal HTML attributes
7 | data() {
8 | return {
9 | uiSchema: [{
10 | component: 'div',
11 | fieldOptions: {
12 | attrs: {
13 | id: 'foo',
14 | placeholder: 'bar'
15 | }
16 | }
17 | }]
18 | }
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/class.md:
--------------------------------------------------------------------------------
1 | # class
2 |
3 | The `class` property can be configured in 3 ways. Either as an `Object`, `Array` or simply a `String`. This is essentially the same API as [`v-bind:class`](https://vuejs.org/v2/guide/class-and-style.html) uses.
4 |
5 | ## Object
6 |
7 | An `Object` must have the classes as keys and the keys' value should be a `Boolean`.
8 |
9 | ```js
10 | // Option 1: Object
11 | data() {
12 | uiSchema: [{
13 | component: 'div',
14 | fieldOptions: {
15 | class: {
16 | 'col-12': true, // Class is included
17 | 'col-md-6': true, // Class is included
18 | 'col-lg-4': false // Class is NOT included
19 | }
20 | }
21 | }]
22 | }
23 | ```
24 |
25 | ## Array
26 |
27 | An `Array` should be a an array of strings, multidimensional arrays or arrays with any other values other than strings are not supported.
28 |
29 | ```js
30 | // Option 2: Arrays
31 | data() {
32 | uiSchema: [{
33 | component: 'div',
34 | fieldOptions: {
35 | // All values in array is included
36 | class: [
37 | 'col-12',
38 | 'col-md-6'
39 | ]
40 | }
41 | }]
42 | }
43 | ```
44 |
45 | ## String
46 |
47 | ```js
48 | // Option 3: String
49 | data() {
50 | uiSchema: [{
51 | component: 'div',
52 | fieldOptions: {
53 | class: 'col-12 col-md-6'
54 | }
55 | }]
56 | }
57 | ```
58 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/dom-props.md:
--------------------------------------------------------------------------------
1 | # domProps
2 |
3 | > Be careful about setting `innerHTML` as that effectively disables a field's ability to render children
4 |
5 | ```js
6 | // DOM properties
7 | data() {
8 | return {
9 | uiSchema: [{
10 | component: 'div',
11 | fieldOptions: {
12 | domProps: {
13 | innerHTML: '
Hello
'
14 | }
15 | }
16 | }]
17 | }
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/key.md:
--------------------------------------------------------------------------------
1 | # key
2 |
3 | > The key special attribute is primarily used as a hint for Vue’s virtual DOM algorithm to identify VNodes when diffing the new list of nodes against the old list. - [Vue.js guide](https://vuejs.org/v2/api/#key)
4 |
5 | This property is set to each field's unique internal id by default. You can optionally override it should you wish to specifiy it.
6 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/native-on.md:
--------------------------------------------------------------------------------
1 | # nativeOn
2 |
3 | Register events listeners for native [Events](https://developer.mozilla.org/en-US/docs/Web/Events).
4 | Accepts a `String`, `Array` or an `Object`.
5 |
6 | ## String
7 |
8 | ```js
9 | // Option 1: String
10 | data() {
11 | return {
12 | uiSchema: [{
13 | component: 'input',
14 | fieldOptions: {
15 | on: 'input'
16 | }
17 | }]
18 | }
19 | }
20 | ```
21 |
22 | ## Array
23 |
24 | ```js
25 | // Option 2: Arrays
26 | data() {
27 | return {
28 | uiSchema: [{
29 | component: 'input',
30 | fieldOptions: {
31 | nativeOn: [
32 | 'input'
33 | ]
34 | }
35 | }]
36 | }
37 | }
38 | ```
39 |
40 | ## Object
41 |
42 | An `Object` can be used if the value should be manipulated or used elsewhere before set in to the model.
43 |
44 | > Note that the callback must be synchronous
45 |
46 | ```js
47 | // Option 3: Object
48 | data() {
49 | return {
50 | uiSchema: [{
51 | component: 'input',
52 | fieldOptions: {
53 | nativeOn: {
54 | 'input': event => String(event.target.value).toLowerCase();
55 | }
56 | }
57 | }]
58 | }
59 | }
60 | ```
61 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/on.md:
--------------------------------------------------------------------------------
1 | # on
2 |
3 | Register events listeners for [Custom Events](https://vuejs.org/v2/guide/components.html#Custom-Events) emitted using [`$emit`](https://vuejs.org/v2/api/#vm-emit).
4 | Accepts a `String`, `Array` or an `Object`.
5 |
6 | ## String
7 |
8 | ```js
9 | // Option 1: String
10 | data() {
11 | return {
12 | uiSchema: [{
13 | component: 'input',
14 | fieldOptions: {
15 | on: 'input'
16 | }
17 | }]
18 | }
19 | }
20 | ```
21 |
22 | ## Array
23 |
24 | ```js
25 | // Option 2: Arrays
26 | data() {
27 | return {
28 | uiSchema: [{
29 | component: 'input',
30 | fieldOptions: {
31 | on: [
32 | 'input'
33 | ]
34 | }
35 | }]
36 | }
37 | }
38 | ```
39 |
40 | ## Object
41 |
42 | An `Object` can be used if the value should be manipulated or used elsewhere before set in to the model.
43 |
44 | > Note that the callback must be synchronous
45 |
46 | ```js
47 | // Option 3: Object
48 | data() {
49 | return {
50 | uiSchema: {
51 | component: 'input',
52 | fieldOptions: {
53 | on: {
54 | 'change': value => String(value).toLowerCase();
55 | }
56 | }
57 | }
58 | }
59 | }
60 | ```
61 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/props.md:
--------------------------------------------------------------------------------
1 | # props
2 |
3 | Plain `Vue` [props](https://vuejs.org/v2/guide/components.html#Props)
4 |
5 | ```js
6 | // A custom component
7 | Vue.component('my-custom-component', {
8 | name: 'my-custom-component',
9 | props: ['message'],
10 | template: '{{ message }}'
11 | })
12 |
13 | ...
14 | data() {
15 | return {
16 | uiSchema: [{
17 | component: 'my-custom-component',
18 | fieldOptions: {
19 | props: {
20 | message: 'Hello!'
21 | }
22 | }
23 | }]
24 | }
25 | }
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/slot.md:
--------------------------------------------------------------------------------
1 | # slot
2 |
3 | > Used on content inserted into child components to indicate which named slot the content belongs to. - [Vue.js guide](https://vuejs.org/v2/api/#slot)
4 |
5 | MyCustomComponent.vue
6 |
7 | ```html
8 |
9 |
10 | This is the default main slot text
11 |
12 |
13 | ```
14 |
15 | MyForm.vue
16 |
17 | ```html
18 |
19 | ...
20 |
21 |
41 | ```
42 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/field-options/style.md:
--------------------------------------------------------------------------------
1 | # style
2 |
3 | The style property is simply an object where the key is the style property and the value is the property value. See Vue's guide on [`v-bind:style`](https://vuejs.org/v2/guide/class-and-style.html#Binding-Inline-Styles) for more information.
4 |
5 | > Note that the [Array syntax](https://vuejs.org/v2/guide/class-and-style.html#Array-Syntax-1) is NOT tested yet as of 2017-12-17
6 |
7 | ```js
8 | data() {
9 | return {
10 | uiSchema: {
11 | component: 'div',
12 | fieldOptions: {
13 | domProps: {
14 | innerHTML: 'This is some red text'
15 | },
16 | style: {
17 | color: 'red',
18 | fontSize: '13px'
19 | }
20 | }
21 | }
22 | }
23 | }
24 | ```
25 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/internal-model.md:
--------------------------------------------------------------------------------
1 | # Internal model
2 |
3 | Some component's require the model to be updated when the next [tick](https://vuejs.org/v2/api/#Vue-nextTick) happens. As there might be several `ticks` until `vue-form-json-schema` has updated the form model and re-renders the component.
4 | An example of this is the `el-input` component from [element-ui](https://element.eleme.io), which loses its cursor position on the next re-render when the value hasn't updated yet.
5 |
6 | VFJS can keep track of when the value changes and store it internally to ensure that on the next `tick` the
7 |
8 | ## Example 1
9 |
10 | Setting `internalModel` to `true` will update the value for all events in `fieldOptions.on`
11 |
12 | ```js
13 | data() {
14 | return {
15 | uiSchema: [{
16 | component: 'custom-input',
17 | model: 'input',
18 | internalModel: true,
19 | fieldOptions: {
20 | on: ['input']
21 | }
22 | }]
23 | }
24 | }
25 | ```
26 |
27 | ## Example 2
28 |
29 | `internalModel` can also be an array with keys for event names. The internal model will only be updated when these events are emitted.
30 |
31 | ```js
32 | data() {
33 | return {
34 | uiSchema: [{
35 | component: 'custom-input',
36 | model: 'input',
37 | internalModel: ['input'],
38 | fieldOptions: {
39 | on: [
40 | 'input',
41 | 'custom-event'
42 | ]
43 | }
44 | }]
45 | }
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/value-model.md:
--------------------------------------------------------------------------------
1 | # Value model
2 |
3 | Sets which field's model value is passed down as the `value` prop. Default is the same as the field set in the `model` property.
4 | This is useful if you want to use another field's `model` as the value for another field. Note that the [valueProp](./value-prop.md) can set the `valueModel` to be passed to another prop than `value`.
5 |
6 | You can also use `valueModel: true` to pass the entire form model to the field.
7 |
8 | ## Example
9 |
10 | This example
11 |
12 | ```js
13 | data() {
14 | return {
15 | model: {
16 | options: ['Cat', 'Dog', 'Rabbit'],
17 | selectedOptions: [],
18 | },
19 | uiSchema: [
20 | {
21 | component: 'custom-select',
22 | model: 'selectedOptions', , // This sets what property in the form model is passed to this component's 'value' prop and by default this property is the one which will be updated when the 'change' event is emitted
23 | valueModel: 'options', // This overrides what property in the form model will be passed to this component, the default is to pass it to the 'value' prop
24 | valueProp: 'options', // This overrides the prop to which the field's model will be passed and sets it to 'options', this prop will receive the value of 'valueModel' if it is set, or else it will receive the normal 'model' value
25 | fieldOptions: {
26 | on: ['change'],
27 | },
28 | }
29 | ]
30 | }
31 | }
32 | ```
33 |
--------------------------------------------------------------------------------
/docs/api/ui-schema/field/value-prop.md:
--------------------------------------------------------------------------------
1 | # Value prop
2 |
3 | Sets the property to which the field's `model` value is passed. Default is `value`.
4 |
5 | ## Example
6 |
7 | ```js
8 | data() {
9 | return {
10 | uiSchema: [{
11 | component: 'restaurants-component',
12 | model: 'input',
13 | valueProp: 'restaurants',
14 | fieldOptions: {
15 | on: ['input']
16 | }
17 | }]
18 | }
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/docs/api/vue-form-json-schema.md:
--------------------------------------------------------------------------------
1 | # vue-form-json-schema
2 |
3 | ## Props
4 |
5 | | Property | Value | Description |
6 | | ---------|-------| -------------|
7 | | tag | [HTML element tag name](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) | Render the `vue-form-json-schema` element with this tag name |
8 | | model | `Object` | The form values |
9 | | options | `Object` | See [Options](options.md) |
10 | | schema | `Object` | A valid [JSON Schema]( http://json-schema.org/) (validated by [Ajv](https://github.com/epoberezkin/ajv)) |
11 | | ui-schema | `Object` | See [uiSchema](ui-schema.md) |
12 | | components | `Object` | See [components](components.md) |
13 |
14 | ## Events
15 |
16 | | Event | Description |
17 | | ---------|-------| -------------|
18 | | change | When the `model` is updated this function will be called with the new value as the first parameter |
19 | | state-change | When the internal state is updated this function will be called with the new value as the first parameter. The state is an `Object` which contains information such as validation errors. |
20 | | validated | When a validation has been performed this function will be called a `Boolean` as the first parameter describing the overall form valid state |
21 |
22 | ```html
23 |
24 |
35 |
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting started
2 |
3 | ## Option 1
4 |
5 | Import everything and use globally
6 |
7 | ```js
8 | // App.js
9 | import VueFormJsonSchema from 'vue-form-json-schema';
10 | Vue.component('vue-form-json-schema', VueFormJsonSchema);
11 | ```
12 |
13 | ```html
14 |
43 |
44 |
45 |
50 |
51 |
52 | ```
53 |
54 | ## Option 2
55 |
56 | Import and use locally
57 |
58 | ```html
59 |
94 |
95 |
100 |
101 |
102 | ```
103 |
--------------------------------------------------------------------------------
/docs/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | > `vue-form-json-schema` is distributed as both an UMD and ES module version. If you use CommonJS/AMD or are stuck on an older version of Webpack you should use the UMD build. If you use `webpack`, `parcel` or `rollup` the ESM version will be used automatically.
4 |
5 |
6 | ## Requirements
7 |
8 | `Vue.js >= 2.4.0`
9 |
10 | ## Direct Download / CDN
11 |
12 | https://unpkg.com/vue-form-json-schema/vue-form-json-schema
13 |
14 | This link will always use the latest version. To use a specific version you can update the URL like this:
15 |
16 | https://unpkg.com/vue-form-json-schema@2.3.0
17 |
18 | ## NPM
19 |
20 | `npm install vue-form-json-schema`
21 |
--------------------------------------------------------------------------------
/examples/example-1/example-one.js:
--------------------------------------------------------------------------------
1 | const template = `
2 |
3 |
vue-form-json-schema
4 |
Example #1 Minimal example
5 |
6 | A minimal example showing a simple input field.
7 |
20 | This example uses the Bootstraprow and col-*
21 | classes to create a two-column row for devices with larger screens and a single column row for devices with smaller screens.
22 | We also wrap each input in a .form-group
23 |
23 | In this example some fields remain hidden until a certain criteria is met.
24 | We couple that with the <transition> element to show a nice animation when the element comes into and disappears from the view.
25 |
26 |
27 | To create a condition we use the displayOptions property on a ui-schema field.
28 | The condition is simply a JSON Schema and can make use of any available JSON Schema logic.
29 | To make it easier to write conditions a model property can be set on the displayOptions object to target a specific field's model.
30 |
31 |
32 | Here we target the first animation to appear when firstName is longer than 3 characters.The second animation is set to appear when both firstName and lastName are at least 3 characters or longer
33 |
34 |
35 |
Prevent content being pushed around with a fixed height
36 |
37 | We can set a height to preserve the space where the animated divs will pop in.
38 | This avoids the issue of the added divs pushing the content below down and up when transitioning in and out
39 |
6 | An example showing how to use Vue components in
8 | vue-form-json-schema.
9 |
10 | In this example we use the <b-form-input> component
12 | from Bootstrap Vue
14 |
15 |
16 | First: Any component or DOM element can be used in
18 | vue-form-json-schema.
19 |
20 | Any Vue component which uses the v-model can be
22 | used.
24 | See more info below the demo about how to configure Vue
26 | components.
28 |
29 |
30 |
38 |
39 |
40 |
41 |
42 |
43 | Most Vue components which support the v-model can be used
45 | with a very simple configuration
47 |
48 |
49 |
50 | The vue-component-name should be replaced by the globally
52 | registered name of the component.
54 | A globally registered component is one that is imported and registered
56 | like this:
57 | Vue.component('vue-component-name', VueComponentName)
59 |
60 |
61 | This is pretty much it.
62 | Most Vue components will work right away using this
64 | configuration.
66 |
6 | A medium complex example showing a registration form with validation and validation messages.
7 |
8 |
9 |
10 | In this example we configure the options property castToSchemaType to allow values to be cast to their correct type. Without this property all values would be strings for fields where the component is a regular HTML element, such as input, which would make any validation based on other types fail.
11 |
12 |
13 |
14 | Try submitting the form empty and see what error messages you get. You can try typing a number less than 18 into the Age input field and moving to another field (i.e. causing a blur event). This will show you a different validation message when the condition value < 18 is met.
15 |
16 |
17 |
18 | Complete the form with valid information and you can see how the message below the submit button changes. A different message can be shown when all errors have been fixed to let the user know that it can now submit the form again and it will succeed.
19 |
20 |
21 |
22 | Try filling out the form correctly but enter a value less than 18 into the Age input field. You see that when you navigate away the validation message with the 18 year limit appear immediately.
23 |