├── .eslintrc.js ├── .gitignore ├── .jsdoc.json ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── css └── json-schema-forms.css ├── dist └── json-schema-forms.min.js ├── docs ├── JsonSchemaForms.js.html ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ └── OpenSans-Regular-webfont.woff ├── form_components.js.html ├── form_defaultFormOptions.js.html ├── form_formElement.js.html ├── form_formElementDefinitions.js.html ├── form_json-schema_JsonSchemaKeywords.js.html ├── form_json-schema_JsonSchemaType.js.html ├── form_json-schema_childApplicators.js.html ├── form_json-schema_inPlaceApplicators.js.html ├── form_layouts.js.html ├── form_selectors.js.html ├── global.html ├── index.html ├── module-JsonSchemaForms.html ├── module-JsonSchemaKeywords.html ├── module-JsonSchemaType.html ├── module-childApplicators-AdditionalItems.html ├── module-childApplicators-AdditionalProperties.html ├── module-childApplicators-ArrayHandler.html ├── module-childApplicators-ChildApplicator.html ├── module-childApplicators-ChildrenHandler.html ├── module-childApplicators-Items.html ├── module-childApplicators-ObjectHandler.html ├── module-childApplicators-Properties.html ├── module-childApplicators.html ├── module-components-AddButton.html ├── module-components-BooleanInput.html ├── module-components-Component.html ├── module-components-GeneratorIcon.html ├── module-components-InputComponent.html ├── module-components-InputTitle.html ├── module-components-InstanceViewPanel.html ├── module-components-LabelTitle.html ├── module-components-NumericInput.html ├── module-components-PillsInstancePanel.html ├── module-components-RemoveButton.html ├── module-components-RequiredIcon.html ├── module-components-RootIcon.html ├── module-components-Select.html ├── module-components-SelectInstancePanel.html ├── module-components-TextInput.html ├── module-components-Toggler.html ├── module-components.html ├── module-formElement-FormElement.html ├── module-formElement.html ├── module-formElementDefinitions-State.html ├── module-formElementDefinitions.html ├── module-inPlaceApplicators-Aggregation.html ├── module-inPlaceApplicators-IPASchema.html ├── module-inPlaceApplicators-InPlaceApplicator.html ├── module-inPlaceApplicators.html ├── module-layouts-Layout.html ├── module-layouts.html ├── module-selectors-Selector.html ├── module-selectors-SelectorsContainer.html ├── module-selectors-SelectorsToolbar.html ├── module-selectors.html ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── Apache-License-2.0.txt │ │ ├── lang-css.js │ │ └── prettify.js ├── styles │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── utils_formElementByDiv.js.html ├── utils_lcm.js.html └── utils_pointerToId.js.html ├── package.json └── src ├── JsonSchemaForms.js ├── form ├── components.js ├── defaultFormOptions.js ├── formElement.js ├── formElementDefinitions.js ├── json-schema │ ├── JsonSchemaKeywords.js │ ├── JsonSchemaType.js │ ├── childApplicators.js │ └── inPlaceApplicators.js ├── layouts.js └── selectors.js ├── index.js ├── test-schema.js └── utils ├── formElementByDiv.js ├── lcm.js └── pointerToId.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | node: true, 5 | es6: true 6 | }, 7 | parser: 'babel-eslint', 8 | plugins: ['jsdoc'], 9 | extends: ['eslint:recommended', 'plugin:jsdoc/recommended'], 10 | rules: { 11 | 'jsdoc/check-examples': 1, 12 | // Use only as guidance. Set to 0 before "git add". 13 | 'jsdoc/check-indentation': 0, 14 | 'jsdoc/check-syntax': 1, 15 | 'jsdoc/match-description': 1, 16 | 'jsdoc/require-description': 1, 17 | // Use only as guidance. Set to 0 before "git add". 18 | 'jsdoc/require-description-complete-sentence': 0 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /*.adoc 2 | node_modules 3 | .cache 4 | /serve 5 | /tests 6 | /yarn-error.log 7 | -------------------------------------------------------------------------------- /.jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "include": [ 4 | "./src", 5 | "./README.md" 6 | ] 7 | }, 8 | "opts": { 9 | "destination": "./docs", 10 | "recurse": true 11 | }, 12 | "recurseDepth": 3, 13 | "plugins": [ 14 | "plugins/markdown" 15 | ], 16 | "templates": { 17 | "default": { 18 | "includeDate": false 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.2.0-alpha.2] - 2020-05-27 10 | ### Added 11 | - First working implementation. 12 | - Documentation and usage hints. 13 | 14 | 15 | [Unreleased]: https://github.com/hblanko/cookbase/compare/v0.2.0-alpha.2...HEAD 16 | [0.2.0-alpha.2]: https://github.com/hblanko/cookbase/releases/tag/v0.2.0-alpha.2 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JsonSchemaForms 2 | 3 | A JavaScript tool that generates HTML forms from JSON Schemas. 4 | 5 | This implementation accepts schemas following the [JSON Schema Draft 2019-09 specification](https://json-schema.org/), with the goal of providing a straightforward mean to express potentially large and complex JSON Schemas in an intuitive fashion. 6 | 7 | JsonSchemaForms comes with [Bootstrap](https://getbootstrap.com/) (4.5+) and [Font Awesome](https://fontawesome.com/) (5.13+) support in order to organize and decorate the layout. While these libraries are not required, they are highly recommended to get the form properly rendered by the browser. 8 | 9 | JsonSchemaForms makes use of the [JSON Schema \$Ref Parser](https://github.com/APIDevTools/json-schema-ref-parser) to resolve and dereference the schemas to be processed. 10 | 11 | ## Usage 12 | 13 | The JsonSchemaForms module provides a `build()` function that performs the whole process of analyzing a JSON Schema and generating the DOM and internal representation of the form. Have a look at the [`JsonSchemaForms.build()` API](https://hblanko.github.io/json-schema-forms/module-JsonSchemaForms.html) for usage details. 14 | 15 | ### Through CDN 16 | 17 | The quickly and easy way to make JsonSchemaForms available to your scripts, by adding a few CDN links to your HTML code. 18 | 19 | JsonSchemaForms provides a script and style sheet that can be linked adding the following tags: 20 | 21 | ```html 22 | 23 | ``` 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | On top of that, as mentioned before, Bootstrap and Font Awesome allow for a nice-looking result, so their CDN links are recommended to be included, too. 30 | 31 | Hence, the full picture of a barebone `example.html` using JsonSchemaForms CDN ends up looking like this: 32 | 33 | ```html 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
58 |

 59 |   
 60 | 
 61 | ```
 62 | 
 63 | A basic script `example.js` may look like this:
 64 | 
 65 | ```javascript
 66 | // You've got two options in order to plug your JSON Schema:
 67 | //   1. Provide a URL to a JSON Schema.
 68 | //   2. Directly assign an object following the JSON Schema format.
 69 | 
 70 | // const schema = 'http://landarltracker.com/schemas/test.json';
 71 | const schema = {
 72 |   title: 'The Root Form Element',
 73 |   description: 'Easy, right?',
 74 |   type: 'string',
 75 | };
 76 | 
 77 | // Also, you can define the form behavior on submission, e.g.:
 78 | const submitCallback = (rootFormElement) => {
 79 |   // Show the resulting JSON instance in your page.
 80 |   document.getElementById('json-result').innerText = JSON.stringify(
 81 |     rootFormElement.getInstance(),
 82 |     null,
 83 |     2
 84 |   );
 85 |   // (For testing purposes, return false to prevent automatic redirect.)
 86 |   return false;
 87 | };
 88 | 
 89 | // Finally, get your form...
 90 | const jsonSchemaForm = JsonSchemaForms.build(schema, submitCallback);
 91 | 
 92 | // ... and attach it somewhere to your page.
 93 | window.addEventListener('load', () => {
 94 |   document.getElementById('form-container').appendChild(jsonSchemaForm);
 95 | });
 96 | ```
 97 | 
 98 | This example works directly out of the box. Feel free to copy, paste, and play around with it!
 99 | 
100 | ### Custom bundle
101 | 
102 | If you prefer to import it into your own project, use your favorite package manager to install it:
103 | 
104 | ```console
105 | yarn add json-schema-forms
106 | ```
107 | 
108 | or
109 | 
110 | ```console
111 | npm i json-schema-forms
112 | ```
113 | 
114 | And just make it available by including at the top of your script:
115 | 
116 | ```javascript
117 | import JsonSchemaForms from 'json-schema-forms';
118 | ```
119 | 
120 | Then, you can use it as shown in `example.js` through the `build()` function
121 | (check [the API docs](https://hblanko.github.io/json-schema-forms/module-JsonSchemaForms.html) for detailed information).
122 | 
123 | ## What's to come?
124 | 
125 | Base code is still under work, being several features not yet covered (but expected to be):
126 | 
127 | - Conditional in-place applicators.
128 | - Some child applicators (e.g. `patternProperties`) and validation keywords.
129 | - Aggregation logic yet to be implemented for several keywords.
130 | 
131 | _JsonSchemaForms was initially conceived as a basis for a specialized version to be used in the framework of [the Cookbase Project](https://github.com/hblanko/cookbase)._
132 | 


--------------------------------------------------------------------------------
/css/json-schema-forms.css:
--------------------------------------------------------------------------------
 1 | @charset "UTF-8";
 2 | 
 3 | body {
 4 |   background-color: #f5f6f7;
 5 | }
 6 | 
 7 | .help-icon {
 8 |   color: grey;
 9 |   transition: 0.3s;
10 |   opacity: 0.5;
11 | }
12 | 
13 | .help-icon:hover {
14 |   color: #0275d8;
15 |   opacity: 1;
16 |   transition: 0.3s;
17 |   cursor: default;
18 | }
19 | 
20 | .fas.fa-bullseye {
21 |   color: #ff8b8b;
22 |   font-size: 1.25rem;
23 | }
24 | 
25 | .fas.fa-asterisk {
26 |   color: orange;
27 |   font-size: 1.25rem;
28 | }
29 | 
30 | .fab.fa-sourcetree {
31 |   color: #ef5350;
32 |   font-size: 1.25rem;
33 | }
34 | 
35 | .btn,
36 | input.form-control,
37 | option,
38 | .dropdown-item {
39 |   transition: 0.5s;
40 | }
41 | 
42 | .form-control {
43 |   max-width: 300px;
44 | }
45 | 
46 | .btn[disabled],
47 | input.form-control[disabled],
48 | option[disabled],
49 | .dropdown-item[disabled] {
50 |   transition: 0.5s;
51 | }
52 | 
53 | label.custom-control-label {
54 |   cursor: pointer;
55 | }
56 | 
57 | .disabled {
58 |   display: none;
59 | }
60 | 
61 | .container-fluid {
62 |   max-width: var(--container-max-width);
63 | }
64 | 
65 | .icon {
66 |   width: var(--icon-offset);
67 |   min-width: var(--icon-offset);
68 | }
69 | 
70 | .primitive {
71 |   padding-left: var(--icon-offset);
72 | }
73 | 
74 | :root {
75 |   --icon-offset: 40px;
76 |   --container-max-width: 900px;
77 | }
78 | 


--------------------------------------------------------------------------------
/docs/JsonSchemaForms.js.html:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  3 | 
  4 |     
  5 |     JSDoc: Source: JsonSchemaForms.js
  6 | 
  7 |     
  8 |     
  9 |     
 12 |     
 13 |     
 14 | 
 15 | 
 16 | 
 17 | 
 18 | 
19 | 20 |

Source: JsonSchemaForms.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * The main module implementing the form construction.
 31 |  *
 32 |  * @module JsonSchemaForms
 33 |  */
 34 | 'use strict';
 35 | 
 36 | import FormElement from './form/formElement.js';
 37 | import defaultFormOptions from './form/defaultFormOptions.js';
 38 | 
 39 | import $RefParser from '@apidevtools/json-schema-ref-parser';
 40 | import jquery from 'jquery';
 41 | 
 42 | /**
 43 |  * Builds an HTML form from a given JSON Schema. The main function to be
 44 |  * interacted by users.
 45 |  *
 46 |  * It allows to provide specific options for the form construction, and a custom
 47 |  * callback function triggered on submission.
 48 |  *
 49 |  * @param {object} schema The JSON Schema to represent as an HTML form.
 50 |  * @param {Function} [submitCallback=() => {}] Callback function to be called
 51 |  * when the form triggers the `submit` DOM event.
 52 |  * @param {object} customFormOptions Form options overriding the default. See
 53 |  * {@link defaultFormOptions} for details.
 54 |  *
 55 |  * @returns {HTMLDivElement} A `<div>` element containing the HTML form.
 56 |  */
 57 | function build(schema, submitCallback = () => {}, customFormOptions = {}) {
 58 |   // Builds form options by merging the provided custom options with the
 59 |   // defaults.
 60 |   const formOptions = {
 61 |     ...defaultFormOptions,
 62 |     ...customFormOptions,
 63 |   };
 64 | 
 65 |   // Ensures jQuery is available if Bootstrap is required but failed loading.
 66 |   if (formOptions.bootstrap && !window.$) {
 67 |     console.warn('Bootstrap expected but JQuery was not loaded.');
 68 |     window.$ = jquery;
 69 |   }
 70 | 
 71 |   const containerDiv = document.createElement('div');
 72 | 
 73 |   $RefParser.dereference(schema, (err, s) => {
 74 |     if (err) console.error(err);
 75 |     else {
 76 |       // Generates the form recursively.
 77 |       const rootFormElement = new FormElement(s, {
 78 |         formOptions,
 79 |       });
 80 | 
 81 |       // Creates the HTML structure containing the form.
 82 |       const formDiv = document.createElement('div');
 83 |       const form = formDiv.appendChild(document.createElement('form'));
 84 |       form.id = formOptions.formId;
 85 | 
 86 |       form.addEventListener('submit', (event) => {
 87 |         const valid = submitCallback(rootFormElement);
 88 | 
 89 |         if (valid === false) event.preventDefault();
 90 |       });
 91 | 
 92 |       const submitButton = form.appendChild(document.createElement('button'));
 93 |       submitButton.type = 'submit';
 94 |       submitButton.innerText = formOptions.submitButtonText;
 95 | 
 96 |       containerDiv.appendChild(rootFormElement.layout.root);
 97 |       containerDiv.appendChild(formDiv);
 98 | 
 99 |       if (formOptions.bootstrap) {
100 |         containerDiv.classList.add('container-fluid', 'bg-light');
101 |         formDiv.classList.add('pt-4');
102 |         submitButton.classList.add('btn', 'btn-primary');
103 |       }
104 |     }
105 |   });
106 | 
107 |   return containerDiv;
108 | }
109 | 
110 | export default { build };
111 | 
112 |
113 |
114 | 115 | 116 | 117 | 118 |
119 | 120 | 123 | 124 |
125 | 126 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hblanko/json-schema-forms/c8caf7182f84cd50e8e0c76da298f895107dd1d1/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/form_defaultFormOptions.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: form/defaultFormOptions.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: form/defaultFormOptions.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
30 |  * The default options used to build the form.
31 |  *
32 |  * @enum
33 |  */
34 | const defaultFormOptions = {
35 |   formId: 'json-schema-form',
36 |   bootstrap: '4.5',
37 |   fontAwesome: '5.13.0',
38 |   maxEnumTabs: 5,
39 |   maxSelectSize: 6,
40 |   booleanTranslateFunction: (b) => (b ? 'Yes' : 'No'),
41 |   arraySubstitute: 'List',
42 |   objectSubstitute: 'Group',
43 |   submitButtonText: 'Submit',
44 |   initTogglersOff: false,
45 |   arrayItemTitle: 'Item',
46 |   adHocOptions: {
47 |     todo: 'To-do',
48 |   },
49 | };
50 | 
51 | export default defaultFormOptions;
52 | 
53 |
54 |
55 | 56 | 57 | 58 | 59 |
60 | 61 | 64 | 65 |
66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/form_formElementDefinitions.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: form/formElementDefinitions.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: form/formElementDefinitions.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * Module containing classes and objects that define the form element type and
 31 |  * behavior.
 32 |  *
 33 |  * @module formElementDefinitions
 34 |  */
 35 | 
 36 | /**
 37 |  * The available types of a form element.
 38 |  *
 39 |  * @enum {string}
 40 |  */
 41 | const ElementType = {
 42 |   /** The form element representing the root JSON Schema. */
 43 |   ROOT: 'root',
 44 | 
 45 |   /** A required form element. */
 46 |   REQUIRED: 'required',
 47 | 
 48 |   /** An optional form element. */
 49 |   OPTIONAL: 'optional',
 50 | 
 51 |   /** A form element able to be removed. */
 52 |   REMOVABLE: 'removable',
 53 | };
 54 | 
 55 | /**
 56 |  * The possible types of a form element title.
 57 |  *
 58 |  * @enum {string}
 59 |  */
 60 | const TitleType = {
 61 |   /** A regular, unmodifiable form element title. */
 62 |   STATIC: 'static',
 63 | 
 64 |   /** An editable form element title. */
 65 |   FIELD: 'field',
 66 | 
 67 |   /** A static element title for an added JSON Schema's `array` item. */
 68 |   ADDED_ITEM: 'addedItem',
 69 | };
 70 | 
 71 | /** The form element state descriptor. */
 72 | class State {
 73 |   /**
 74 |    * Class constructor.
 75 |    *
 76 |    * @param {boolean} [active=true] Flag indicating whether the form element is
 77 |    * active (i.e. the form element can be interacted --at least its toggler).
 78 |    * @param {boolean?} [disabled=null] Flag indicating whether the form element
 79 |    * is disabled (i.e. the input fields or child elements cannot be interacted).
 80 |    */
 81 |   constructor(active = true, disabled = null) {
 82 |     /**
 83 |      * Indicates whether the form element is active.
 84 |      *
 85 |      * @type {boolean}
 86 |      */
 87 |     this.active = active;
 88 | 
 89 |     /**
 90 |      * Indicates whether the form element is disabled.
 91 |      *
 92 |      * @type {boolean?}
 93 |      */
 94 |     this.disabled = disabled;
 95 |   }
 96 | }
 97 | 
 98 | export { ElementType, State, TitleType };
 99 | 
100 |
101 |
102 | 103 | 104 | 105 | 106 |
107 | 108 | 111 | 112 |
113 | 114 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/form_json-schema_JsonSchemaKeywords.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: form/json-schema/JsonSchemaKeywords.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: form/json-schema/JsonSchemaKeywords.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * Keywords and types specified by the [JSON Schema 2019-09 RFC Draft](https://json-schema.org/draft/2019-09/json-schema-core.html).
 31 |  *
 32 |  * @module JsonSchemaKeywords
 33 |  */
 34 | 
 35 | /**
 36 |  * Object containing the JSON Schema keywords classified by its role in the
 37 |  * schema definition.
 38 |  *
 39 |  * @enum {object.<string, string>}
 40 |  */
 41 | const JsonSchemaKeywords = {
 42 |   /**
 43 |    * Keywords representing [JSON Schema annotations](https://json-schema.org/draft/2019-09/json-schema-core.html#annotations).
 44 |    *
 45 |    * @enum {string}
 46 |    */
 47 |   Annotation: {
 48 |     DEFAULT: 'default',
 49 |     DEPRECATED: 'deprecated',
 50 |     DESCRIPTION: 'description',
 51 |     EXAMPLES: 'examples',
 52 |     READ_ONLY: 'readOnly',
 53 |     TITLE: 'title',
 54 |     WRITE_ONLY: 'writeOnly',
 55 |   },
 56 | 
 57 |   /**
 58 |    * Keywords representing [JSON Schema applicators for `array` instances](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.3.1).
 59 |    *
 60 |    * @enum {string}
 61 |    */
 62 |   ArrayApplicator: {
 63 |     ADDITIONAL_ITEMS: 'additionalItems',
 64 |     CONTAINS: 'contains',
 65 |     ITEMS: 'items',
 66 |     UNEVALUATED_ITEMS: 'unevaluatedItems',
 67 |   },
 68 | 
 69 |   /**
 70 |    * Keywords representing [JSON Schema validation conditions for `array`
 71 |    * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4).
 72 |    *
 73 |    * @enum {string}
 74 |    */
 75 |   ArrayValidation: {
 76 |     MAX_CONTAINS: 'maxContains',
 77 |     MAX_ITEMS: 'maxItems',
 78 |     MIN_CONTAINS: 'minContains',
 79 |     MIN_ITEMS: 'minItems',
 80 |     UNIQUE_ITEMS: 'uniqueItems',
 81 |   },
 82 | 
 83 |   /**
 84 |    * Keywords representing [JSON Schema in-place applicators with boolean logic](https://json-schema.org/draft/2019-09/json-schema-core.html#logic).
 85 |    *
 86 |    * @enum {string}
 87 |    */
 88 |   BooleanLogicApplicator: {
 89 |     ALL_OF: 'allOf',
 90 |     ANY_OF: 'anyOf',
 91 |     NOT: 'not',
 92 |     ONE_OF: 'oneOf',
 93 |   },
 94 | 
 95 |   /**
 96 |    * Keywords representing [JSON Schema in-place applicators conditionally](https://json-schema.org/draft/2019-09/json-schema-core.html#conditional).
 97 |    *
 98 |    * @enum {string}
 99 |    */
100 |   ConditionalApplicator: {
101 |     IF: 'if',
102 |     THEN: 'then',
103 |     ELSE: 'else',
104 |   },
105 | 
106 |   /**
107 |    * Keywords representing [generic JSON Schema validation conditions](https://json-schema.org/draft/2019-09/json-schema-validation.html#general).
108 |    *
109 |    * @enum {string}
110 |    */
111 |   GenericValidation: {
112 |     CONST: 'const',
113 |     ENUM: 'enum',
114 |     TYPE: 'type',
115 |   },
116 | 
117 |   /**
118 |    * Keywords representing [JSON Schema validation conditions for numeric
119 |    * (`number` and `integer`) instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#numeric).
120 |    *
121 |    * @enum {string}
122 |    */
123 |   NumberValidation: {
124 |     EXCLUSIVE_MAXIMUM: 'exclusiveMaximum',
125 |     EXCLUSIVE_MINIMUM: 'exclusiveMinimum',
126 |     MAXIMUM: 'maximum',
127 |     MINIMUM: 'minimum',
128 |     MULTIPLE_OF: 'multipleOf',
129 |   },
130 | 
131 |   /**
132 |    * Keywords representing [JSON Schema applicators for `object` instances](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.3.2).
133 |    *
134 |    * @enum {string}
135 |    */
136 |   ObjectApplicator: {
137 |     ADDITIONAL_PROPERTIES: 'additionalProperties',
138 |     PATTERN_PROPERTIES: 'patternProperties',
139 |     PROPERTIES: 'properties',
140 |     UNEVALUATED_PROPERTIES: 'unevaluatedProperties',
141 |   },
142 | 
143 |   /**
144 |    * Keywords representing [JSON Schema validation conditions for `object`
145 |    * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5).
146 |    *
147 |    * @enum {string}
148 |    */
149 |   ObjectValidation: {
150 |     DEPENDENT_REQUIRED: 'dependentRequired',
151 |     MAX_PROPERTIES: 'maxProperties',
152 |     MIN_PROPERTIES: 'minProperties',
153 |     PROPERTY_NAMES: 'propertyNames',
154 |     REQUIRED: 'required',
155 |   },
156 | 
157 |   /**
158 |    * Keywords representing [JSON Schema validation conditions for `string`
159 |    * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#string).
160 |    *
161 |    * @enum {string}
162 |    */
163 |   StringValidation: {
164 |     MAX_LENGTH: 'maxLength',
165 |     MIN_LENGTH: 'minLength',
166 |     PATTERN: 'pattern',
167 |   },
168 | };
169 | 
170 | export default JsonSchemaKeywords;
171 | 
172 |
173 |
174 | 175 | 176 | 177 | 178 |
179 | 180 | 183 | 184 |
185 | 186 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /docs/form_json-schema_JsonSchemaType.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: form/json-schema/JsonSchemaType.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: form/json-schema/JsonSchemaType.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
30 |  * Module specifying the values that the `type` generic validation keyword can
31 |  * take.
32 |  *
33 |  * @module JsonSchemaType
34 |  *
35 |  * @see {@link https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.1.1}
36 |  */
37 | 
38 | /**
39 |  * List of JSON types defined by the JSON Schema specification.
40 |  *
41 |  * @enum {string}
42 |  */
43 | const JsonSchemaType = {
44 |   ARRAY: 'array',
45 |   BOOLEAN: 'boolean',
46 |   INTEGER: 'integer',
47 |   NULL: 'null',
48 |   NUMBER: 'number',
49 |   OBJECT: 'object',
50 |   STRING: 'string',
51 | };
52 | 
53 | export default JsonSchemaType;
54 | 
55 |
56 |
57 | 58 | 59 | 60 | 61 |
62 | 63 | 66 | 67 |
68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

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 |

JsonSchemaForms

47 |

A JavaScript tool that generates HTML forms from JSON Schemas.

48 |

This implementation accepts schemas following the JSON Schema Draft 2019-09 specification, with the goal of providing a straightforward mean to express potentially large and complex JSON Schemas in an intuitive fashion.

49 |

JsonSchemaForms comes with Bootstrap (4.5+) and Font Awesome (5.13+) support in order to organize and decorate the layout. While these libraries are not required, they are highly recommended to get the form properly rendered by the browser.

50 |

JsonSchemaForms makes use of the JSON Schema $Ref Parser to resolve and dereference the schemas to be processed.

51 |

Usage

52 |

The JsonSchemaForms module provides a build() function that performs the whole process of analyzing a JSON Schema and generating the DOM and internal representation of the form. Have a look at the JsonSchemaForms.build() API for usage details.

53 |

Through CDN

54 |

The quickly and easy way to make JsonSchemaForms available to your scripts, by adding a few CDN links to your HTML code.

55 |

JsonSchemaForms provides a script and style sheet that can be linked adding the following tags:

56 |
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/json-schema-forms@latest/css/json-schema-forms.min.css" />
 57 | 
58 |
<script src="https://cdn.jsdelivr.net/npm/json-schema-forms@latest/dist/json-schema-forms.min.js"></script>
 59 | 
60 |

On top of that, as mentioned before, Bootstrap and Font Awesome allow for a nice-looking result, so their CDN links are recommended to be included, too.

61 |

Hence, the full picture of a barebone example.html using JsonSchemaForms CDN ends up looking like this:

62 |
<!DOCTYPE html>
 63 | <html lang="en">
 64 |   <head>
 65 |     <meta charset="utf-8" />
 66 |     <!-- Bootstrap-related style -->
 67 |     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
 68 |     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous" />
 69 |     <!-- JsonSchemaForms style sheet -->
 70 |     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/json-schema-forms@latest/css/json-schema-forms.min.css" />
 71 |   </head>
 72 | 
 73 |   <body>
 74 |     <!-- Bootstrap and Font Awesome scripts -->
 75 |     <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
 76 |     <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
 77 |     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
 78 |     <script src="https://kit.fontawesome.com/64968f57be.js" crossorigin="anonymous"></script>
 79 |     <!-- JsonSchemaForms script -->
 80 |     <script src="https://cdn.jsdelivr.net/npm/json-schema-forms@latest/dist/json-schema-forms.min.js"></script>
 81 |     <!-- Your script -->
 82 |     <script src="./example.js"></script>
 83 | 
 84 |     <!-- Some containers to use by your script -->
 85 |     <div id="form-container"></div>
 86 |     <pre id="json-result"></pre>
 87 |   </body>
 88 | </html>
 89 | 
90 |

A basic script example.js may look like this:

91 |
// You've got two options in order to plug your JSON Schema:
 92 | //   1. Provide a URL to a JSON Schema.
 93 | //   2. Directly assign an object following the JSON Schema format.
 94 | 
 95 | // const schema = 'http://landarltracker.com/schemas/test.json';
 96 | const schema = {
 97 |   title: 'The Root Form Element',
 98 |   description: 'Easy, right?',
 99 |   type: 'string',
100 | };
101 | 
102 | // Also, you can define the form behavior on submission, e.g.:
103 | const submitCallback = (rootFormElement) => {
104 |   // Show the resulting JSON instance in your page.
105 |   document.getElementById('json-result').innerText = JSON.stringify(
106 |     rootFormElement.getInstance(),
107 |     null,
108 |     2
109 |   );
110 |   // (For testing purposes, return false to prevent automatic redirect.)
111 |   return false;
112 | };
113 | 
114 | // Finally, get your form...
115 | const jsonSchemaForm = JsonSchemaForms.build(schema, submitCallback);
116 | 
117 | // ... and attach it somewhere to your page.
118 | window.addEventListener('load', () => {
119 |   document.getElementById('form-container').appendChild(jsonSchemaForm);
120 | });
121 | 
122 |

This example works directly out of the box. Feel free to copy, paste, and play around with it!

123 |

Custom bundle

124 |

If you prefer to import it into your own project, use your favorite package manager to install it:

125 |
yarn add json-schema-forms
126 | 
127 |

or

128 |
npm i json-schema-forms
129 | 
130 |

And just make it available by including at the top of your script:

131 |
import JsonSchemaForms from 'json-schema-forms';
132 | 
133 |

Then, you can use it as shown in example.js through the build() function 134 | (check the API docs for detailed information).

135 |

What's to come?

136 |

Base code is still under work, being several features not yet covered (but expected to be):

137 |
    138 |
  • Conditional in-place applicators.
  • 139 |
  • Some child applicators (e.g. patternProperties) and validation keywords.
  • 140 |
  • Aggregation logic yet to be implemented for several keywords.
  • 141 |
142 |

JsonSchemaForms was initially conceived as a basis for a specialized version to be used in the framework of the Cookbase Project.

143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 | 152 | 155 | 156 |
157 | 158 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /docs/module-JsonSchemaForms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Module: JsonSchemaForms 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Module: JsonSchemaForms

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 |
38 |
39 | 40 | 41 |

The main module implementing the form construction.

42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
Source:
89 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |

Methods

140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |

(inner) build(schema, submitCallbackopt, customFormOptions) → {HTMLDivElement}

148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 |

Builds an HTML form from a given JSON Schema. The main function to be 156 | interacted by users.

157 |

It allows to provide specific options for the form construction, and a custom 158 | callback function triggered on submission.

159 |
160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 |
Parameters:
170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 209 | 210 | 211 | 218 | 219 | 220 | 221 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 244 | 245 | 246 | 255 | 256 | 257 | 258 | 263 | 264 | 265 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 284 | 285 | 286 | 293 | 294 | 295 | 296 | 299 | 300 | 301 | 303 | 304 | 305 | 306 | 307 |
NameTypeAttributesDefaultDescription
schema 202 | 203 | 204 | object 205 | 206 | 207 | 208 | 212 | 213 | 214 | 215 | 216 | 217 | 222 | 223 |

The JSON Schema to represent as an HTML form.

submitCallback 237 | 238 | 239 | function 240 | 241 | 242 | 243 | 247 | 248 | <optional>
249 | 250 | 251 | 252 | 253 | 254 |
259 | 260 | () => {} 261 | 262 |

Callback function to be called 266 | when the form triggers the submit DOM event.

customFormOptions 277 | 278 | 279 | object 280 | 281 | 282 | 283 | 287 | 288 | 289 | 290 | 291 | 292 | 297 | 298 |

Form options overriding the default. See 302 | defaultFormOptions for details.

308 | 309 | 310 | 311 | 312 | 313 | 314 |
315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 |
Source:
342 |
345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 |
353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 |
Returns:
369 | 370 | 371 |
372 |

A <div> element containing the HTML form.

373 |
374 | 375 | 376 | 377 |
378 |
379 | Type 380 |
381 |
382 | 383 | HTMLDivElement 384 | 385 | 386 |
387 |
388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 |
402 | 403 |
404 | 405 | 406 | 407 | 408 |
409 | 410 | 413 | 414 |
415 | 416 | 419 | 420 | 421 | 422 | 423 | -------------------------------------------------------------------------------- /docs/module-JsonSchemaType.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Module: JsonSchemaType 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Module: JsonSchemaType

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 |
38 |
39 | 40 | 41 |

Module specifying the values that the type generic validation keyword can 42 | take.

43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
Source:
90 |
93 | 94 | 95 | 96 | 97 | 98 |
See:
99 |
100 | 103 |
104 | 105 | 106 | 107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 |

Members

146 | 147 | 148 | 149 |

(inner, constant) JsonSchemaType :string

150 | 151 | 152 | 153 | 154 |
155 |

List of JSON types defined by the JSON Schema specification.

156 |
157 | 158 | 159 | 160 |
Type:
161 |
    162 |
  • 163 | 164 | string 165 | 166 | 167 |
  • 168 |
169 | 170 | 171 | 172 | 173 | 174 |
Properties:
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 |
NameTypeDescription
ARRAY 204 | 205 | 206 | string 207 | 208 | 209 | 210 |
BOOLEAN 227 | 228 | 229 | string 230 | 231 | 232 | 233 |
INTEGER 250 | 251 | 252 | string 253 | 254 | 255 | 256 |
NULL 273 | 274 | 275 | string 276 | 277 | 278 | 279 |
NUMBER 296 | 297 | 298 | string 299 | 300 | 301 | 302 |
OBJECT 319 | 320 | 321 | string 322 | 323 | 324 | 325 |
STRING 342 | 343 | 344 | string 345 | 346 | 347 | 348 |
360 | 361 | 362 | 363 | 364 |
365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 |
Source:
392 |
395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 |
403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 |
418 | 419 |
420 | 421 | 422 | 423 | 424 |
425 | 426 | 429 | 430 |
431 | 432 | 435 | 436 | 437 | 438 | 439 | -------------------------------------------------------------------------------- /docs/module-childApplicators-ArrayHandler.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: ArrayHandler 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: ArrayHandler

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | childApplicators~ArrayHandler(parent)

33 | 34 |

Handler for child applicator containers of array-typed form elements.

35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 |

Constructor

46 | 47 | 48 | 49 |

new ArrayHandler(parent)

50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |

Class constructor.

58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Parameters:
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 |
NameTypeDescription
parent 97 | 98 | 99 | module:formElement~FormElement 100 | 101 | 102 | 103 |

The parent form element 110 | containing the child applicator containers to be handled.

116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
Source:
150 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 | 185 |

Extends

186 | 187 | 188 | 189 | 190 |
    191 |
  • ChildrenHandler
  • 192 |
193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 |

Methods

211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 |

getInstance() → {any}

219 | 220 | 221 | 222 | 223 | 224 | 225 |
226 |

Retrieves the JSON instance expressed by the child applicator containers 227 | together with the inputted values.

228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 |
243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 |
Source:
270 |
273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 |
281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
Returns:
297 | 298 | 299 |
300 |

The JSON instance associated to the form element.

301 |
302 | 303 | 304 | 305 |
306 |
307 | Type 308 |
309 |
310 | 311 | any 312 | 313 | 314 |
315 |
316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 |
332 | 333 | 334 | 335 | 336 |
337 | 338 | 341 | 342 |
343 | 344 | 347 | 348 | 349 | 350 | 351 | -------------------------------------------------------------------------------- /docs/module-childApplicators-ObjectHandler.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: ObjectHandler 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: ObjectHandler

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | childApplicators~ObjectHandler(parent)

33 | 34 |

Handler for child applicator containers of object-typed form elements.

35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 |

Constructor

46 | 47 | 48 | 49 |

new ObjectHandler(parent)

50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |

Class constructor.

58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Parameters:
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 |
NameTypeDescription
parent 97 | 98 | 99 | module:formElement~FormElement 100 | 101 | 102 | 103 |

The parent form element 110 | containing the child applicator containers to be handled.

116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
Source:
150 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 | 185 |

Extends

186 | 187 | 188 | 189 | 190 |
    191 |
  • ChildrenHandler
  • 192 |
193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 |

Methods

211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 |

getInstance() → {any}

219 | 220 | 221 | 222 | 223 | 224 | 225 |
226 |

Retrieves the JSON instance expressed by the child applicator containers 227 | together with the inputted values.

228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 |
243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 |
Source:
270 |
273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 |
281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
Returns:
297 | 298 | 299 |
300 |

The JSON instance associated to the form element.

301 |
302 | 303 | 304 | 305 |
306 |
307 | Type 308 |
309 |
310 | 311 | any 312 | 313 | 314 |
315 |
316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 |
332 | 333 | 334 | 335 | 336 |
337 | 338 | 341 | 342 |
343 | 344 | 347 | 348 | 349 | 350 | 351 | -------------------------------------------------------------------------------- /docs/module-components-Component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Interface: Component 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Interface: Component

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | components~Component

33 | 34 | 35 |
36 | 37 |
38 |
39 | 40 | 41 |

Interface for classes that represent a form component.

42 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
Source:
75 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 | 87 | 88 | 89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |

Members

106 | 107 | 108 | 109 |

domElement :HTMLDivElement

110 | 111 | 112 | 113 | 114 |
115 |

Reference to the DOM object that contains the HTML structure of the 116 | component.

117 |
118 | 119 | 120 | 121 |
Type:
122 |
    123 |
  • 124 | 125 | HTMLDivElement 126 | 127 | 128 |
  • 129 |
130 | 131 | 132 | 133 | 134 | 135 |
136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 |
Source:
163 |
166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 |

Methods

185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 |

disable()

193 | 194 | 195 | 196 | 197 | 198 | 199 |
200 |

Disables the component.

201 |
202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 |
216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 |
Source:
243 |
246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 |
254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 |

enable()

281 | 282 | 283 | 284 | 285 | 286 | 287 |
288 |

Enables the component.

289 |
290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 |
304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 |
Source:
331 |
334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 |
342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 |
369 | 370 |
371 | 372 | 373 | 374 | 375 |
376 | 377 | 380 | 381 |
382 | 383 | 386 | 387 | 388 | 389 | 390 | -------------------------------------------------------------------------------- /docs/module-formElementDefinitions-State.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: State 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: State

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | formElementDefinitions~State(activeopt, disabledopt, nullable)

33 | 34 |

The form element state descriptor.

35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 |

Constructor

46 | 47 | 48 | 49 |

new State(activeopt, disabledopt, nullable)

50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |

Class constructor.

58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Parameters:
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 108 | 109 | 110 | 119 | 120 | 121 | 122 | 127 | 128 | 129 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 148 | 149 | 150 | 161 | 162 | 163 | 164 | 169 | 170 | 171 | 173 | 174 | 175 | 176 | 177 |
NameTypeAttributesDefaultDescription
active 101 | 102 | 103 | boolean 104 | 105 | 106 | 107 | 111 | 112 | <optional>
113 | 114 | 115 | 116 | 117 | 118 |
123 | 124 | true 125 | 126 |

Flag indicating whether the form element is 130 | active (i.e. the form element can be interacted --at least its toggler).

disabled 141 | 142 | 143 | boolean 144 | 145 | 146 | 147 | 151 | 152 | <optional>
153 | 154 | 155 | 156 | <nullable>
157 | 158 | 159 | 160 |
165 | 166 | null 167 | 168 |

Flag indicating whether the form element 172 | is disabled (i.e. the input fields or child elements cannot be interacted).

178 | 179 | 180 | 181 | 182 | 183 | 184 |
185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 |
Source:
212 |
215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 |
223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 |
245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |

Members

260 | 261 | 262 | 263 |

active :boolean

264 | 265 | 266 | 267 | 268 |
269 |

Indicates whether the form element is active.

270 |
271 | 272 | 273 | 274 |
Type:
275 |
    276 |
  • 277 | 278 | boolean 279 | 280 | 281 |
  • 282 |
283 | 284 | 285 | 286 | 287 | 288 |
289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 |
Source:
316 |
319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 |
327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 |

(nullable) disabled :boolean

336 | 337 | 338 | 339 | 340 |
341 |

Indicates whether the form element is disabled.

342 |
343 | 344 | 345 | 346 |
Type:
347 |
    348 |
  • 349 | 350 | boolean 351 | 352 | 353 |
  • 354 |
355 | 356 | 357 | 358 | 359 | 360 |
361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 |
Source:
388 |
391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 |
399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 |
414 | 415 |
416 | 417 | 418 | 419 | 420 |
421 | 422 | 425 | 426 |
427 | 428 | 431 | 432 | 433 | 434 | 435 | -------------------------------------------------------------------------------- /docs/module-inPlaceApplicators-Aggregation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Aggregation 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Aggregation

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | inPlaceApplicators~Aggregation(keyword, …init)

33 | 34 |

Class that handles keyword collision during aggregation process.

35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 |

Constructor

46 | 47 | 48 | 49 |

new Aggregation(keyword, …init)

50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |

Class constructor.

58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Parameters:
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 106 | 107 | 108 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 137 | 138 | 139 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 |
NameTypeAttributesDescription
keyword 99 | 100 | 101 | string 102 | 103 | 104 | 105 | 109 | 110 | 111 | 112 | 113 | 114 |

The aggregated JSON Schema keyword.

init 130 | 131 | 132 | any 133 | 134 | 135 | 136 | 140 | 141 | 142 | 143 | 144 | 145 | <repeatable>
146 | 147 |

The initial values to aggregate.

158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 |
Source:
192 |
195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 |
225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 |

Methods

242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 |

add(e)

250 | 251 | 252 | 253 | 254 | 255 | 256 |
257 |

Adds a value to the aggregation, or joins the content of another 258 | Aggregation object.

259 |
260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 |
Parameters:
270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 |
NameTypeDescription
e 298 | 299 | 300 | any 301 | 302 | 303 | 304 |

The value/aggregation to be added/joined.

316 | 317 | 318 | 319 | 320 | 321 | 322 |
323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 |
Source:
350 |
353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 |
361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 |

resolve() → {any}

388 | 389 | 390 | 391 | 392 | 393 | 394 |
395 |

Generates an aggregated value following the specific rules associated to 396 | the keyword.

397 |
398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 |
412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 |
Source:
439 |
442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 |
To Do:
450 |
451 |
    452 |
  • Implement specific logic for every keyword.
  • 453 |
454 |
455 | 456 |
457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 |
Returns:
473 | 474 | 475 |
476 |

The value resulted of applying the aggregation rules to the 477 | different contained values.

478 |
479 | 480 | 481 | 482 |
483 |
484 | Type 485 |
486 |
487 | 488 | any 489 | 490 | 491 |
492 |
493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 |
507 | 508 |
509 | 510 | 511 | 512 | 513 |
514 | 515 | 518 | 519 |
520 | 521 | 524 | 525 | 526 | 527 | 528 | -------------------------------------------------------------------------------- /docs/module-inPlaceApplicators-InPlaceApplicator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: InPlaceApplicator 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: InPlaceApplicator

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | inPlaceApplicators~InPlaceApplicator(subschemas, selected)

33 | 34 |

Class representing a JSON Schema in-place applicator.

35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 |

Constructor

46 | 47 | 48 | 49 |

new InPlaceApplicator(subschemas, selected)

50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |

Class constructor.

58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Parameters:
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 128 | 129 | 130 | 131 | 132 | 133 | 135 | 136 | 137 | 138 | 139 |
NameTypeDescription
subschemas 97 | 98 | 99 | Array.<module:inPlaceApplicators~IPASchema> 100 | 101 | 102 | 103 |

The array 110 | of nodes representing the subschemas contained by the applicator.

selected 121 | 122 | 123 | number 124 | 125 | 126 | 127 |

The index indicating the subschema to be selected 134 | at initialization.

140 | 141 | 142 | 143 | 144 | 145 | 146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
Source:
174 |
177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 |
185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 |
207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |

Members

222 | 223 | 224 | 225 |

selected :number

226 | 227 | 228 | 229 | 230 |
231 |

The index indicating the selected subschema.

232 |
233 | 234 | 235 | 236 |
Type:
237 |
    238 |
  • 239 | 240 | number 241 | 242 | 243 |
  • 244 |
245 | 246 | 247 | 248 | 249 | 250 |
251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 |
Source:
278 |
281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 |
289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 |

subschemas :Array.<module:inPlaceApplicators~IPASchema>

298 | 299 | 300 | 301 | 302 |
303 |

The array of nodes representing the subschemas contained by the 304 | applicator.

305 |
306 | 307 | 308 | 309 |
Type:
310 | 318 | 319 | 320 | 321 | 322 | 323 |
324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 |
Source:
351 |
354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 |
362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |

Methods

373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 |

getSelectedIpaSchema() → {module:inPlaceApplicators~IPASchema}

381 | 382 | 383 | 384 | 385 | 386 | 387 |
388 |

Retrieves the node representing the in-place applicator subschema that is 389 | currently selected.

390 |
391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 |
405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 |
Source:
432 |
435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 |
443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 |
Returns:
459 | 460 | 461 |
462 |

The selected node 463 | representing an in-place applicator subschema.

464 |
465 | 466 | 467 | 468 |
469 |
470 | Type 471 |
472 |
473 | 474 | module:inPlaceApplicators~IPASchema 475 | 476 | 477 |
478 |
479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 |
493 | 494 |
495 | 496 | 497 | 498 | 499 |
500 | 501 | 504 | 505 |
506 | 507 | 510 | 511 | 512 | 513 | 514 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (() => { 3 | const source = document.getElementsByClassName('prettyprint source linenums'); 4 | let i = 0; 5 | let lineNumber = 0; 6 | let lineId; 7 | let lines; 8 | let totalLines; 9 | let anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = `line${lineNumber}`; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/prettify/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /docs/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/styles/jsdoc-default.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: normal; 4 | font-style: normal; 5 | src: url('../fonts/OpenSans-Regular-webfont.eot'); 6 | src: 7 | local('Open Sans'), 8 | local('OpenSans'), 9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), 10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), 11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); 12 | } 13 | 14 | @font-face { 15 | font-family: 'Open Sans Light'; 16 | font-weight: normal; 17 | font-style: normal; 18 | src: url('../fonts/OpenSans-Light-webfont.eot'); 19 | src: 20 | local('Open Sans Light'), 21 | local('OpenSans Light'), 22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), 23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'), 24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); 25 | } 26 | 27 | html 28 | { 29 | overflow: auto; 30 | background-color: #fff; 31 | font-size: 14px; 32 | } 33 | 34 | body 35 | { 36 | font-family: 'Open Sans', sans-serif; 37 | line-height: 1.5; 38 | color: #4d4e53; 39 | background-color: white; 40 | } 41 | 42 | a, a:visited, a:active { 43 | color: #0095dd; 44 | text-decoration: none; 45 | } 46 | 47 | a:hover { 48 | text-decoration: underline; 49 | } 50 | 51 | header 52 | { 53 | display: block; 54 | padding: 0px 4px; 55 | } 56 | 57 | tt, code, kbd, samp { 58 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 59 | } 60 | 61 | .class-description { 62 | font-size: 130%; 63 | line-height: 140%; 64 | margin-bottom: 1em; 65 | margin-top: 1em; 66 | } 67 | 68 | .class-description:empty { 69 | margin: 0; 70 | } 71 | 72 | #main { 73 | float: left; 74 | width: 70%; 75 | } 76 | 77 | article dl { 78 | margin-bottom: 40px; 79 | } 80 | 81 | article img { 82 | max-width: 100%; 83 | } 84 | 85 | section 86 | { 87 | display: block; 88 | background-color: #fff; 89 | padding: 12px 24px; 90 | border-bottom: 1px solid #ccc; 91 | margin-right: 30px; 92 | } 93 | 94 | .variation { 95 | display: none; 96 | } 97 | 98 | .signature-attributes { 99 | font-size: 60%; 100 | color: #aaa; 101 | font-style: italic; 102 | font-weight: lighter; 103 | } 104 | 105 | nav 106 | { 107 | display: block; 108 | float: right; 109 | margin-top: 28px; 110 | width: 30%; 111 | box-sizing: border-box; 112 | border-left: 1px solid #ccc; 113 | padding-left: 16px; 114 | } 115 | 116 | nav ul { 117 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; 118 | font-size: 100%; 119 | line-height: 17px; 120 | padding: 0; 121 | margin: 0; 122 | list-style-type: none; 123 | } 124 | 125 | nav ul a, nav ul a:visited, nav ul a:active { 126 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 127 | line-height: 18px; 128 | color: #4D4E53; 129 | } 130 | 131 | nav h3 { 132 | margin-top: 12px; 133 | } 134 | 135 | nav li { 136 | margin-top: 6px; 137 | } 138 | 139 | footer { 140 | display: block; 141 | padding: 6px; 142 | margin-top: 12px; 143 | font-style: italic; 144 | font-size: 90%; 145 | } 146 | 147 | h1, h2, h3, h4 { 148 | font-weight: 200; 149 | margin: 0; 150 | } 151 | 152 | h1 153 | { 154 | font-family: 'Open Sans Light', sans-serif; 155 | font-size: 48px; 156 | letter-spacing: -2px; 157 | margin: 12px 24px 20px; 158 | } 159 | 160 | h2, h3.subsection-title 161 | { 162 | font-size: 30px; 163 | font-weight: 700; 164 | letter-spacing: -1px; 165 | margin-bottom: 12px; 166 | } 167 | 168 | h3 169 | { 170 | font-size: 24px; 171 | letter-spacing: -0.5px; 172 | margin-bottom: 12px; 173 | } 174 | 175 | h4 176 | { 177 | font-size: 18px; 178 | letter-spacing: -0.33px; 179 | margin-bottom: 12px; 180 | color: #4d4e53; 181 | } 182 | 183 | h5, .container-overview .subsection-title 184 | { 185 | font-size: 120%; 186 | font-weight: bold; 187 | letter-spacing: -0.01em; 188 | margin: 8px 0 3px 0; 189 | } 190 | 191 | h6 192 | { 193 | font-size: 100%; 194 | letter-spacing: -0.01em; 195 | margin: 6px 0 3px 0; 196 | font-style: italic; 197 | } 198 | 199 | table 200 | { 201 | border-spacing: 0; 202 | border: 0; 203 | border-collapse: collapse; 204 | } 205 | 206 | td, th 207 | { 208 | border: 1px solid #ddd; 209 | margin: 0px; 210 | text-align: left; 211 | vertical-align: top; 212 | padding: 4px 6px; 213 | display: table-cell; 214 | } 215 | 216 | thead tr 217 | { 218 | background-color: #ddd; 219 | font-weight: bold; 220 | } 221 | 222 | th { border-right: 1px solid #aaa; } 223 | tr > th:last-child { border-right: 1px solid #ddd; } 224 | 225 | .ancestors, .attribs { color: #999; } 226 | .ancestors a, .attribs a 227 | { 228 | color: #999 !important; 229 | text-decoration: none; 230 | } 231 | 232 | .clear 233 | { 234 | clear: both; 235 | } 236 | 237 | .important 238 | { 239 | font-weight: bold; 240 | color: #950B02; 241 | } 242 | 243 | .yes-def { 244 | text-indent: -1000px; 245 | } 246 | 247 | .type-signature { 248 | color: #aaa; 249 | } 250 | 251 | .name, .signature { 252 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 253 | } 254 | 255 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 257 | .details dd { margin-left: 70px; } 258 | .details ul { margin: 0; } 259 | .details ul { list-style-type: none; } 260 | .details li { margin-left: 30px; padding-top: 6px; } 261 | .details pre.prettyprint { margin: 0 } 262 | .details .object-value { padding-top: 0; } 263 | 264 | .description { 265 | margin-bottom: 1em; 266 | margin-top: 1em; 267 | } 268 | 269 | .code-caption 270 | { 271 | font-style: italic; 272 | font-size: 107%; 273 | margin: 0; 274 | } 275 | 276 | .source 277 | { 278 | border: 1px solid #ddd; 279 | width: 80%; 280 | overflow: auto; 281 | } 282 | 283 | .prettyprint.source { 284 | width: inherit; 285 | } 286 | 287 | .source code 288 | { 289 | font-size: 100%; 290 | line-height: 18px; 291 | display: block; 292 | padding: 4px 12px; 293 | margin: 0; 294 | background-color: #fff; 295 | color: #4D4E53; 296 | } 297 | 298 | .prettyprint code span.line 299 | { 300 | display: inline-block; 301 | } 302 | 303 | .prettyprint.linenums 304 | { 305 | padding-left: 70px; 306 | -webkit-user-select: none; 307 | -moz-user-select: none; 308 | -ms-user-select: none; 309 | user-select: none; 310 | } 311 | 312 | .prettyprint.linenums ol 313 | { 314 | padding-left: 0; 315 | } 316 | 317 | .prettyprint.linenums li 318 | { 319 | border-left: 3px #ddd solid; 320 | } 321 | 322 | .prettyprint.linenums li.selected, 323 | .prettyprint.linenums li.selected * 324 | { 325 | background-color: lightyellow; 326 | } 327 | 328 | .prettyprint.linenums li * 329 | { 330 | -webkit-user-select: text; 331 | -moz-user-select: text; 332 | -ms-user-select: text; 333 | user-select: text; 334 | } 335 | 336 | .params .name, .props .name, .name code { 337 | color: #4D4E53; 338 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 339 | font-size: 100%; 340 | } 341 | 342 | .params td.description > p:first-child, 343 | .props td.description > p:first-child 344 | { 345 | margin-top: 0; 346 | padding-top: 0; 347 | } 348 | 349 | .params td.description > p:last-child, 350 | .props td.description > p:last-child 351 | { 352 | margin-bottom: 0; 353 | padding-bottom: 0; 354 | } 355 | 356 | .disabled { 357 | color: #454545; 358 | } 359 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /docs/utils_formElementByDiv.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: utils/formElementByDiv.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: utils/formElementByDiv.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
30 |  * A global map holding weak references from the DOM elements to its represented
31 |  * {@link module:formElement~FormElement} objects.
32 |  *
33 |  * @type {WeakMap.<HTMLDivElement, module:formElement~FormElement>}
34 |  */
35 | const formElementByDiv = new WeakMap();
36 | 
37 | export default formElementByDiv;
38 | 
39 |
40 |
41 | 42 | 43 | 44 | 45 |
46 | 47 | 50 | 51 |
52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/utils_lcm.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: utils/lcm.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: utils/lcm.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
30 |  * Calculates the least common multiple of a list of numbers.
31 |  *
32 |  * @param {Array.<number>} numbers The array of numbers.
33 |  *
34 |  * @returns {number} The result of the least common multiple calculation.
35 |  */
36 | function lcm(...numbers) {
37 |   const gcd = (numbers) => {
38 |     if (!numbers.length) return 0;
39 |     else if (numbers.length === 1) return Math.abs(numbers[0]);
40 |     else
41 |       return numbers
42 |         .slice(1)
43 |         .reduce(
44 |           (a, b) =>
45 |             ((f, a, b) => f(f, a, b))(
46 |               (f, a, b) => (!b ? a : f(f, b, a % b)),
47 |               a,
48 |               b
49 |             ),
50 |           Math.abs(numbers[0])
51 |         );
52 |   };
53 | 
54 |   if (!numbers.length) return 0;
55 |   else if (numbers.length === 1) return Math.abs(numbers[0]);
56 |   else return Math.abs(numbers.reduce((acc, n) => acc * n, 1)) / gcd(numbers);
57 | }
58 | 
59 | export default lcm;
60 | 
61 |
62 |
63 | 64 | 65 | 66 | 67 |
68 | 69 | 72 | 73 |
74 | 75 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/utils_pointerToId.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: utils/pointerToId.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: utils/pointerToId.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
30 |  * Builds a string with a format suitable for its use as an HTML `id` tag
31 |  * attribute.
32 |  *
33 |  * @param {string} pointer A JSON Pointer-like string that provides unique
34 |  * identification of the JSON Schema being represented by the form element.
35 |  *
36 |  * @returns {string} The formatted string suitable for `id` tag attributes.
37 |  */
38 | function pointerToId(pointer) {
39 |   return `json-schema__${pointer.replace(/\//gi, '_')}`;
40 | }
41 | 
42 | export default pointerToId;
43 | 
44 |
45 |
46 | 47 | 48 | 49 | 50 |
51 | 52 | 55 | 56 |
57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-schema-forms", 3 | "version": "0.2.0-alpha.2", 4 | "description": "A pure JavaScript tool that generates HTML forms from JSON Schemas.", 5 | "license": "GPL-3.0-or-later", 6 | "keywords": [ 7 | "json", 8 | "schema", 9 | "form", 10 | "html-form", 11 | "jsonschema", 12 | "json-schema", 13 | "json-schema-form", 14 | "bootstrap" 15 | ], 16 | "author": { 17 | "name": "Hernán Blanco", 18 | "email": "hblanco@pm.me", 19 | "url": "https://github.com/hblanko" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/hblanko/json-schema-forms.git" 24 | }, 25 | "main": "src/index.js", 26 | "files": [ 27 | "dist/json-schema-forms.min.js", 28 | "css/json-schema-forms.css", 29 | "src/**/*" 30 | ], 31 | "scripts": { 32 | "build": "parcel build ./src/index.js --out-dir dist --no-source-maps -o json-schema-forms.min.js", 33 | "dev": "parcel ./tests/example-dev.html --out-dir serve", 34 | "doc": "jsdoc -c ./.jsdoc.json", 35 | "lint": "eslint ./src --ext .js", 36 | "prettify": "prettier-eslint --eslint-config-path ./.eslintrc.js --write \"$PWD/src/**/*.js\" \"$PWD/package.json\"", 37 | "prettify:tests": "prettier-eslint --eslint-config-path ./.eslintrc.js --write \"$PWD/tests/**/*{.js,.html}\"", 38 | "setup-bundler": "yarn add parcel-bundler --dev" 39 | }, 40 | "husky": { 41 | "hooks": { 42 | "pre-commit": "lint-staged && yarn doc && git add docs" 43 | } 44 | }, 45 | "lint-staged": { 46 | "src/**/*.js": "prettier-eslint --eslint-config-path ./.eslintrc.js --write", 47 | "package.json": "prettier-eslint --eslint-config-path ./.eslintrc.js --write" 48 | }, 49 | "devDependencies": { 50 | "babel": "^6.23.0", 51 | "babel-eslint": "^10.1.0", 52 | "eslint": "^7.1.0", 53 | "eslint-plugin-jsdoc": "^25.4.2", 54 | "husky": "^4.2.5", 55 | "lint-staged": "^10.2.6", 56 | "parcel-bundler": "^1.12.4", 57 | "prettier": "^2.0.5", 58 | "prettier-eslint": "^10.1.1", 59 | "prettier-eslint-cli": "^5.0.0" 60 | }, 61 | "dependencies": { 62 | "@apidevtools/json-schema-ref-parser": "^9.0.1", 63 | "es": "^0.7.3", 64 | "jquery": "^3.5.1" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/JsonSchemaForms.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The main module implementing the form construction. 3 | * 4 | * @module JsonSchemaForms 5 | */ 6 | 'use strict'; 7 | 8 | import FormElement from './form/formElement.js'; 9 | import defaultFormOptions from './form/defaultFormOptions.js'; 10 | 11 | import $RefParser from '@apidevtools/json-schema-ref-parser'; 12 | import jquery from 'jquery'; 13 | 14 | /** 15 | * Builds an HTML form from a given JSON Schema. The main function to be 16 | * interacted by users. 17 | * 18 | * It allows to provide specific options for the form construction, and a custom 19 | * callback function triggered on submission. 20 | * 21 | * @param {object} schema The JSON Schema to represent as an HTML form. 22 | * @param {Function} [submitCallback=() => {}] Callback function to be called 23 | * when the form triggers the `submit` DOM event. 24 | * @param {object} customFormOptions Form options overriding the default. See 25 | * {@link defaultFormOptions} for details. 26 | * 27 | * @returns {HTMLDivElement} A `
` element containing the HTML form. 28 | */ 29 | function build(schema, submitCallback = () => {}, customFormOptions = {}) { 30 | // Builds form options by merging the provided custom options with the 31 | // defaults. 32 | const formOptions = { 33 | ...defaultFormOptions, 34 | ...customFormOptions, 35 | }; 36 | 37 | // Ensures jQuery is available if Bootstrap is required but failed loading. 38 | if (formOptions.bootstrap && !window.$) { 39 | console.warn('Bootstrap expected but JQuery was not loaded.'); 40 | window.$ = jquery; 41 | } 42 | 43 | const containerDiv = document.createElement('div'); 44 | 45 | $RefParser.dereference(schema, (err, s) => { 46 | if (err) console.error(err); 47 | else { 48 | // Generates the form recursively. 49 | const rootFormElement = new FormElement(s, { 50 | formOptions, 51 | }); 52 | 53 | // Creates the HTML structure containing the form. 54 | const formDiv = document.createElement('div'); 55 | const form = formDiv.appendChild(document.createElement('form')); 56 | form.id = formOptions.formId; 57 | 58 | form.addEventListener('submit', (event) => { 59 | const valid = submitCallback(rootFormElement); 60 | 61 | if (valid === false) event.preventDefault(); 62 | }); 63 | 64 | const submitButton = form.appendChild(document.createElement('button')); 65 | submitButton.type = 'submit'; 66 | submitButton.innerText = formOptions.submitButtonText; 67 | 68 | containerDiv.appendChild(rootFormElement.layout.root); 69 | containerDiv.appendChild(formDiv); 70 | 71 | if (formOptions.bootstrap) { 72 | containerDiv.classList.add('container-fluid', 'bg-light'); 73 | formDiv.classList.add('pt-4'); 74 | submitButton.classList.add('btn', 'btn-primary'); 75 | } 76 | } 77 | }); 78 | 79 | return containerDiv; 80 | } 81 | 82 | export default { build }; 83 | -------------------------------------------------------------------------------- /src/form/defaultFormOptions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The default options used to build the form. 3 | * 4 | * @enum 5 | */ 6 | const defaultFormOptions = { 7 | formId: 'json-schema-form', 8 | bootstrap: '4.5', 9 | fontAwesome: '5.13.0', 10 | maxEnumTabs: 5, 11 | maxSelectSize: 6, 12 | booleanTranslateFunction: (b) => (b ? 'Yes' : 'No'), 13 | arraySubstitute: 'List', 14 | objectSubstitute: 'Group', 15 | submitButtonText: 'Submit', 16 | initTogglersOff: false, 17 | arrayItemTitle: 'Item', 18 | adHocOptions: { 19 | todo: 'To-do', 20 | }, 21 | }; 22 | 23 | export default defaultFormOptions; 24 | -------------------------------------------------------------------------------- /src/form/formElementDefinitions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module containing classes and objects that define the form element type and 3 | * behavior. 4 | * 5 | * @module formElementDefinitions 6 | */ 7 | 8 | /** 9 | * The available types of a form element. 10 | * 11 | * @enum {string} 12 | */ 13 | const ElementType = { 14 | /** The form element representing the root JSON Schema. */ 15 | ROOT: 'root', 16 | 17 | /** A required form element. */ 18 | REQUIRED: 'required', 19 | 20 | /** An optional form element. */ 21 | OPTIONAL: 'optional', 22 | 23 | /** A form element able to be removed. */ 24 | REMOVABLE: 'removable', 25 | }; 26 | 27 | /** 28 | * The possible types of a form element title. 29 | * 30 | * @enum {string} 31 | */ 32 | const TitleType = { 33 | /** A regular, unmodifiable form element title. */ 34 | STATIC: 'static', 35 | 36 | /** An editable form element title. */ 37 | FIELD: 'field', 38 | 39 | /** A static element title for an added JSON Schema's `array` item. */ 40 | ADDED_ITEM: 'addedItem', 41 | }; 42 | 43 | /** The form element state descriptor. */ 44 | class State { 45 | /** 46 | * Class constructor. 47 | * 48 | * @param {boolean} [active=true] Flag indicating whether the form element is 49 | * active (i.e. the form element can be interacted --at least its toggler). 50 | * @param {boolean?} [disabled=null] Flag indicating whether the form element 51 | * is disabled (i.e. the input fields or child elements cannot be interacted). 52 | */ 53 | constructor(active = true, disabled = null) { 54 | /** 55 | * Indicates whether the form element is active. 56 | * 57 | * @type {boolean} 58 | */ 59 | this.active = active; 60 | 61 | /** 62 | * Indicates whether the form element is disabled. 63 | * 64 | * @type {boolean?} 65 | */ 66 | this.disabled = disabled; 67 | } 68 | } 69 | 70 | export { ElementType, State, TitleType }; 71 | -------------------------------------------------------------------------------- /src/form/json-schema/JsonSchemaKeywords.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Keywords and types specified by the [JSON Schema 2019-09 RFC Draft](https://json-schema.org/draft/2019-09/json-schema-core.html). 3 | * 4 | * @module JsonSchemaKeywords 5 | */ 6 | 7 | /** 8 | * Object containing the JSON Schema keywords classified by its role in the 9 | * schema definition. 10 | * 11 | * @enum {object.} 12 | */ 13 | const JsonSchemaKeywords = { 14 | /** 15 | * Keywords representing [JSON Schema annotations](https://json-schema.org/draft/2019-09/json-schema-core.html#annotations). 16 | * 17 | * @enum {string} 18 | */ 19 | Annotation: { 20 | DEFAULT: 'default', 21 | DEPRECATED: 'deprecated', 22 | DESCRIPTION: 'description', 23 | EXAMPLES: 'examples', 24 | READ_ONLY: 'readOnly', 25 | TITLE: 'title', 26 | WRITE_ONLY: 'writeOnly', 27 | }, 28 | 29 | /** 30 | * Keywords representing [JSON Schema applicators for `array` instances](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.3.1). 31 | * 32 | * @enum {string} 33 | */ 34 | ArrayApplicator: { 35 | ADDITIONAL_ITEMS: 'additionalItems', 36 | CONTAINS: 'contains', 37 | ITEMS: 'items', 38 | UNEVALUATED_ITEMS: 'unevaluatedItems', 39 | }, 40 | 41 | /** 42 | * Keywords representing [JSON Schema validation conditions for `array` 43 | * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4). 44 | * 45 | * @enum {string} 46 | */ 47 | ArrayValidation: { 48 | MAX_CONTAINS: 'maxContains', 49 | MAX_ITEMS: 'maxItems', 50 | MIN_CONTAINS: 'minContains', 51 | MIN_ITEMS: 'minItems', 52 | UNIQUE_ITEMS: 'uniqueItems', 53 | }, 54 | 55 | /** 56 | * Keywords representing [JSON Schema in-place applicators with boolean logic](https://json-schema.org/draft/2019-09/json-schema-core.html#logic). 57 | * 58 | * @enum {string} 59 | */ 60 | BooleanLogicApplicator: { 61 | ALL_OF: 'allOf', 62 | ANY_OF: 'anyOf', 63 | NOT: 'not', 64 | ONE_OF: 'oneOf', 65 | }, 66 | 67 | /** 68 | * Keywords representing [JSON Schema in-place applicators conditionally](https://json-schema.org/draft/2019-09/json-schema-core.html#conditional). 69 | * 70 | * @enum {string} 71 | */ 72 | ConditionalApplicator: { 73 | IF: 'if', 74 | THEN: 'then', 75 | ELSE: 'else', 76 | }, 77 | 78 | /** 79 | * Keywords representing [generic JSON Schema validation conditions](https://json-schema.org/draft/2019-09/json-schema-validation.html#general). 80 | * 81 | * @enum {string} 82 | */ 83 | GenericValidation: { 84 | CONST: 'const', 85 | ENUM: 'enum', 86 | TYPE: 'type', 87 | }, 88 | 89 | /** 90 | * Keywords representing [JSON Schema validation conditions for numeric 91 | * (`number` and `integer`) instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#numeric). 92 | * 93 | * @enum {string} 94 | */ 95 | NumberValidation: { 96 | EXCLUSIVE_MAXIMUM: 'exclusiveMaximum', 97 | EXCLUSIVE_MINIMUM: 'exclusiveMinimum', 98 | MAXIMUM: 'maximum', 99 | MINIMUM: 'minimum', 100 | MULTIPLE_OF: 'multipleOf', 101 | }, 102 | 103 | /** 104 | * Keywords representing [JSON Schema applicators for `object` instances](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.3.2). 105 | * 106 | * @enum {string} 107 | */ 108 | ObjectApplicator: { 109 | ADDITIONAL_PROPERTIES: 'additionalProperties', 110 | PATTERN_PROPERTIES: 'patternProperties', 111 | PROPERTIES: 'properties', 112 | UNEVALUATED_PROPERTIES: 'unevaluatedProperties', 113 | }, 114 | 115 | /** 116 | * Keywords representing [JSON Schema validation conditions for `object` 117 | * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5). 118 | * 119 | * @enum {string} 120 | */ 121 | ObjectValidation: { 122 | DEPENDENT_REQUIRED: 'dependentRequired', 123 | MAX_PROPERTIES: 'maxProperties', 124 | MIN_PROPERTIES: 'minProperties', 125 | PROPERTY_NAMES: 'propertyNames', 126 | REQUIRED: 'required', 127 | }, 128 | 129 | /** 130 | * Keywords representing [JSON Schema validation conditions for `string` 131 | * instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#string). 132 | * 133 | * @enum {string} 134 | */ 135 | StringValidation: { 136 | MAX_LENGTH: 'maxLength', 137 | MIN_LENGTH: 'minLength', 138 | PATTERN: 'pattern', 139 | }, 140 | }; 141 | 142 | export default JsonSchemaKeywords; 143 | -------------------------------------------------------------------------------- /src/form/json-schema/JsonSchemaType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module specifying the values that the `type` generic validation keyword can 3 | * take. 4 | * 5 | * @module JsonSchemaType 6 | * 7 | * @see {@link https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.1.1} 8 | */ 9 | 10 | /** 11 | * List of JSON types defined by the JSON Schema specification. 12 | * 13 | * @enum {string} 14 | */ 15 | const JsonSchemaType = { 16 | ARRAY: 'array', 17 | BOOLEAN: 'boolean', 18 | INTEGER: 'integer', 19 | NULL: 'null', 20 | NUMBER: 'number', 21 | OBJECT: 'object', 22 | STRING: 'string', 23 | }; 24 | 25 | export default JsonSchemaType; 26 | -------------------------------------------------------------------------------- /src/form/json-schema/inPlaceApplicators.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module that analyzes and resolves [JSON Schema in-place applicators](https://json-schema.org/draft/2019-09/json-schema-core.html#in-place). 3 | * 4 | * In this approach, the in-place applicators present in a JSON Schema are 5 | * modeled as a directed tree (where nodes represented by {@link 6 | * module:inPlaceApplicators~IPASchema} objects). Each node stores the keywords 7 | * belonging to its corresponding subschema: hence, any possible materialization 8 | * of a JSON Schema can be reconstructed by aggregating the keywords of each 9 | * node traversed by any directed path from the root node to the leaf. 10 | * 11 | * The user is intended to select the desired path: {@link module:selectors} 12 | * provides a user interface for this purpose. 13 | * 14 | * @module inPlaceApplicators 15 | */ 16 | import JsonSchemaKeywords from './JsonSchemaKeywords.js'; 17 | 18 | /** 19 | * Processes a JSON Schema, generating an in-place application tree that 20 | * represents its possible materializations. 21 | * 22 | * @param {object} schema The JSON Schema to process. 23 | * @param {string} [pointer=''] A JSON Pointer that provides unique 24 | * identification to each in-place applicator in the JSON Schema. 25 | * @param {number} [selected=0] The index indicating the applicator subschema to 26 | * be selected at initialization. 27 | * 28 | * @returns {module:inPlaceApplicators~IPASchema} The root node to the in-place 29 | * application tree that represents the given JSON Schema. 30 | */ 31 | function process(schema, pointer = '', selected = 0) { 32 | const { common, applicatorByPointer } = schema.allOf 33 | ? processAllOf( 34 | schema, 35 | `${pointer}/${JsonSchemaKeywords.BooleanLogicApplicator.ALL_OF}` 36 | ) 37 | : { 38 | common: { 39 | ...schema, 40 | }, 41 | applicatorByPointer: new Map(), 42 | }; 43 | 44 | if (schema.anyOf) { 45 | delete common.anyOf; 46 | const aop = `${pointer}/${JsonSchemaKeywords.BooleanLogicApplicator.ANY_OF}`; 47 | 48 | applicatorByPointer.set( 49 | aop, 50 | new InPlaceApplicator(processAnyOf(schema.anyOf, aop), selected) 51 | ); 52 | } 53 | 54 | if (schema.oneOf) { 55 | delete common.oneOf; 56 | const oop = `${pointer}/${JsonSchemaKeywords.BooleanLogicApplicator.ONE_OF}`; 57 | 58 | applicatorByPointer.set( 59 | oop, 60 | new InPlaceApplicator(processOneOf(schema.oneOf, oop), selected) 61 | ); 62 | } 63 | 64 | return new IPASchema(common, applicatorByPointer); 65 | } 66 | 67 | /** 68 | * @typedef {object} ProcessAllOfResult 69 | * 70 | * @property {object} common The keywords that are common to all the `allOf` 71 | * subschemas. 72 | * @property {Map.} applicatorByPointer 73 | * A map including the child in-place applicators contained by the processed 74 | * `allOf` applicator. 75 | */ 76 | 77 | /** 78 | * Processes an `allOf` in-place applicator. 79 | * 80 | * @param {object} schema The JSON Schema including an `allOf` property to 81 | * process. 82 | * @param {string} [pointer=''] A JSON Pointer that identifies the JSON Schema. 83 | * 84 | * @returns {module:inPlaceApplicators~ProcessAllOfResult} The result of 85 | * processing the `allOf` in-place applicator. 86 | */ 87 | function processAllOf(schema, pointer) { 88 | const ipaSchemas = schema.allOf.map((s, i) => process(s, `${pointer}/${i}`)); 89 | 90 | return { 91 | common: aggregate(schema, ...ipaSchemas), 92 | applicatorByPointer: new Map( 93 | ipaSchemas.flatMap((ipaSchema) => [...ipaSchema.applicatorByPointer]) 94 | ), 95 | }; 96 | } 97 | 98 | /** 99 | * Processes an `anyOf` in-place applicator. 100 | * 101 | * @param {Array.} subschemas The subschemas included in the `anyOf` 102 | * in-place applicator. 103 | * @param {string} [pointer=''] A JSON Pointer that identifies the JSON Schema. 104 | * 105 | * @returns {Array.} An array of nodes 106 | * representing each subschema contained by the `anyOf` applicator. 107 | */ 108 | function processAnyOf(subschemas, pointer) { 109 | return processDisjunctiveInPlaceApplicator(subschemas, pointer); 110 | } 111 | 112 | /** 113 | * Processes an `oneOf` in-place applicator. 114 | * 115 | * @param {Array.} subschemas The subschemas included in the `oneOf` 116 | * in-place applicator. 117 | * @param {string} [pointer=''] A JSON Pointer that identifies the JSON Schema. 118 | * 119 | * @returns {Array.} An array of nodes 120 | * representing each subschema contained by the `oneOf` applicator. 121 | */ 122 | function processOneOf(subschemas, pointer) { 123 | return processDisjunctiveInPlaceApplicator(subschemas, pointer); 124 | } 125 | 126 | /** 127 | * Processes a disjunctive in-place applicator. 128 | * 129 | * @param {Array.} subschemas The subschemas included in the disjunctive 130 | * in-place applicator. 131 | * @param {string} [pointer=''] A JSON Pointer that identifies the JSON Schema. 132 | * 133 | * @returns {Array.} An array of nodes 134 | * representing each subschema contained by the applicator. 135 | */ 136 | function processDisjunctiveInPlaceApplicator(subschemas, pointer) { 137 | return subschemas.map((s, i) => process(s, `${pointer}/${i}`)); 138 | } 139 | 140 | /** Class representing a JSON Schema in-place applicator. */ 141 | class InPlaceApplicator { 142 | /** 143 | * Class constructor. 144 | * 145 | * @param {Array.} subschemas The array 146 | * of nodes representing the subschemas contained by the applicator. 147 | * @param {number} selected The index indicating the subschema to be selected 148 | * at initialization. 149 | */ 150 | constructor(subschemas, selected) { 151 | /** 152 | * The array of nodes representing the subschemas contained by the 153 | * applicator. 154 | * 155 | * @type {Array.} 156 | */ 157 | this.subschemas = subschemas; 158 | 159 | /** 160 | * The index indicating the selected subschema. 161 | * 162 | * @type {number} 163 | */ 164 | this.selected = selected; 165 | } 166 | 167 | /** 168 | * Retrieves the node representing the in-place applicator subschema that is 169 | * currently selected. 170 | * 171 | * @returns {module:inPlaceApplicators~IPASchema} The selected node 172 | * representing an in-place applicator subschema. 173 | */ 174 | getSelectedIpaSchema() { 175 | return this.subschemas[this.selected]; 176 | } 177 | } 178 | 179 | /** 180 | * The node for a tree representation of the possible JSON Schema 181 | * materializations regarding its in-place applicators (standing for "In-Place 182 | * Application Schema"). 183 | */ 184 | class IPASchema { 185 | /** 186 | * Class constructor. 187 | * 188 | * @param {object} common The keywords that are common to all possible 189 | * materializations of the in-place application subtree. 190 | * @param {Map.} applicatorByPointer 191 | * A map including the child in-place applicators to be contained by the 192 | * node. 193 | */ 194 | constructor(common, applicatorByPointer) { 195 | /** 196 | * The keywords that are common to all possible materializations of the 197 | * in-place application subtree. 198 | * 199 | * @type {object} 200 | */ 201 | this.common = common; 202 | 203 | /** 204 | * A map including the child in-place applicators contained by the node. 205 | * 206 | * @type {Map.} 207 | */ 208 | this.applicatorByPointer = applicatorByPointer; 209 | } 210 | 211 | /** 212 | * Returns the nodes representing the selected in-place applicator subschemas. 213 | * 214 | * @returns {Array.?} The array of 215 | * selected in-place applicator subnodes, or `null` if the node has no child 216 | * in-place applicators. 217 | */ 218 | getSelectedApplicators() { 219 | if (this.applicatorByPointer.size) 220 | return Array.from(this.applicatorByPointer).map(([, a]) => 221 | a.getSelectedIpaSchema() 222 | ); 223 | else return null; 224 | } 225 | 226 | /** 227 | * Retrieves the materialization of the JSON Schema that is currently 228 | * selected. 229 | * 230 | * @returns {object} The selected materialization of the JSON Schema 231 | * represented by the node. 232 | */ 233 | getSelectedSchema() { 234 | const recursion = (ipaSchema) => { 235 | if (ipaSchema.applicatorByPointer.size == 0) return ipaSchema; 236 | else 237 | return new IPASchema( 238 | aggregate( 239 | ipaSchema.common, 240 | ...Array.from(ipaSchema.applicatorByPointer).map(([, a]) => 241 | recursion(a.getSelectedIpaSchema()) 242 | ) 243 | ) 244 | ); 245 | }; 246 | 247 | return recursion(this).common; 248 | } 249 | 250 | /** 251 | * Retrieves the [annotation-related keywords](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9) 252 | * from the in-place application node. 253 | * 254 | * @returns {object} The JSON Schema subset representing the annotations at 255 | * the top level. 256 | */ 257 | getAnnotations() { 258 | const annotations = {}; 259 | 260 | if (this.common.title) annotations.title = this.common.title; 261 | 262 | if (this.common.description) 263 | annotations.description = this.common.description; 264 | 265 | return annotations; 266 | } 267 | } 268 | 269 | /** 270 | * Aggregates the keywords of a JSON Schema with the common keywords from a list 271 | * of in-place application nodes. 272 | * 273 | * Collisions are resolved applying the logic implemented by the 274 | * {@link module:inPlaceApplicators~Aggregation} class. 275 | * 276 | * @param {object} schema The JSON Schema to aggregate. 277 | * @param {...module:inPlaceApplicators~IPASchema} ipaSchemas The in-place 278 | * application nodes whose common keywords are to be aggregated. 279 | * 280 | * @returns {object} The aggregated JSON Schema. 281 | */ 282 | function aggregate(schema, ...ipaSchemas) { 283 | const common = { 284 | ...schema, 285 | }; 286 | 287 | delete common.allOf; 288 | 289 | for (const ipaSchema of ipaSchemas) { 290 | const filteredKeywords = Object.entries(ipaSchema.common).filter( 291 | ([keyword]) => 292 | !Object.values(JsonSchemaKeywords.Annotation).includes(keyword) 293 | ); 294 | 295 | for (const [keyword, value] of filteredKeywords) { 296 | if (Object.prototype.hasOwnProperty.call(common, keyword)) 297 | if (common[keyword] instanceof Aggregation) common[keyword].add(value); 298 | else common[keyword] = new Aggregation(keyword, common[keyword], value); 299 | else common[keyword] = value; 300 | } 301 | } 302 | 303 | for (const [keyword, value] of Object.entries(common)) 304 | if (value instanceof Aggregation) common[keyword] = value.resolve(); 305 | 306 | return common; 307 | } 308 | 309 | /** Class that handles keyword collision during aggregation process. */ 310 | class Aggregation { 311 | /** 312 | * Class constructor. 313 | * 314 | * @param {string} keyword The aggregated JSON Schema keyword. 315 | * @param {...any} init The initial values to aggregate. 316 | */ 317 | constructor(keyword, ...init) { 318 | this.keyword = keyword; 319 | this.values = init.map((i) => (i instanceof Aggregation ? i.values : i)); 320 | } 321 | 322 | /** 323 | * Adds a value to the aggregation, or joins the content of another 324 | * `Aggregation` object. 325 | * 326 | * @param {any} e The value/aggregation to be added/joined. 327 | */ 328 | add(e) { 329 | if (e instanceof Aggregation) this.values.concat(e.values); 330 | else this.values.push(e); 331 | } 332 | 333 | /** 334 | * Generates an aggregated value following the specific rules associated to 335 | * the keyword. 336 | * 337 | * @returns {any} The value resulted of applying the aggregation rules to the 338 | * different contained values. 339 | * 340 | * @todo Implement specific logic for every keyword. 341 | */ 342 | resolve() { 343 | const resolveSwitch = { 344 | [JsonSchemaKeywords.ObjectApplicator.PROPERTIES]: () => 345 | Object.assign({}, ...this.values), 346 | [JsonSchemaKeywords.ObjectValidation.REQUIRED]: () => this.values.flat(), 347 | default: () => 348 | console.warn(`Keyword aggregation not defined for the\ 349 | "${this.keyword}" keyword.`), 350 | }; 351 | 352 | return (resolveSwitch[this.keyword] || resolveSwitch.default)(); 353 | } 354 | } 355 | 356 | export default process; 357 | export { InPlaceApplicator, IPASchema }; 358 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import JsonSchemaForms from './JsonSchemaForms.js'; 2 | 3 | window.JsonSchemaForms = JsonSchemaForms; 4 | -------------------------------------------------------------------------------- /src/test-schema.js: -------------------------------------------------------------------------------- 1 | const schema = { 2 | $schema: 'http://json-schema.org/draft-07/schema#', 3 | $id: 'http://landarltracker.com/schemas/great/invention.json', 4 | title: 'Testing', 5 | type: 'object', 6 | required: ['qqt'], 7 | minProperties: 5, 8 | maxProperties: 6, 9 | properties: { 10 | qqt: { 11 | const: 3, 12 | /*{ 13 | myNiceConst: 'u u u' 14 | }*/ 15 | }, 16 | ost: { 17 | title: 'un titulito', 18 | description: 'es una basura de titulito', 19 | enum: [345345, [4, 2]], 20 | }, 21 | sst: { 22 | title: 'An enum', 23 | enum: [ 24 | { 25 | this: '3', 26 | }, 27 | '3', 28 | 3, 29 | true, 30 | null, 31 | [ 32 | [ 33 | { 34 | qq: 'sdf', 35 | aa: -4, 36 | bb: 'b', 37 | }, 38 | 3, 39 | ], 40 | 4, 41 | 5, 42 | ], 43 | 4, 44 | // 'A very very long stringegergiuhbengviuergeriugeuieiuegfeiu', 45 | { 46 | ways: false, 47 | other: true, 48 | }, 49 | ], 50 | }, 51 | fString: { 52 | title: 'F String', 53 | description: 'An object created for recreation.', 54 | type: 'object', 55 | oneOf: [ 56 | { 57 | title: 'A', 58 | oneOf: [ 59 | { 60 | title: 'A.1', 61 | oneOf: [ 62 | { 63 | title: 'Que sea booleano', 64 | properties: { 65 | aString: { 66 | title: 'From A.1.1', 67 | type: 'boolean', 68 | }, 69 | }, 70 | }, 71 | { 72 | title: 'A.1.2', 73 | properties: { 74 | aString: { 75 | title: 'From A.1.2', 76 | type: 'array', 77 | minItems: 1, 78 | maxItems: 3, 79 | items: { 80 | title: 'do you like it?', 81 | anyOf: [ 82 | { 83 | title: 'array', 84 | type: 'string', 85 | }, 86 | { 87 | title: 'obj', 88 | type: 'array', 89 | items: { 90 | type: 'string', 91 | }, 92 | }, 93 | ], 94 | }, 95 | additionalItems: { 96 | title: 'najlepszego', 97 | description: 'beauty personified', 98 | type: 'boolean', 99 | }, 100 | }, 101 | }, 102 | }, 103 | ], 104 | anyOf: [ 105 | { 106 | title: 'A.2.1', 107 | properties: { 108 | bString: { 109 | title: 'From A.2.1', 110 | type: 'number', 111 | minimum: 0, 112 | multipleOf: 4, 113 | }, 114 | }, 115 | }, 116 | ], 117 | }, 118 | ], 119 | }, 120 | { 121 | title: 'B', 122 | anyOf: [ 123 | { 124 | title: 'B.1', 125 | oneOf: [ 126 | { 127 | title: 'B.1.1', 128 | properties: { 129 | aString: { 130 | title: 'From B.1.1', 131 | type: 'string', 132 | }, 133 | }, 134 | }, 135 | { 136 | title: 'B.1.2', 137 | properties: { 138 | aString: { 139 | title: 'From B.1.2', 140 | oneOf: [ 141 | { 142 | type: 'boolean', 143 | }, 144 | { 145 | type: 'integer', 146 | }, 147 | ], 148 | }, 149 | }, 150 | }, 151 | ], 152 | }, 153 | ], 154 | }, 155 | ], 156 | }, 157 | }, 158 | additionalProperties: { 159 | title: "nice, isn't it?", 160 | oneOf: [ 161 | { 162 | title: '🤷‍', 163 | type: 'string', 164 | }, 165 | { 166 | title: '🔘', 167 | type: 'number', 168 | multipleOf: 7, 169 | exclusiveMinimum: 3, 170 | }, 171 | ], 172 | }, 173 | }; 174 | 175 | export default schema; 176 | -------------------------------------------------------------------------------- /src/utils/formElementByDiv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A global map holding weak references from the DOM elements to its represented 3 | * {@link module:formElement~FormElement} objects. 4 | * 5 | * @type {WeakMap.} 6 | */ 7 | const formElementByDiv = new WeakMap(); 8 | 9 | export default formElementByDiv; 10 | -------------------------------------------------------------------------------- /src/utils/lcm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculates the least common multiple of a list of numbers. 3 | * 4 | * @param {Array.} numbers The array of numbers. 5 | * 6 | * @returns {number} The result of the least common multiple calculation. 7 | */ 8 | function lcm(...numbers) { 9 | const gcd = (numbers) => { 10 | if (!numbers.length) return 0; 11 | else if (numbers.length === 1) return Math.abs(numbers[0]); 12 | else 13 | return numbers 14 | .slice(1) 15 | .reduce( 16 | (a, b) => 17 | ((f, a, b) => f(f, a, b))( 18 | (f, a, b) => (!b ? a : f(f, b, a % b)), 19 | a, 20 | b 21 | ), 22 | Math.abs(numbers[0]) 23 | ); 24 | }; 25 | 26 | if (!numbers.length) return 0; 27 | else if (numbers.length === 1) return Math.abs(numbers[0]); 28 | else return Math.abs(numbers.reduce((acc, n) => acc * n, 1)) / gcd(numbers); 29 | } 30 | 31 | export default lcm; 32 | -------------------------------------------------------------------------------- /src/utils/pointerToId.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Builds a string with a format suitable for its use as an HTML `id` tag 3 | * attribute. 4 | * 5 | * @param {string} pointer A JSON Pointer-like string that provides unique 6 | * identification of the JSON Schema being represented by the form element. 7 | * 8 | * @returns {string} The formatted string suitable for `id` tag attributes. 9 | */ 10 | function pointerToId(pointer) { 11 | return `json-schema__${pointer.replace(/\//gi, '_')}`; 12 | } 13 | 14 | export default pointerToId; 15 | --------------------------------------------------------------------------------