@formio/js 5.0.0-rc.43 → 5.0.0-rc.44
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.js +1 -1
- package/dist/formio.embed.min.js.LICENSE.txt +1 -1
- package/dist/formio.form.js +602 -580
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -11
- package/dist/formio.full.js +605 -583
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -11
- package/dist/formio.js +10 -11
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +1 -1
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Element.js +2 -0
- package/lib/cjs/Form.js +3 -1
- package/lib/cjs/Webform.js +93 -15
- package/lib/cjs/WebformBuilder.js +8 -8
- package/lib/cjs/components/_classes/component/Component.js +25 -8
- package/lib/cjs/components/_classes/componentModal/ComponentModal.js +5 -4
- package/lib/cjs/components/_classes/input/Input.js +1 -1
- package/lib/cjs/components/_classes/multivalue/Multivalue.js +1 -1
- package/lib/cjs/components/_classes/nested/NestedComponent.js +4 -2
- package/lib/cjs/components/datagrid/DataGrid.js +1 -1
- package/lib/cjs/components/editgrid/EditGrid.js +3 -3
- package/lib/cjs/components/form/Form.js +1 -1
- package/lib/cjs/components/html/HTML.js +2 -2
- package/lib/cjs/components/html/fixtures/comp3.js +40 -0
- package/lib/cjs/components/html/fixtures/index.js +3 -1
- package/lib/cjs/components/radio/Radio.js +29 -10
- package/lib/cjs/components/radio/editForm/Radio.edit.data.js +20 -0
- package/lib/cjs/components/radio/fixtures/comp11.js +85 -0
- package/lib/cjs/components/radio/fixtures/index.js +3 -1
- package/lib/cjs/components/select/Select.js +3 -0
- package/lib/cjs/components/select/editForm/Select.edit.data.js +63 -1
- package/lib/cjs/components/signature/Signature.js +1 -1
- package/lib/cjs/components/textarea/TextArea.js +1 -1
- package/lib/cjs/formio.form.js +5 -1
- package/lib/cjs/providers/storage/s3.js +29 -1
- package/lib/mjs/Element.js +2 -0
- package/lib/mjs/Form.js +3 -1
- package/lib/mjs/Webform.js +98 -16
- package/lib/mjs/WebformBuilder.js +8 -8
- package/lib/mjs/components/_classes/component/Component.js +25 -8
- package/lib/mjs/components/_classes/componentModal/ComponentModal.js +5 -4
- package/lib/mjs/components/_classes/input/Input.js +1 -1
- package/lib/mjs/components/_classes/multivalue/Multivalue.js +1 -1
- package/lib/mjs/components/_classes/nested/NestedComponent.js +4 -2
- package/lib/mjs/components/datagrid/DataGrid.js +1 -1
- package/lib/mjs/components/editgrid/EditGrid.js +3 -3
- package/lib/mjs/components/form/Form.js +1 -1
- package/lib/mjs/components/html/HTML.js +2 -2
- package/lib/mjs/components/html/fixtures/comp3.js +38 -0
- package/lib/mjs/components/html/fixtures/index.js +2 -1
- package/lib/mjs/components/radio/Radio.js +29 -10
- package/lib/mjs/components/radio/editForm/Radio.edit.data.js +20 -0
- package/lib/mjs/components/radio/fixtures/comp11.js +83 -0
- package/lib/mjs/components/radio/fixtures/index.js +2 -1
- package/lib/mjs/components/select/Select.js +3 -0
- package/lib/mjs/components/select/editForm/Select.edit.data.js +59 -1
- package/lib/mjs/components/signature/Signature.js +1 -1
- package/lib/mjs/components/textarea/TextArea.js +1 -1
- package/lib/mjs/formio.form.js +3 -1
- package/lib/mjs/providers/storage/s3.js +6 -1
- package/package.json +7 -8
- package/types/builders.d.ts +0 -7
- package/types/components/_classes/component/component.d.ts +0 -175
- package/types/components/_classes/componentmodal/componentmodal.d.ts +0 -31
- package/types/components/_classes/field/field.d.ts +0 -5
- package/types/components/_classes/input/input.d.ts +0 -30
- package/types/components/_classes/multivalue/multivalue.d.ts +0 -16
- package/types/components/_classes/nested/nestedComponent.d.ts +0 -61
- package/types/components/_classes/widgetcomponent/widgetComponent.d.ts +0 -6
- package/types/components/components.d.ts +0 -69
- package/types/components/schema.d.ts +0 -174
- package/types/displays.d.ts +0 -7
- package/types/element.d.ts +0 -45
- package/types/eventEmitter.d.ts +0 -3
- package/types/form.d.ts +0 -18
- package/types/formbuilder.d.ts +0 -6
- package/types/formio.d.ts +0 -1236
- package/types/index.d.ts +0 -18
- package/types/licenses.d.ts +0 -7
- package/types/providers.d.ts +0 -8
- package/types/rulesEngine/conjunctions.d.ts +0 -7
- package/types/rulesEngine/operators.d.ts +0 -7
- package/types/rulesEngine/quckRules.d.ts +0 -7
- package/types/rulesEngine/rules.d.ts +0 -7
- package/types/rulesEngine/transformers.d.ts +0 -7
- package/types/rulesEngine/valueSources.d.ts +0 -7
- package/types/templates.d.ts +0 -8
- package/types/utils.d.ts +0 -157
- package/types/widgets.d.ts +0 -4
@@ -0,0 +1,85 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = {
|
4
|
+
title: 'Test',
|
5
|
+
name: 'test',
|
6
|
+
path: 'test',
|
7
|
+
type: 'form',
|
8
|
+
display: 'form',
|
9
|
+
components: [
|
10
|
+
{
|
11
|
+
label: 'Radio',
|
12
|
+
optionsLabelPosition: 'right',
|
13
|
+
inline: false,
|
14
|
+
tableView: false,
|
15
|
+
values: [
|
16
|
+
{
|
17
|
+
label: '0',
|
18
|
+
value: '0',
|
19
|
+
shortcut: ''
|
20
|
+
},
|
21
|
+
{
|
22
|
+
label: '1',
|
23
|
+
value: '1',
|
24
|
+
shortcut: ''
|
25
|
+
}
|
26
|
+
],
|
27
|
+
key: 'radioNumber',
|
28
|
+
type: 'radio',
|
29
|
+
dataType: 'number',
|
30
|
+
input: true
|
31
|
+
},
|
32
|
+
{
|
33
|
+
label: 'Radio',
|
34
|
+
optionsLabelPosition: 'right',
|
35
|
+
inline: false,
|
36
|
+
tableView: false,
|
37
|
+
values: [
|
38
|
+
{
|
39
|
+
label: '0',
|
40
|
+
value: '0',
|
41
|
+
shortcut: ''
|
42
|
+
},
|
43
|
+
{
|
44
|
+
label: '1',
|
45
|
+
value: '1',
|
46
|
+
shortcut: ''
|
47
|
+
}
|
48
|
+
],
|
49
|
+
key: 'radioString',
|
50
|
+
dataType: 'string',
|
51
|
+
type: 'radio',
|
52
|
+
input: true
|
53
|
+
},
|
54
|
+
{
|
55
|
+
label: 'Radio',
|
56
|
+
optionsLabelPosition: 'right',
|
57
|
+
inline: false,
|
58
|
+
tableView: false,
|
59
|
+
values: [
|
60
|
+
{
|
61
|
+
label: 'true',
|
62
|
+
value: 'true',
|
63
|
+
shortcut: ''
|
64
|
+
},
|
65
|
+
{
|
66
|
+
label: 'false',
|
67
|
+
value: 'false',
|
68
|
+
shortcut: ''
|
69
|
+
}
|
70
|
+
],
|
71
|
+
key: 'radioBoolean',
|
72
|
+
dataType: 'boolean',
|
73
|
+
type: 'radio',
|
74
|
+
input: true
|
75
|
+
},
|
76
|
+
{
|
77
|
+
type: 'button',
|
78
|
+
label: 'Submit',
|
79
|
+
key: 'submit',
|
80
|
+
disableOnInvalid: true,
|
81
|
+
input: true,
|
82
|
+
tableView: false
|
83
|
+
}
|
84
|
+
]
|
85
|
+
};
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp3 = exports.comp2 = exports.comp1 = void 0;
|
6
|
+
exports.comp11 = exports.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp3 = exports.comp2 = exports.comp1 = void 0;
|
7
7
|
const comp1_1 = __importDefault(require("./comp1"));
|
8
8
|
exports.comp1 = comp1_1.default;
|
9
9
|
const comp2_1 = __importDefault(require("./comp2"));
|
@@ -24,3 +24,5 @@ const comp9_1 = __importDefault(require("./comp9"));
|
|
24
24
|
exports.comp9 = comp9_1.default;
|
25
25
|
const comp10_1 = __importDefault(require("./comp10"));
|
26
26
|
exports.comp10 = comp10_1.default;
|
27
|
+
const comp11_1 = __importDefault(require("./comp11"));
|
28
|
+
exports.comp11 = comp11_1.default;
|
@@ -217,6 +217,9 @@ class SelectComponent extends ListComponent_1.default {
|
|
217
217
|
}
|
218
218
|
return super.shouldLoad;
|
219
219
|
}
|
220
|
+
get selectData() {
|
221
|
+
return this.component.selectData || super.selectData;
|
222
|
+
}
|
220
223
|
isEntireObjectDisplay() {
|
221
224
|
return this.component.dataSrc === 'resource' && this.valueProperty === 'data';
|
222
225
|
}
|
@@ -1,6 +1,36 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const lodash_1 = __importDefault(require("lodash"));
|
3
7
|
const utils_1 = require("../../../utils/utils");
|
8
|
+
const calculateSelectData = (context) => {
|
9
|
+
const { instance, data } = context;
|
10
|
+
const rawDefaultValue = instance.downloadedResources.find(resource => lodash_1.default.get(resource, data.valueProperty) === instance.getValue());
|
11
|
+
const options = { data: {}, noeval: true };
|
12
|
+
instance.interpolate(data.template, {
|
13
|
+
item: rawDefaultValue,
|
14
|
+
}, options);
|
15
|
+
return options.data.item;
|
16
|
+
};
|
17
|
+
const setSelectData = (context) => {
|
18
|
+
// Wait before downloadedResources will be set
|
19
|
+
setTimeout(() => {
|
20
|
+
var _a;
|
21
|
+
const { instance, data } = context;
|
22
|
+
const selectDataComponent = instance === null || instance === void 0 ? void 0 : instance.root.getComponent('selectData');
|
23
|
+
// nothing can set if don't have downloaded resources
|
24
|
+
if (!selectDataComponent || !instance.getValue() || !((_a = instance.downloadedResources) === null || _a === void 0 ? void 0 : _a.length)) {
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
// if valueProperty is not provided, we have entire object
|
28
|
+
const shouldCalculateUrlData = data.dataSrc === 'url' && data.data.url && data.valueProperty;
|
29
|
+
const shouldCalculateResourceData = data.dataSrc === 'resource' && data.data.resource && data.valueProperty;
|
30
|
+
const newValue = shouldCalculateUrlData || shouldCalculateResourceData ? calculateSelectData(context) : undefined;
|
31
|
+
selectDataComponent.setValue(newValue);
|
32
|
+
}, 0);
|
33
|
+
};
|
4
34
|
exports.default = [
|
5
35
|
{
|
6
36
|
key: 'dataSrc',
|
@@ -625,5 +655,37 @@ exports.default = [
|
|
625
655
|
key: 'useExactSearch',
|
626
656
|
label: 'Use exact search',
|
627
657
|
tooltip: 'Disables search algorithm threshold.',
|
628
|
-
}
|
658
|
+
},
|
659
|
+
{
|
660
|
+
key: 'defaultValue',
|
661
|
+
onSetItems(component) {
|
662
|
+
setSelectData(component.evalContext());
|
663
|
+
},
|
664
|
+
onChange(context) {
|
665
|
+
if (context && context.flags && context.flags.modified) {
|
666
|
+
setSelectData(context);
|
667
|
+
}
|
668
|
+
},
|
669
|
+
},
|
670
|
+
{
|
671
|
+
key: 'selectData',
|
672
|
+
conditional: {
|
673
|
+
json: { 'and': [
|
674
|
+
{ '!==': [{ var: 'data.valueProperty' }, null] },
|
675
|
+
{ '!==': [{ var: 'data.valueProperty' }, ''] },
|
676
|
+
] },
|
677
|
+
},
|
678
|
+
},
|
679
|
+
{
|
680
|
+
key: 'template',
|
681
|
+
onChange(context) {
|
682
|
+
if (context && context.flags && context.flags.modified) {
|
683
|
+
const defaultValueComponent = context.instance.root.getComponent('defaultValue');
|
684
|
+
if (!defaultValueComponent) {
|
685
|
+
return;
|
686
|
+
}
|
687
|
+
setSelectData(defaultValueComponent.evalContext());
|
688
|
+
}
|
689
|
+
},
|
690
|
+
},
|
629
691
|
];
|
@@ -174,7 +174,7 @@ class SignatureComponent extends Input_1.default {
|
|
174
174
|
getModalPreviewTemplate() {
|
175
175
|
return this.renderTemplate('modalPreview', {
|
176
176
|
previewText: this.dataValue ?
|
177
|
-
`<img src=${this.dataValue}
|
177
|
+
`<img src=${this.dataValue} ${this._referenceAttributeName}='openModal' style="width: 100%;height: 100%;" />` :
|
178
178
|
this.t('Click to Sign')
|
179
179
|
});
|
180
180
|
}
|
@@ -62,7 +62,7 @@ class TextAreaComponent extends TextField_1.default {
|
|
62
62
|
info.content = value;
|
63
63
|
if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) {
|
64
64
|
const elementStyle = this.info.attr.style || '';
|
65
|
-
const children = `<div
|
65
|
+
const children = `<div ${this._referenceAttributeName}="input" class="formio-editor-read-only-content" ${elementStyle ? `style='${elementStyle}'` : ''}></div>`;
|
66
66
|
return this.renderTemplate('well', {
|
67
67
|
children,
|
68
68
|
nestedKey: this.key,
|
package/lib/cjs/formio.form.js
CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.Licenses = exports.Formio = exports.Form = exports.Utils = exports.Templates = exports.Widgets = exports.Providers = exports.Displays = exports.Components = exports.useModule = exports.registerModule = void 0;
|
6
|
+
exports.Webform = exports.EventEmitter = exports.Licenses = exports.Formio = exports.Form = exports.Utils = exports.Templates = exports.Widgets = exports.Providers = exports.Displays = exports.Components = exports.useModule = exports.registerModule = void 0;
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
8
8
|
const Formio_1 = require("./Formio");
|
9
9
|
Object.defineProperty(exports, "Formio", { enumerable: true, get: function () { return Formio_1.Formio; } });
|
@@ -25,6 +25,10 @@ exports.Utils = utils_1.default;
|
|
25
25
|
const Evaluator_1 = __importDefault(require("./utils/Evaluator"));
|
26
26
|
const licenses_1 = __importDefault(require("./licenses"));
|
27
27
|
exports.Licenses = licenses_1.default;
|
28
|
+
const EventEmitter_1 = __importDefault(require("./EventEmitter"));
|
29
|
+
exports.EventEmitter = EventEmitter_1.default;
|
30
|
+
const Webform_1 = __importDefault(require("./Webform"));
|
31
|
+
exports.Webform = Webform_1.default;
|
28
32
|
Formio_1.Formio.loadModules = (path = `${Formio_1.Formio.getApiUrl()}/externalModules.js`, name = 'externalModules') => {
|
29
33
|
Formio_1.Formio.requireLibrary(name, name, path, true)
|
30
34
|
.then((modules) => {
|
@@ -1,4 +1,27 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
@@ -14,7 +37,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
15
38
|
const xhr_1 = __importDefault(require("./xhr"));
|
16
39
|
const util_1 = require("./util");
|
17
|
-
const
|
40
|
+
const loadAbortControllerPolyfill = () => __awaiter(void 0, void 0, void 0, function* () {
|
41
|
+
if (typeof AbortController === 'undefined') {
|
42
|
+
yield Promise.resolve().then(() => __importStar(require('abortcontroller-polyfill/dist/polyfill-patch-fetch')));
|
43
|
+
}
|
44
|
+
});
|
18
45
|
function s3(formio) {
|
19
46
|
return {
|
20
47
|
uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback, multipartOptions) {
|
@@ -25,6 +52,7 @@ function s3(formio) {
|
|
25
52
|
if (response.signed) {
|
26
53
|
if (multipartOptions && Array.isArray(response.signed)) {
|
27
54
|
// patch abort callback
|
55
|
+
yield loadAbortControllerPolyfill();
|
28
56
|
const abortController = new AbortController();
|
29
57
|
const abortSignal = abortController.signal;
|
30
58
|
if (typeof abortCallback === 'function') {
|
package/lib/mjs/Element.js
CHANGED
@@ -69,6 +69,8 @@ export default class Element {
|
|
69
69
|
*
|
70
70
|
* @param {string} event - The event you wish to register the handler for.
|
71
71
|
* @param {function} cb - The callback handler to handle this event.
|
72
|
+
* @param {boolean} [internal] - This is an internal event handler.
|
73
|
+
* @param {boolean} [once] - This event should only fire once.
|
72
74
|
*/
|
73
75
|
on(event, cb, internal, once = false) {
|
74
76
|
if (!this.events) {
|
package/lib/mjs/Form.js
CHANGED
@@ -97,7 +97,9 @@ export default class Form extends Element {
|
|
97
97
|
this.element.appendChild(this.loader);
|
98
98
|
}
|
99
99
|
else if (this.loader) {
|
100
|
-
this.element.
|
100
|
+
if (this.element.contains(this.loader)) {
|
101
|
+
this.element.removeChild(this.loader);
|
102
|
+
}
|
101
103
|
this.loader = null;
|
102
104
|
}
|
103
105
|
}
|
package/lib/mjs/Webform.js
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import moment from 'moment';
|
3
3
|
import { compareVersions } from 'compare-versions';
|
4
|
+
import { Component } from '@formio/core';
|
4
5
|
import EventEmitter from './EventEmitter';
|
5
6
|
import i18nDefaults from './i18n';
|
6
7
|
import { Formio } from './Formio';
|
7
8
|
import Components from './components/Components';
|
8
9
|
import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent';
|
9
|
-
import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, searchComponents, convertStringToHTMLElement, getArrayFromComponentPath,
|
10
|
+
import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, searchComponents, convertStringToHTMLElement, getArrayFromComponentPath, } from './utils/utils';
|
10
11
|
import { eachComponent } from './utils/formUtils';
|
11
12
|
// Initialize the available forms.
|
12
13
|
Formio.forms = {};
|
@@ -34,32 +35,113 @@ function getOptions(options) {
|
|
34
35
|
}
|
35
36
|
return options;
|
36
37
|
}
|
38
|
+
/**
|
39
|
+
* Represents a JSON value.
|
40
|
+
* @typedef {(string | number | boolean | null | JSONArray | JSONObject)} JSON
|
41
|
+
*/
|
42
|
+
/**
|
43
|
+
* Represents a JSON array.
|
44
|
+
* @typedef {Array<JSON>} JSONArray
|
45
|
+
*/
|
46
|
+
/**
|
47
|
+
* Represents a JSON object.
|
48
|
+
* @typedef {{[key: string]: JSON}} JSONObject
|
49
|
+
*/
|
50
|
+
/**
|
51
|
+
* @typedef {Object} FormioHooks
|
52
|
+
* @property {function} [beforeSubmit]
|
53
|
+
* @property {function} [beforeCancel]
|
54
|
+
* @property {function} [beforeNext]
|
55
|
+
* @property {function} [beforePrev]
|
56
|
+
* @property {function} [attachComponent]
|
57
|
+
* @property {function} [setDataValue]
|
58
|
+
* @property {function} [addComponents]
|
59
|
+
* @property {function} [addComponent]
|
60
|
+
* @property {function} [customValidation]
|
61
|
+
* @property {function} [attachWebform]
|
62
|
+
*/
|
63
|
+
/**
|
64
|
+
* @typedef {Object} SanitizeConfig
|
65
|
+
* @property {string[]} [addAttr]
|
66
|
+
* @property {string[]} [addTags]
|
67
|
+
* @property {string[]} [allowedAttrs]
|
68
|
+
* @property {string[]} [allowedTags]
|
69
|
+
* @property {string[]} [allowedUriRegex]
|
70
|
+
* @property {string[]} [addUriSafeAttr]
|
71
|
+
*/
|
72
|
+
/**
|
73
|
+
* @typedef {Object} ButtonSettings
|
74
|
+
* @property {boolean} [showPrevious]
|
75
|
+
* @property {boolean} [showNext]
|
76
|
+
* @property {boolean} [showCancel]
|
77
|
+
* @property {boolean} [showSubmit]
|
78
|
+
*/
|
79
|
+
/**
|
80
|
+
* @typedef {Object} FormOptions
|
81
|
+
* @property {boolean} [saveDraft] - Enable the save draft feature.
|
82
|
+
* @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
|
83
|
+
* @property {boolean} [readOnly] - Set this form to readOnly.
|
84
|
+
* @property {boolean} [noAlerts] - Disable the alerts dialog.
|
85
|
+
* @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
|
86
|
+
* @property {string} [template] - Custom logic for creation of elements.
|
87
|
+
* @property {boolean} [noDefaults] - Exclude default values from the settings.
|
88
|
+
* @property {any} [fileService] - The file service for this form.
|
89
|
+
* @property {EventEmitter} [events] - The EventEmitter for this form.
|
90
|
+
* @property {string} [language] - The language to render this form in.
|
91
|
+
* @property {{[key: string]: string}} [i18next] - The i18next configuration for this form.
|
92
|
+
* @property {boolean} [viewAsHtml] - View the form as raw HTML.
|
93
|
+
* @property {'form' | 'html' | 'flat' | 'builder' | 'pdf'} [renderMode] - The render mode for this form.
|
94
|
+
* @property {boolean} [highlightErrors] - Highlight any errors on the form.
|
95
|
+
* @property {string} [componentErrorClass] - The error class for components.
|
96
|
+
* @property {any} [templates] - The templates for this form.
|
97
|
+
* @property {string} [iconset] - The iconset for this form.
|
98
|
+
* @property {Component[]} [components] - The components for this form.
|
99
|
+
* @property {{[key: string]: boolean}} [disabled] - Disabled components for this form.
|
100
|
+
* @property {boolean} [showHiddenFields] - Show hidden fields.
|
101
|
+
* @property {{[key: string]: boolean}} [hide] - Hidden components for this form.
|
102
|
+
* @property {{[key: string]: boolean}} [show] - Components to show for this form.
|
103
|
+
* @property {Formio} [formio] - The Formio instance for this form.
|
104
|
+
* @property {string} [decimalSeparator] - The decimal separator for this form.
|
105
|
+
* @property {string} [thousandsSeparator] - The thousands separator for this form.
|
106
|
+
* @property {FormioHooks} [hooks] - The hooks for this form.
|
107
|
+
* @property {boolean} [alwaysDirty] - Always be dirty.
|
108
|
+
* @property {boolean} [skipDraftRestore] - Skip restoring a draft.
|
109
|
+
* @property {'form' | 'wizard' | 'pdf'} [display] - The display for this form.
|
110
|
+
* @property {string} [cdnUrl] - The CDN url for this form.
|
111
|
+
* @property {boolean} [flatten] - Flatten the form.
|
112
|
+
* @property {boolean} [sanitize] - Sanitize the form.
|
113
|
+
* @property {SanitizeConfig} [sanitizeConfig] - The sanitize configuration for this form.
|
114
|
+
* @property {ButtonSettings} [buttonSettings] - The button settings for this form.
|
115
|
+
* @property {Object} [breadCrumbSettings] - The breadcrumb settings for this form.
|
116
|
+
* @property {boolean} [allowPrevious] - Allow the previous button (for Wizard forms).
|
117
|
+
* @property {string[]} [wizardButtonOrder] - The order of the buttons (for Wizard forms).
|
118
|
+
* @property {boolean} [showCheckboxBackground] - Show the checkbox background.
|
119
|
+
* @property {number} [zoom] - The zoom for PDF forms.
|
120
|
+
*/
|
37
121
|
/**
|
38
122
|
* Renders a Form.io form within the webpage.
|
39
123
|
*/
|
40
124
|
export default class Webform extends NestedDataComponent {
|
125
|
+
/**
|
126
|
+
* @type {FormOptions} - the options for this Webform.
|
127
|
+
*/
|
128
|
+
options;
|
41
129
|
/**
|
42
130
|
* Creates a new Form instance.
|
43
131
|
*
|
44
|
-
* @param {Object}
|
45
|
-
* @param {
|
46
|
-
* @param {boolean} options.saveDraftThrottle - The throttle for the save draft feature.
|
47
|
-
* @param {boolean} options.readOnly - Set this form to readOnly
|
48
|
-
* @param {boolean} options.noAlerts - Set to true to disable the alerts dialog.
|
49
|
-
* @param {boolean} options.i18n - The translation file for this rendering. @see https://github.com/formio/formio.js/blob/master/i18n.js
|
50
|
-
* @param {boolean} options.template - Provides a way to inject custom logic into the creation of every element rendered within the form.
|
132
|
+
* @param {HTMLElement | Object | FormOptions} [elementOrOptions] - The DOM element to render this form within or the options to create this form instance.
|
133
|
+
* @param {FormOptions} [options] - The options to create a new form instance.
|
51
134
|
*/
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
options = arguments[1];
|
135
|
+
constructor(elementOrOptions, options) {
|
136
|
+
let element, formOptions;
|
137
|
+
if (elementOrOptions instanceof HTMLElement || options) {
|
138
|
+
element = elementOrOptions;
|
139
|
+
formOptions = options;
|
58
140
|
}
|
59
141
|
else {
|
60
|
-
|
142
|
+
formOptions = elementOrOptions;
|
61
143
|
}
|
62
|
-
super(null, getOptions(
|
144
|
+
super(null, getOptions(formOptions));
|
63
145
|
this.setElement(element);
|
64
146
|
// Keep track of all available forms globally.
|
65
147
|
Formio.forms[this.id] = this;
|
@@ -157,7 +157,7 @@ export default class WebformBuilder extends Component {
|
|
157
157
|
return element;
|
158
158
|
}
|
159
159
|
// Attach container and component to element for later reference.
|
160
|
-
const containerElement = element.querySelector(`[
|
160
|
+
const containerElement = element.querySelector(`[${this._referenceAttributeName}="${component.component.key}-container"]`) || element;
|
161
161
|
containerElement.formioContainer = container;
|
162
162
|
containerElement.formioComponent = component;
|
163
163
|
// Add container to draggable list.
|
@@ -1009,7 +1009,7 @@ export default class WebformBuilder extends Component {
|
|
1009
1009
|
};
|
1010
1010
|
const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
|
1011
1011
|
this.preview.form.components.forEach(component => this.replaceDoubleQuotes(component, fieldsToRemoveDoubleQuotes));
|
1012
|
-
const previewElement = this.componentEdit.querySelector(
|
1012
|
+
const previewElement = this.componentEdit.querySelector(`[${this._referenceAttributeName}="preview"]`);
|
1013
1013
|
if (previewElement) {
|
1014
1014
|
this.setContent(previewElement, this.preview.render(), null, sanitizeConfig);
|
1015
1015
|
this.preview.attach(previewElement);
|
@@ -1176,7 +1176,7 @@ export default class WebformBuilder extends Component {
|
|
1176
1176
|
this.emit('saveComponent', schema, originalComp, parentComponentSchema, path, index, isNew, originalComponentSchema);
|
1177
1177
|
}
|
1178
1178
|
attachEditComponentControls(component, parent, isNew, original, ComponentClass) {
|
1179
|
-
const cancelButtons = this.componentEdit.querySelectorAll(
|
1179
|
+
const cancelButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="cancelButton"]`);
|
1180
1180
|
cancelButtons.forEach((cancelButton) => {
|
1181
1181
|
this.editForm.addEventListener(cancelButton, 'click', (event) => {
|
1182
1182
|
event.preventDefault();
|
@@ -1186,7 +1186,7 @@ export default class WebformBuilder extends Component {
|
|
1186
1186
|
this.highlightInvalidComponents();
|
1187
1187
|
});
|
1188
1188
|
});
|
1189
|
-
const removeButtons = this.componentEdit.querySelectorAll(
|
1189
|
+
const removeButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="removeButton"]`);
|
1190
1190
|
removeButtons.forEach((removeButton) => {
|
1191
1191
|
this.editForm.addEventListener(removeButton, 'click', (event) => {
|
1192
1192
|
event.preventDefault();
|
@@ -1198,7 +1198,7 @@ export default class WebformBuilder extends Component {
|
|
1198
1198
|
this.highlightInvalidComponents();
|
1199
1199
|
});
|
1200
1200
|
});
|
1201
|
-
const saveButtons = this.componentEdit.querySelectorAll(
|
1201
|
+
const saveButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="saveButton"]`);
|
1202
1202
|
saveButtons.forEach((saveButton) => {
|
1203
1203
|
this.editForm.addEventListener(saveButton, 'click', (event) => {
|
1204
1204
|
event.preventDefault();
|
@@ -1214,7 +1214,7 @@ export default class WebformBuilder extends Component {
|
|
1214
1214
|
this.saveComponent(component, parent, isNew, original);
|
1215
1215
|
});
|
1216
1216
|
});
|
1217
|
-
const previewButtons = this.componentEdit.querySelectorAll(
|
1217
|
+
const previewButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="previewButton"]`);
|
1218
1218
|
previewButtons.forEach((previewButton) => {
|
1219
1219
|
this.editForm.addEventListener(previewButton, 'click', (event) => {
|
1220
1220
|
event.preventDefault();
|
@@ -1227,7 +1227,7 @@ export default class WebformBuilder extends Component {
|
|
1227
1227
|
showPreview: this.showPreview,
|
1228
1228
|
helplinks: this.helplinks,
|
1229
1229
|
}));
|
1230
|
-
this.editForm.attach(this.componentEdit.querySelector(
|
1230
|
+
this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
|
1231
1231
|
this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
|
1232
1232
|
});
|
1233
1233
|
});
|
@@ -1326,7 +1326,7 @@ export default class WebformBuilder extends Component {
|
|
1326
1326
|
}));
|
1327
1327
|
this.dialog = this.createModal(this.componentEdit, _.get(this.options, 'dialogAttr', {}));
|
1328
1328
|
// This is the attach step.
|
1329
|
-
this.editForm.attach(this.componentEdit.querySelector(
|
1329
|
+
this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
|
1330
1330
|
this.hook('editFormWrapper');
|
1331
1331
|
this.updateComponent(componentCopy);
|
1332
1332
|
this.editForm.on('change', (event) => {
|
@@ -326,6 +326,10 @@ export default class Component extends Element {
|
|
326
326
|
this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;
|
327
327
|
this._visible = this._parentVisible && this.conditionallyVisible(null, data);
|
328
328
|
this._parentDisabled = false;
|
329
|
+
/**
|
330
|
+
* The reference attribute name for this component
|
331
|
+
*/
|
332
|
+
this._referenceAttributeName = 'ref';
|
329
333
|
/**
|
330
334
|
* Used to trigger a new change in this component.
|
331
335
|
* @type {function} - Call to trigger a change in this component.
|
@@ -778,21 +782,22 @@ export default class Component extends Element {
|
|
778
782
|
const name = names[names.length - 1];
|
779
783
|
const templatesByName = Templates.defaultTemplates[name];
|
780
784
|
if (!templatesByName) {
|
781
|
-
return `Unknown template: ${name}
|
785
|
+
return { template: `Unknown template: ${name}` };
|
782
786
|
}
|
783
787
|
const templateByMode = this.checkTemplateMode(templatesByName, modes);
|
784
788
|
if (templateByMode) {
|
785
|
-
return templateByMode;
|
789
|
+
return { template: templateByMode };
|
786
790
|
}
|
787
|
-
return templatesByName.form;
|
791
|
+
return { template: templatesByName.form };
|
788
792
|
}
|
789
793
|
checkTemplate(templates, names, modes) {
|
790
794
|
for (const name of names) {
|
791
795
|
const templatesByName = templates[name];
|
792
796
|
if (templatesByName) {
|
797
|
+
const { referenceAttributeName } = templatesByName;
|
793
798
|
const templateByMode = this.checkTemplateMode(templatesByName, modes);
|
794
799
|
if (templateByMode) {
|
795
|
-
return templateByMode;
|
800
|
+
return { template: templateByMode, referenceAttributeName };
|
796
801
|
}
|
797
802
|
}
|
798
803
|
}
|
@@ -849,7 +854,11 @@ export default class Component extends Element {
|
|
849
854
|
`${name}`,
|
850
855
|
];
|
851
856
|
// Allow template alters.
|
852
|
-
|
857
|
+
const { referenceAttributeName, template } = this.getTemplate(names, mode);
|
858
|
+
if (referenceAttributeName) {
|
859
|
+
this._referenceAttributeName = referenceAttributeName;
|
860
|
+
}
|
861
|
+
return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);
|
853
862
|
}
|
854
863
|
/**
|
855
864
|
* Sanitize an html string.
|
@@ -963,11 +972,19 @@ export default class Component extends Element {
|
|
963
972
|
// Return current timezone if none are provided.
|
964
973
|
return currentTimezone();
|
965
974
|
}
|
966
|
-
|
975
|
+
/**
|
976
|
+
*
|
977
|
+
* @param {HTMLElement} element - The containing DOM element to query for the ref value.
|
978
|
+
* @param {object} refs - The references to load.
|
979
|
+
* @param {string} [referenceAttributeName] - The attribute name to use for the reference.
|
980
|
+
*/
|
981
|
+
loadRefs(element, refs, referenceAttributeName) {
|
967
982
|
for (const ref in refs) {
|
968
983
|
const refType = refs[ref];
|
969
984
|
const isString = typeof refType === 'string';
|
970
|
-
const selector = isString && refType.includes('scope')
|
985
|
+
const selector = isString && refType.includes('scope')
|
986
|
+
? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`
|
987
|
+
: `[${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`;
|
971
988
|
if (isString && refType.startsWith('single')) {
|
972
989
|
this.refs[ref] = element.querySelector(selector);
|
973
990
|
}
|
@@ -1042,7 +1059,7 @@ export default class Component extends Element {
|
|
1042
1059
|
});
|
1043
1060
|
}
|
1044
1061
|
createComponentModal(element, modalShouldBeOpened, currentValue) {
|
1045
|
-
return new ComponentModal(this, element, modalShouldBeOpened, currentValue);
|
1062
|
+
return new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
|
1046
1063
|
}
|
1047
1064
|
attach(element) {
|
1048
1065
|
if (!this.builderMode && !this.previewMode && this.component.modalEdit) {
|
@@ -8,7 +8,8 @@ export default class ComponentModal {
|
|
8
8
|
children,
|
9
9
|
});
|
10
10
|
}
|
11
|
-
constructor(component, element, isOpened, currentValue) {
|
11
|
+
constructor(component, element, isOpened, currentValue, referenceAttributeName = 'ref') {
|
12
|
+
this._referenceAttributeName = referenceAttributeName;
|
12
13
|
this.isOpened = isOpened;
|
13
14
|
this.component = component;
|
14
15
|
this.element = element;
|
@@ -142,10 +143,10 @@ export default class ComponentModal {
|
|
142
143
|
showDialog() {
|
143
144
|
this.dialogElement = this.component.ce('div');
|
144
145
|
const dialogContent = `
|
145
|
-
<h3
|
146
|
+
<h3 ${this._referenceAttributeName}="dialogHeader">${this.component.t('Do you want to clear changes?')}</h3>
|
146
147
|
<div style="display:flex; justify-content: flex-end;">
|
147
|
-
<button
|
148
|
-
<button
|
148
|
+
<button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary">${this.component.t('Cancel')}</button>
|
149
|
+
<button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger">${this.component.t('Yes, delete it')}</button>
|
149
150
|
</div>
|
150
151
|
`;
|
151
152
|
this.dialogElement.innerHTML = dialogContent;
|
@@ -101,7 +101,7 @@ export default class Input extends Multivalue {
|
|
101
101
|
}).trim();
|
102
102
|
if (this.component.prefix !== calendarIcon) {
|
103
103
|
// converting string to HTML markup to render correctly DateTime component in portal.form.io
|
104
|
-
return convertStringToHTMLElement(calendarIcon,
|
104
|
+
return convertStringToHTMLElement(calendarIcon, `[${this._referenceAttributeName}="icon"]`);
|
105
105
|
}
|
106
106
|
}
|
107
107
|
return this.component.suffix;
|
@@ -32,7 +32,7 @@ export default class Multivalue extends Field {
|
|
32
32
|
render() {
|
33
33
|
// If single value field.
|
34
34
|
if (!this.useWrapper()) {
|
35
|
-
return super.render(`<div
|
35
|
+
return super.render(`<div ${this._referenceAttributeName}="element">
|
36
36
|
${this.renderElement(this.component.type !== 'hidden' ? this.dataValue : '')}
|
37
37
|
</div>`);
|
38
38
|
}
|