@formio/js 5.1.0-dev.5976.b0f317d → 5.1.0-dev.5976.f61da27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/formio.builder.css +11 -11
- package/dist/formio.builder.min.css +1 -1
- package/dist/formio.form.css +11 -11
- package/dist/formio.form.js +30 -30
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -1
- package/dist/formio.full.css +11 -11
- package/dist/formio.full.js +36 -36
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -1
- package/dist/formio.js +3 -3
- package/dist/formio.min.js +1 -1
- package/dist/formio.utils.js +1 -1
- package/dist/formio.utils.min.js +1 -1
- package/lib/cjs/Form.d.ts +2 -4
- package/lib/cjs/Form.js +3 -1
- package/lib/cjs/PDFBuilder.js +2 -2
- package/lib/cjs/Webform.d.ts +5 -2
- package/lib/cjs/Webform.js +31 -16
- package/lib/cjs/WebformBuilder.d.ts +1 -0
- package/lib/cjs/WebformBuilder.js +14 -3
- package/lib/cjs/Wizard.js +2 -1
- package/lib/cjs/WizardBuilder.js +14 -1
- package/lib/cjs/components/Components.d.ts +3 -0
- package/lib/cjs/components/_classes/component/Component.js +12 -2
- package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.d.ts +37 -0
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +13 -2
- package/lib/cjs/components/_classes/component/editForm/utils.d.ts +1 -0
- package/lib/cjs/components/_classes/component/editForm/utils.js +3 -0
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -0
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +3 -0
- package/lib/cjs/components/datetime/DateTime.d.ts +1 -1
- package/lib/cjs/components/datetime/DateTime.js +5 -5
- package/lib/cjs/components/day/Day.js +7 -5
- package/lib/cjs/components/file/File.js +2 -1
- package/lib/cjs/components/form/Form.d.ts +4 -2
- package/lib/cjs/components/form/Form.js +25 -10
- package/lib/cjs/components/form/editForm/Form.edit.data.js +1 -1
- package/lib/cjs/components/form/editForm/Form.edit.form.js +2 -2
- package/lib/cjs/components/select/Select.js +1 -1
- package/lib/cjs/components/select/editForm/Select.edit.data.js +2 -2
- package/lib/cjs/components/tags/Tags.d.ts +1 -1
- package/lib/cjs/components/tags/Tags.js +1 -1
- package/lib/cjs/providers/storage/googleDrive.js +3 -2
- package/lib/cjs/providers/storage/s3.js +3 -3
- package/lib/cjs/providers/storage/xhr.d.ts +1 -0
- package/lib/cjs/providers/storage/xhr.js +6 -1
- package/lib/cjs/utils/ChoicesWrapper.d.ts +1 -1
- package/lib/cjs/utils/ChoicesWrapper.js +1 -1
- package/lib/cjs/utils/utils.d.ts +2 -1
- package/lib/cjs/utils/utils.js +3 -2
- package/lib/cjs/widgets/CalendarWidget.js +0 -14
- package/lib/mjs/Form.d.ts +2 -4
- package/lib/mjs/Form.js +4 -2
- package/lib/mjs/PDFBuilder.js +2 -2
- package/lib/mjs/Webform.d.ts +5 -2
- package/lib/mjs/Webform.js +31 -16
- package/lib/mjs/WebformBuilder.d.ts +1 -0
- package/lib/mjs/WebformBuilder.js +13 -2
- package/lib/mjs/Wizard.js +2 -1
- package/lib/mjs/WizardBuilder.js +14 -1
- package/lib/mjs/components/Components.d.ts +3 -0
- package/lib/mjs/components/_classes/component/Component.js +12 -2
- package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.d.ts +37 -0
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +13 -2
- package/lib/mjs/components/_classes/component/editForm/utils.d.ts +1 -0
- package/lib/mjs/components/_classes/component/editForm/utils.js +3 -0
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -0
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +3 -0
- package/lib/mjs/components/datetime/DateTime.d.ts +1 -1
- package/lib/mjs/components/datetime/DateTime.js +5 -5
- package/lib/mjs/components/day/Day.js +7 -5
- package/lib/mjs/components/file/File.js +2 -1
- package/lib/mjs/components/form/Form.d.ts +4 -2
- package/lib/mjs/components/form/Form.js +25 -10
- package/lib/mjs/components/form/editForm/Form.edit.data.js +1 -1
- package/lib/mjs/components/form/editForm/Form.edit.form.js +2 -2
- package/lib/mjs/components/select/Select.js +1 -0
- package/lib/mjs/components/select/editForm/Select.edit.data.js +2 -2
- package/lib/mjs/components/tags/Tags.d.ts +1 -1
- package/lib/mjs/components/tags/Tags.js +1 -1
- package/lib/mjs/providers/storage/googleDrive.js +3 -2
- package/lib/mjs/providers/storage/s3.js +3 -3
- package/lib/mjs/providers/storage/xhr.d.ts +1 -0
- package/lib/mjs/providers/storage/xhr.js +6 -1
- package/lib/mjs/utils/ChoicesWrapper.d.ts +1 -1
- package/lib/mjs/utils/ChoicesWrapper.js +1 -1
- package/lib/mjs/utils/utils.d.ts +2 -1
- package/lib/mjs/utils/utils.js +3 -2
- package/lib/mjs/widgets/CalendarWidget.js +0 -14
- package/package.json +2 -2
@@ -380,10 +380,11 @@ class FormComponent extends Component_1.default {
|
|
380
380
|
/**
|
381
381
|
* Create a subform instance.
|
382
382
|
* @param {boolean} [fromAttach] - This function is being called from an `attach` method.
|
383
|
+
* @param {boolean} [beforeSubmit] - This function is being called from a `beforeSubmit` method.
|
383
384
|
* @returns {*} - The subform instance.
|
384
385
|
*/
|
385
|
-
createSubForm(fromAttach) {
|
386
|
-
this.subFormReady = this.loadSubForm(fromAttach).then((form) => {
|
386
|
+
createSubForm(fromAttach, beforeSubmit) {
|
387
|
+
this.subFormReady = this.loadSubForm(fromAttach, beforeSubmit).then((form) => {
|
387
388
|
if (!form) {
|
388
389
|
return;
|
389
390
|
}
|
@@ -440,11 +441,13 @@ class FormComponent extends Component_1.default {
|
|
440
441
|
/**
|
441
442
|
* Load the subform.
|
442
443
|
* @param {boolean} fromAttach - This function is being called from an `attach` method.
|
444
|
+
* @param {boolean} beforeSubmit - This function is being called from a `beforeSubmit` method.
|
443
445
|
* @returns {Promise} - The promise that resolves when the subform is loaded.
|
444
446
|
*/
|
445
|
-
loadSubForm(fromAttach) {
|
447
|
+
loadSubForm(fromAttach, beforeSubmit) {
|
446
448
|
var _a, _b, _c, _d, _e;
|
447
|
-
|
449
|
+
const loadHiddenForm = beforeSubmit && !this.component.clearOnHide;
|
450
|
+
if (this.builderMode || (this.conditionallyHidden && !loadHiddenForm) || (this.isSubFormLazyLoad() && !fromAttach)) {
|
448
451
|
return Promise.resolve();
|
449
452
|
}
|
450
453
|
if (this.hasLoadedForm && !this.isRevisionChanged &&
|
@@ -516,7 +519,7 @@ class FormComponent extends Component_1.default {
|
|
516
519
|
* @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
|
517
520
|
*/
|
518
521
|
get shouldSubmit() {
|
519
|
-
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.conditionallyHidden;
|
522
|
+
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden || !this.component.clearOnHide);
|
520
523
|
}
|
521
524
|
/**
|
522
525
|
* Returns the data for the subform.
|
@@ -587,11 +590,23 @@ class FormComponent extends Component_1.default {
|
|
587
590
|
this.dataValue = submission;
|
588
591
|
return Promise.resolve(this.dataValue);
|
589
592
|
}
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
593
|
+
// we need to load a hidden form (when clearOnHide is disabled) in order to get and submit (if needed) its data
|
594
|
+
const loadHiddenForm = !this.subForm && !this.component.clearOnHide;
|
595
|
+
if ((this.isSubFormLazyLoad() || loadHiddenForm) && !this.subFormLoading) {
|
596
|
+
return this.createSubForm(true, true)
|
597
|
+
.then(this.submitSubForm(false))
|
598
|
+
.then(() => {
|
599
|
+
return this.dataValue;
|
600
|
+
})
|
601
|
+
.then(() => super.beforeSubmit());
|
602
|
+
}
|
603
|
+
else {
|
604
|
+
return this.submitSubForm(false)
|
605
|
+
.then(() => {
|
606
|
+
return this.dataValue;
|
607
|
+
})
|
608
|
+
.then(() => super.beforeSubmit());
|
609
|
+
}
|
595
610
|
}
|
596
611
|
isSubFormLazyLoad() {
|
597
612
|
var _a, _b;
|
@@ -11,7 +11,7 @@ exports.default = [
|
|
11
11
|
{
|
12
12
|
weight: 140,
|
13
13
|
type: 'checkbox',
|
14
|
-
label: '
|
14
|
+
label: 'Omit Value From Submission Data When Conditionally Hidden',
|
15
15
|
key: 'clearOnHide',
|
16
16
|
defaultValue: true,
|
17
17
|
tooltip: 'When a field is hidden, clear the value.',
|
@@ -69,7 +69,7 @@ exports.default = [
|
|
69
69
|
input: true,
|
70
70
|
weight: 20,
|
71
71
|
key: 'reference',
|
72
|
-
label: '
|
73
|
-
tooltip: '
|
72
|
+
label: 'Submit as reference',
|
73
|
+
tooltip: 'When "Submit as reference" is enabled, the form submission will be recorded against the Parent Form as well as the Child Form. When a submission recorded with "Submit as reference" is edited, the update is applied to each submission made against the Parent Form and Child Form.'
|
74
74
|
}
|
75
75
|
];
|
@@ -770,7 +770,7 @@ class SelectComponent extends ListComponent_1.default {
|
|
770
770
|
containerOuter: ['choices', 'form-group', 'formio-choices'],
|
771
771
|
containerInner: this.transform('class', 'form-control ui fluid selection dropdown').split(' '),
|
772
772
|
}, addItemText: false, allowHTML: true, placeholder: !!this.component.placeholder, placeholderValue: placeholderValue, noResultsText: this.t('noResultsFound'), noChoicesText: this.t('noChoices'), searchPlaceholderValue: this.t('typeToSearch'), shouldSort: false, position: (this.component.dropdown || 'auto'), searchEnabled: useSearch, searchChoices: !this.component.searchField, searchFields: lodash_1.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch
|
773
|
-
? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false }, customOptions);
|
773
|
+
? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false, duplicateItemsAllowed: false }, customOptions);
|
774
774
|
}
|
775
775
|
/* eslint-disable max-statements */
|
776
776
|
attach(element) {
|
@@ -641,8 +641,8 @@ exports.default = [
|
|
641
641
|
input: true,
|
642
642
|
weight: 25,
|
643
643
|
key: 'reference',
|
644
|
-
label: '
|
645
|
-
tooltip: 'Using this option will
|
644
|
+
label: 'Submit as reference',
|
645
|
+
tooltip: 'Using this option will submit this field as a reference id and link its value to the value of the origin record.',
|
646
646
|
conditional: {
|
647
647
|
json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
|
648
648
|
},
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const utils_1 = require("../../utils/utils");
|
7
7
|
const Input_1 = __importDefault(require("../_classes/input/Input"));
|
8
|
-
const choices_js_1 = __importDefault(require("
|
8
|
+
const choices_js_1 = __importDefault(require("choices.js"));
|
9
9
|
class TagsComponent extends Input_1.default {
|
10
10
|
static schema(...extend) {
|
11
11
|
return Input_1.default.schema({
|
@@ -52,10 +52,11 @@ function googledrive(formio) {
|
|
52
52
|
xhr.send(fd);
|
53
53
|
}));
|
54
54
|
},
|
55
|
-
downloadFile(file) {
|
55
|
+
downloadFile(file, component) {
|
56
56
|
const token = formio.getToken();
|
57
|
+
// Constructed the url with the fileId, fileName, displayImage, imageSize if applicable
|
57
58
|
file.url =
|
58
|
-
`${formio.formUrl}/storage/gdrive?fileId=${file.id}&fileName=${file.originalName}${token ? `&x-jwt-token=${token}` : ''}`;
|
59
|
+
`${formio.formUrl}/storage/gdrive?fileId=${file.id}&fileName=${file.originalName}${token ? `&x-jwt-token=${token}` : ''}${component.image ? '&displayImage=true' : ''}${component.imageSize ? `&imageSize=${component.imageSize}` : ''}`;
|
59
60
|
return Promise.resolve(file);
|
60
61
|
},
|
61
62
|
deleteFile: function deleteFile(fileInfo) {
|
@@ -115,7 +115,7 @@ function s3(formio) {
|
|
115
115
|
const { changeMessage } = multipart;
|
116
116
|
changeMessage('Completing AWS S3 multipart upload...');
|
117
117
|
const token = formio.getToken();
|
118
|
-
const response = yield fetch(`${formio.formUrl}/storage/s3/multipart/complete`, {
|
118
|
+
const response = yield xhr_1.default.fetch(`${formio.formUrl}/storage/s3/multipart/complete`, {
|
119
119
|
method: 'POST',
|
120
120
|
headers: Object.assign({ 'Content-Type': 'application/json' }, (token ? { 'x-jwt-token': token } : {})),
|
121
121
|
body: JSON.stringify({ parts, uploadId: serverResponse.uploadId, key: serverResponse.key })
|
@@ -134,7 +134,7 @@ function s3(formio) {
|
|
134
134
|
abortMultipartUpload(serverResponse) {
|
135
135
|
const { uploadId, key } = serverResponse;
|
136
136
|
const token = formio.getToken();
|
137
|
-
fetch(`${formio.formUrl}/storage/s3/multipart/abort`, {
|
137
|
+
xhr_1.default.fetch(`${formio.formUrl}/storage/s3/multipart/abort`, {
|
138
138
|
method: 'POST',
|
139
139
|
headers: Object.assign({ 'Content-Type': 'application/json' }, (token ? { 'x-jwt-token': token } : {})),
|
140
140
|
body: JSON.stringify({ uploadId, key })
|
@@ -148,7 +148,7 @@ function s3(formio) {
|
|
148
148
|
const start = i * partSize;
|
149
149
|
const end = (i + 1) * partSize;
|
150
150
|
const blob = i < urls.length ? file.slice(start, end) : file.slice(start);
|
151
|
-
const promise = fetch(urls[i], {
|
151
|
+
const promise = xhr_1.default.fetch(urls[i], {
|
152
152
|
method: 'PUT',
|
153
153
|
headers,
|
154
154
|
body: blob,
|
@@ -3,6 +3,7 @@ export default XHR;
|
|
3
3
|
declare namespace XHR {
|
4
4
|
function trim(text: any): any;
|
5
5
|
function path(items: any): any;
|
6
|
+
function fetch(url: any, options: any): Promise<Response>;
|
6
7
|
function upload(formio: any, type: any, xhrCallback: any, file: any, fileName: any, dir: any, progressCallback: any, groupPermissions: any, groupId: any, abortCallback: any, multipartOptions: any): Promise<any>;
|
7
8
|
function makeXhrRequest(formio: any, xhrCallback: any, serverResponse: any, progressCallback: any, abortCallback: any): Promise<any>;
|
8
9
|
}
|
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
15
15
|
exports.setXhrHeaders = void 0;
|
16
16
|
const trim_1 = __importDefault(require("lodash/trim"));
|
17
|
+
const Formio_1 = require("../../Formio");
|
17
18
|
const setXhrHeaders = (formio, xhr) => {
|
18
19
|
const { headers } = formio.options;
|
19
20
|
if (headers) {
|
@@ -36,13 +37,17 @@ const XHR = {
|
|
36
37
|
path(items) {
|
37
38
|
return items.filter(item => !!item).map(XHR.trim).join('/');
|
38
39
|
},
|
40
|
+
fetch(url, options) {
|
41
|
+
options = Formio_1.Formio.pluginAlter('requestOptions', options, url);
|
42
|
+
return fetch(url, options);
|
43
|
+
},
|
39
44
|
upload(formio, type, xhrCallback, file, fileName, dir, progressCallback, groupPermissions, groupId, abortCallback, multipartOptions) {
|
40
45
|
return __awaiter(this, void 0, void 0, function* () {
|
41
46
|
// make request to Form.io server
|
42
47
|
const token = formio.getToken();
|
43
48
|
let response;
|
44
49
|
try {
|
45
|
-
response = yield fetch(`${formio.formUrl}/storage/${type}`, {
|
50
|
+
response = yield XHR.fetch(`${formio.formUrl}/storage/${type}`, {
|
46
51
|
method: 'POST',
|
47
52
|
headers: Object.assign({ 'Accept': 'application/json', 'Content-Type': 'application/json; charset=UTF-8' }, (token ? { 'x-jwt-token': token } : {})),
|
48
53
|
body: JSON.stringify({
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
23
|
return result;
|
24
24
|
};
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
-
const choices_js_1 = __importStar(require("
|
26
|
+
const choices_js_1 = __importStar(require("choices.js"));
|
27
27
|
const ExtendedKeyCodeMap = Object.assign(Object.assign({}, choices_js_1.KeyCodeMap), { TAB_KEY: 9 });
|
28
28
|
class ChoicesWrapper extends choices_js_1.default {
|
29
29
|
constructor(...args) {
|
package/lib/cjs/utils/utils.d.ts
CHANGED
@@ -208,9 +208,10 @@ export function loadZones(url: string, timezone: string): Promise<any> | any;
|
|
208
208
|
* @param {string|Date} value - The value to convert into a moment date.
|
209
209
|
* @param {string} format - The format to convert the date to.
|
210
210
|
* @param {string} timezone - The timezone to convert the date to.
|
211
|
+
* @param {object} options - The options object
|
211
212
|
* @returns {Date} - The moment date object.
|
212
213
|
*/
|
213
|
-
export function momentDate(value: string | Date, format: string, timezone: string): Date;
|
214
|
+
export function momentDate(value: string | Date, format: string, timezone: string, options: object): Date;
|
214
215
|
/**
|
215
216
|
* Format a date provided a value, format, and timezone object.
|
216
217
|
* @param {string} timezonesUrl - The URL to load the timezone data from.
|
package/lib/cjs/utils/utils.js
CHANGED
@@ -687,9 +687,10 @@ exports.loadZones = loadZones;
|
|
687
687
|
* @param {string|Date} value - The value to convert into a moment date.
|
688
688
|
* @param {string} format - The format to convert the date to.
|
689
689
|
* @param {string} timezone - The timezone to convert the date to.
|
690
|
+
* @param {object} options - The options object
|
690
691
|
* @returns {Date} - The moment date object.
|
691
692
|
*/
|
692
|
-
function momentDate(value, format, timezone) {
|
693
|
+
function momentDate(value, format, timezone, options) {
|
693
694
|
const momentDate = (0, moment_timezone_1.default)(value);
|
694
695
|
if (!timezone) {
|
695
696
|
return momentDate;
|
@@ -697,7 +698,7 @@ function momentDate(value, format, timezone) {
|
|
697
698
|
if (timezone === 'UTC') {
|
698
699
|
timezone = 'Etc/UTC';
|
699
700
|
}
|
700
|
-
if ((timezone !== currentTimezone() || (format && format.match(/\s(z$|z\s)/))) && moment_timezone_1.default.zonesLoaded) {
|
701
|
+
if ((timezone !== currentTimezone() || (format && format.match(/\s(z$|z\s)/))) && (moment_timezone_1.default.zonesLoaded || (options === null || options === void 0 ? void 0 : options.email))) {
|
701
702
|
return momentDate.tz(timezone);
|
702
703
|
}
|
703
704
|
return momentDate;
|
@@ -93,8 +93,6 @@ class CalendarWidget extends InputWidget_1.default {
|
|
93
93
|
this.settings.disableWeekends ? this.settings.disable.push(this.disableWeekends) : '';
|
94
94
|
this.settings.disableWeekdays ? this.settings.disable.push(this.disableWeekdays) : '';
|
95
95
|
this.settings.disableFunction ? this.settings.disable.push(this.disableFunction) : '';
|
96
|
-
this.settings.wasDefaultValueChanged = false;
|
97
|
-
this.settings.defaultValue = '';
|
98
96
|
this.settings.manualInputValue = '';
|
99
97
|
this.settings.isManuallyOverriddenValue = false;
|
100
98
|
this.settings.currentValue = '';
|
@@ -115,10 +113,6 @@ class CalendarWidget extends InputWidget_1.default {
|
|
115
113
|
this.calendar._input.value = this.settings.isManuallyOverriddenValue ? this.settings.manualInputValue : this.calendar.altInput.value;
|
116
114
|
this.emit('update');
|
117
115
|
}
|
118
|
-
if (this.settings.wasDefaultValueChanged) {
|
119
|
-
this.calendar._input.value = this.settings.defaultValue;
|
120
|
-
this.settings.wasDefaultValueChanged = false;
|
121
|
-
}
|
122
116
|
if (this.calendar) {
|
123
117
|
this.emit('blur');
|
124
118
|
}
|
@@ -360,14 +354,6 @@ class CalendarWidget extends InputWidget_1.default {
|
|
360
354
|
this.settings.currentValue = event.target.value;
|
361
355
|
this.emit('update');
|
362
356
|
}
|
363
|
-
if (event.target.value === '' && this.calendar.selectedDates.length > 0) {
|
364
|
-
this.settings.wasDefaultValueChanged = true;
|
365
|
-
this.settings.defaultValue = event.target.value;
|
366
|
-
this.calendar.clear();
|
367
|
-
}
|
368
|
-
else {
|
369
|
-
this.settings.wasDefaultValueChanged = false;
|
370
|
-
}
|
371
357
|
});
|
372
358
|
if (this.calendar.daysContainer) {
|
373
359
|
this.calendar.daysContainer.addEventListener('click', () => {
|
package/lib/mjs/Form.d.ts
CHANGED
@@ -48,7 +48,7 @@ export default class Form extends Element {
|
|
48
48
|
* @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
|
49
49
|
* @property {boolean} [readOnly] - Set this form to readOnly.
|
50
50
|
* @property {boolean} [noAlerts] - Disable the alerts dialog.
|
51
|
-
* @property {
|
51
|
+
* @property {Record<string, Record<string, string>>} [i18n] - The translation file for this rendering.
|
52
52
|
* @property {string} [template] - Custom logic for creation of elements.
|
53
53
|
* @property {boolean} [noDefaults] - Exclude default values from the settings.
|
54
54
|
* @property {any} [fileService] - The file service for this form.
|
@@ -117,9 +117,7 @@ export default class Form extends Element {
|
|
117
117
|
/**
|
118
118
|
* - The translation file for this rendering.
|
119
119
|
*/
|
120
|
-
i18n?:
|
121
|
-
[key: string]: string;
|
122
|
-
} | undefined;
|
120
|
+
i18n?: Record<string, Record<string, string>> | undefined;
|
123
121
|
/**
|
124
122
|
* - Custom logic for creation of elements.
|
125
123
|
*/
|
package/lib/mjs/Form.js
CHANGED
@@ -51,7 +51,7 @@ export default class Form extends Element {
|
|
51
51
|
* @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
|
52
52
|
* @property {boolean} [readOnly] - Set this form to readOnly.
|
53
53
|
* @property {boolean} [noAlerts] - Disable the alerts dialog.
|
54
|
-
* @property {
|
54
|
+
* @property {Record<string, Record<string, string>>} [i18n] - The translation file for this rendering.
|
55
55
|
* @property {string} [template] - Custom logic for creation of elements.
|
56
56
|
* @property {boolean} [noDefaults] - Exclude default values from the settings.
|
57
57
|
* @property {any} [fileService] - The file service for this form.
|
@@ -350,7 +350,9 @@ export default class Form extends Element {
|
|
350
350
|
this.form.display = display;
|
351
351
|
this.instance.destroy();
|
352
352
|
this.instance = this.create(display);
|
353
|
-
return this.setForm(this.form)
|
353
|
+
return this.setForm(this.form).then(() => {
|
354
|
+
this.instance.emit('setDisplay', this.form.display);
|
355
|
+
});
|
354
356
|
}
|
355
357
|
empty() {
|
356
358
|
if (this.element) {
|
package/lib/mjs/PDFBuilder.js
CHANGED
@@ -294,7 +294,7 @@ export default class PDFBuilder extends WebformBuilder {
|
|
294
294
|
height: schema.height,
|
295
295
|
width: schema.width
|
296
296
|
};
|
297
|
-
if (!this.options.noNewEdit && !component.component.noNewEdit) {
|
297
|
+
if (!this.options.noNewEdit && !component.component.noNewEdit && this.hasEditTabs(component.type)) {
|
298
298
|
this.editComponent(component.component, this.getParentContainer(component), isNew);
|
299
299
|
}
|
300
300
|
this.emit('updateComponent', component.component);
|
@@ -318,7 +318,7 @@ export default class PDFBuilder extends WebformBuilder {
|
|
318
318
|
});
|
319
319
|
this.webform.on('iframe-componentClick', schema => {
|
320
320
|
const component = this.webform.getComponentById(schema.id);
|
321
|
-
if (component) {
|
321
|
+
if (component && this.hasEditTabs(component.type)) {
|
322
322
|
this.editComponent(component.component, this.getParentContainer(component));
|
323
323
|
}
|
324
324
|
}, true);
|
package/lib/mjs/Webform.d.ts
CHANGED
@@ -190,7 +190,10 @@ declare class Webform extends NestedDataComponent {
|
|
190
190
|
get language(): string;
|
191
191
|
root: this;
|
192
192
|
localRoot: this;
|
193
|
+
beforeInit(): void;
|
194
|
+
executeFormController: any;
|
193
195
|
get emptyValue(): null;
|
196
|
+
get shouldCallFormController(): any;
|
194
197
|
get shadowRoot(): any;
|
195
198
|
/**
|
196
199
|
* Add a language for translations
|
@@ -360,7 +363,7 @@ declare class Webform extends NestedDataComponent {
|
|
360
363
|
* @returns {Promise} - The promise that is triggered when the form is built.
|
361
364
|
*/
|
362
365
|
init(): Promise<any>;
|
363
|
-
|
366
|
+
_executeFormController(): void;
|
364
367
|
build(element: any): Promise<any>;
|
365
368
|
getClassName(): string;
|
366
369
|
render(): string;
|
@@ -452,7 +455,7 @@ declare class Webform extends NestedDataComponent {
|
|
452
455
|
*/
|
453
456
|
submit(before?: boolean, options?: any): Promise<any>;
|
454
457
|
submitUrl(URL: any, headers: any): void;
|
455
|
-
triggerCaptcha(): void;
|
458
|
+
triggerCaptcha(components?: null): void;
|
456
459
|
_nosubmit: any;
|
457
460
|
get conditions(): any;
|
458
461
|
get variables(): any;
|
package/lib/mjs/Webform.js
CHANGED
@@ -287,12 +287,24 @@ export default class Webform extends NestedDataComponent {
|
|
287
287
|
this.localRoot = this;
|
288
288
|
}
|
289
289
|
/* eslint-enable max-statements */
|
290
|
+
beforeInit() {
|
291
|
+
this.executeFormController = _.once(this._executeFormController);
|
292
|
+
}
|
290
293
|
get language() {
|
291
294
|
return this.options.language;
|
292
295
|
}
|
293
296
|
get emptyValue() {
|
294
297
|
return null;
|
295
298
|
}
|
299
|
+
get shouldCallFormController() {
|
300
|
+
// If no controller value or
|
301
|
+
// hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
|
302
|
+
return (this.form &&
|
303
|
+
this.form.controller &&
|
304
|
+
!((!this.visible || this.component.hidden) &&
|
305
|
+
this.component.clearOnHide &&
|
306
|
+
!this.rootPristine));
|
307
|
+
}
|
296
308
|
componentContext() {
|
297
309
|
return this._data;
|
298
310
|
}
|
@@ -902,19 +914,12 @@ export default class Webform extends NestedDataComponent {
|
|
902
914
|
this.on('resetForm', () => this.resetValue(), true);
|
903
915
|
this.on('deleteSubmission', () => this.deleteSubmission(), true);
|
904
916
|
this.on('refreshData', () => this.updateValue(), true);
|
905
|
-
this.
|
917
|
+
if (this.shouldCallFormController) {
|
918
|
+
this.executeFormController();
|
919
|
+
}
|
906
920
|
return this.formReady;
|
907
921
|
}
|
908
|
-
|
909
|
-
// If no controller value or
|
910
|
-
// hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
|
911
|
-
if (!this.form ||
|
912
|
-
!this.form.controller ||
|
913
|
-
((!this.visible || this.component.hidden) &&
|
914
|
-
this.component.clearOnHide &&
|
915
|
-
!this.rootPristine)) {
|
916
|
-
return false;
|
917
|
-
}
|
922
|
+
_executeFormController() {
|
918
923
|
this.formReady.then(() => {
|
919
924
|
this.evaluate(this.form.controller, {
|
920
925
|
components: this.components,
|
@@ -1529,18 +1534,28 @@ export default class Webform extends NestedDataComponent {
|
|
1529
1534
|
return console.warn(message);
|
1530
1535
|
}
|
1531
1536
|
}
|
1532
|
-
triggerCaptcha() {
|
1533
|
-
if (!this || !this.components) {
|
1537
|
+
triggerCaptcha(components = null) {
|
1538
|
+
if (!this || !this.components || this.options.preview) {
|
1534
1539
|
return;
|
1535
1540
|
}
|
1536
1541
|
const captchaComponent = [];
|
1537
|
-
this.
|
1542
|
+
eachComponent(components || this.components, (component) => {
|
1538
1543
|
if (/^(re)?captcha$/.test(component.type) && component.component.eventType === 'formLoad') {
|
1539
1544
|
captchaComponent.push(component);
|
1540
1545
|
}
|
1541
|
-
});
|
1546
|
+
}, true);
|
1542
1547
|
if (captchaComponent.length > 0) {
|
1543
|
-
captchaComponent[0].
|
1548
|
+
if (captchaComponent[0].component.provider === 'google' && components) {
|
1549
|
+
return;
|
1550
|
+
}
|
1551
|
+
if (this.parent) {
|
1552
|
+
this.parent.subFormReady.then(() => {
|
1553
|
+
captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
|
1554
|
+
});
|
1555
|
+
}
|
1556
|
+
else {
|
1557
|
+
captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
|
1558
|
+
}
|
1544
1559
|
}
|
1545
1560
|
}
|
1546
1561
|
set nosubmit(value) {
|
@@ -123,6 +123,7 @@ export default class WebformBuilder extends Component {
|
|
123
123
|
addBuilderGroup(name: any, group: any): void;
|
124
124
|
updateBuilderGroup(name: any, group: any): void;
|
125
125
|
generateKey(info: any): any;
|
126
|
+
hasEditTabs(type: any): boolean;
|
126
127
|
}
|
127
128
|
import Component from './components/_classes/component/Component';
|
128
129
|
import Webform from './Webform';
|
@@ -115,7 +115,9 @@ export default class WebformBuilder extends Component {
|
|
115
115
|
html,
|
116
116
|
disableBuilderActions: self?.component?.disableBuilderActions,
|
117
117
|
childComponent: component,
|
118
|
-
design: self?.options?.design
|
118
|
+
design: self?.options?.design,
|
119
|
+
editJson: self?.options?.editJson,
|
120
|
+
editComponent: this.hasEditTabs(component.type)
|
119
121
|
});
|
120
122
|
};
|
121
123
|
this.options.hooks.renderComponents = (html, { components, self }) => {
|
@@ -840,7 +842,11 @@ export default class WebformBuilder extends Component {
|
|
840
842
|
parent.addChildComponent(info, element, target, source, sibling);
|
841
843
|
}
|
842
844
|
const componentInDataGrid = parent.type === 'datagrid';
|
843
|
-
if (isNew
|
845
|
+
if (isNew
|
846
|
+
&& !this.options.noNewEdit
|
847
|
+
&& !info.noNewEdit
|
848
|
+
&& this.hasEditTabs(info.type)
|
849
|
+
&& !(this.options.design && info.type === 'reviewpage')) {
|
844
850
|
this.editComponent(info, target, isNew, null, null, { inDataGrid: componentInDataGrid });
|
845
851
|
}
|
846
852
|
// Only rebuild the parts needing to be rebuilt.
|
@@ -1619,4 +1625,9 @@ export default class WebformBuilder extends Component {
|
|
1619
1625
|
info.placeholder ||
|
1620
1626
|
info.type);
|
1621
1627
|
}
|
1628
|
+
hasEditTabs(type) {
|
1629
|
+
const editTabs = getComponent(Components.components[type].editForm().components, 'tabs', true).components;
|
1630
|
+
const hiddenEditTabs = _.filter(_.get(this.options, `editForm.${type}`, []), 'ignore');
|
1631
|
+
return _.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
|
1632
|
+
}
|
1622
1633
|
}
|
package/lib/mjs/Wizard.js
CHANGED
@@ -594,6 +594,7 @@ export default class Wizard extends Webform {
|
|
594
594
|
}
|
595
595
|
this.redraw().then(() => {
|
596
596
|
this.checkData(this.submission.data);
|
597
|
+
this.triggerCaptcha(this.currentPanel.components);
|
597
598
|
const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
|
598
599
|
if (this.alert) {
|
599
600
|
this.showErrors(errors, true, true);
|
@@ -657,7 +658,7 @@ export default class Wizard extends Webform {
|
|
657
658
|
return this.page - 1;
|
658
659
|
}
|
659
660
|
beforeSubmit() {
|
660
|
-
const pages = this.getPages();
|
661
|
+
const pages = this.getPages({ all: true });
|
661
662
|
return Promise.all(pages.map((page) => {
|
662
663
|
page.options.beforeSubmit = true;
|
663
664
|
return page.beforeSubmit();
|
package/lib/mjs/WizardBuilder.js
CHANGED
@@ -255,10 +255,23 @@ export default class WizardBuilder extends WebformBuilder {
|
|
255
255
|
if (component instanceof WizardBuilder) {
|
256
256
|
return;
|
257
257
|
}
|
258
|
+
if (!window.sessionStorage) {
|
259
|
+
return console.warn(this.t('sessionStorageSupportError'));
|
260
|
+
}
|
261
|
+
// If pasting after the Wizard's page, check if a full Wizard page was copied and pass it to addPage method
|
258
262
|
if (this._form.components.find(comp => _.isEqual(component.component, comp))) {
|
259
|
-
|
263
|
+
const data = window.sessionStorage.getItem('formio.clipboard');
|
264
|
+
if (data) {
|
265
|
+
const schema = JSON.parse(data);
|
266
|
+
// If the copied component is not a Wizard's page, do nothing since we can't paste outside the panel in Wizard
|
267
|
+
if (schema.type !== 'panel') {
|
268
|
+
return;
|
269
|
+
}
|
270
|
+
this.addPage(schema);
|
271
|
+
}
|
260
272
|
}
|
261
273
|
else {
|
274
|
+
// If we are not trying to paster after the current Wizard's page, just pass it to the WebformBuilder
|
262
275
|
return super.pasteComponent(component);
|
263
276
|
}
|
264
277
|
}
|
@@ -2,6 +2,7 @@ export default class Components {
|
|
2
2
|
static _editFormUtils: {
|
3
3
|
sortAndFilterComponents(components: any): any;
|
4
4
|
unifyComponents(objValue: any, srcValue: any): any;
|
5
|
+
tokenVariableDescription(): string;
|
5
6
|
logicVariablesTable(additional: any): {
|
6
7
|
type: string;
|
7
8
|
tag: string;
|
@@ -86,6 +87,7 @@ export default class Components {
|
|
86
87
|
static set EditFormUtils(value: {
|
87
88
|
sortAndFilterComponents(components: any): any;
|
88
89
|
unifyComponents(objValue: any, srcValue: any): any;
|
90
|
+
tokenVariableDescription(): string;
|
89
91
|
logicVariablesTable(additional: any): {
|
90
92
|
type: string;
|
91
93
|
tag: string;
|
@@ -169,6 +171,7 @@ export default class Components {
|
|
169
171
|
static get EditFormUtils(): {
|
170
172
|
sortAndFilterComponents(components: any): any;
|
171
173
|
unifyComponents(objValue: any, srcValue: any): any;
|
174
|
+
tokenVariableDescription(): string;
|
172
175
|
logicVariablesTable(additional: any): {
|
173
176
|
type: string;
|
174
177
|
tag: string;
|
@@ -161,6 +161,7 @@ export default class Component extends Element {
|
|
161
161
|
properties: {},
|
162
162
|
allowMultipleMasks: false,
|
163
163
|
addons: [],
|
164
|
+
serverOverride: {},
|
164
165
|
}, ...sources);
|
165
166
|
}
|
166
167
|
/**
|
@@ -418,6 +419,9 @@ export default class Component extends Element {
|
|
418
419
|
// Allow anyone to hook into the component creation.
|
419
420
|
this.hook('component');
|
420
421
|
if (!this.options.skipInit) {
|
422
|
+
if (typeof this.beforeInit === 'function') {
|
423
|
+
this.beforeInit();
|
424
|
+
}
|
421
425
|
this.init();
|
422
426
|
}
|
423
427
|
}
|
@@ -1264,7 +1268,7 @@ export default class Component extends Element {
|
|
1264
1268
|
detach() {
|
1265
1269
|
// First iterate through each ref and delete the component so there are no dangling component references.
|
1266
1270
|
_.each(this.refs, (ref) => {
|
1267
|
-
if (
|
1271
|
+
if (ref instanceof NodeList) {
|
1268
1272
|
ref.forEach((elem) => {
|
1269
1273
|
delete elem.component;
|
1270
1274
|
});
|
@@ -1914,15 +1918,21 @@ export default class Component extends Element {
|
|
1914
1918
|
}
|
1915
1919
|
// Check advanced conditions (and cache the result)
|
1916
1920
|
const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;
|
1921
|
+
let shouldClear = false;
|
1917
1922
|
if (isConditionallyHidden !== this._conditionallyHidden) {
|
1918
1923
|
this._conditionallyHidden = isConditionallyHidden;
|
1919
|
-
|
1924
|
+
shouldClear = true;
|
1920
1925
|
}
|
1921
1926
|
// Check visibility
|
1922
1927
|
const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
|
1923
1928
|
if (this.visible !== visible) {
|
1924
1929
|
this.visible = visible;
|
1925
1930
|
}
|
1931
|
+
// Wait for visibility to update for nested components, so the component state is up-to-date when
|
1932
|
+
// calling clearOnHide
|
1933
|
+
if (shouldClear) {
|
1934
|
+
this.clearOnHide();
|
1935
|
+
}
|
1926
1936
|
return visible;
|
1927
1937
|
}
|
1928
1938
|
/**
|
@@ -45,6 +45,6 @@ export default [
|
|
45
45
|
},
|
46
46
|
EditFormUtils.javaScriptValue('Advanced Conditions', 'customConditional', 'conditional.json', 110, '<p>You must assign the <strong>show</strong> variable a boolean result.</p>' +
|
47
47
|
'<p><strong>Note: Advanced Conditional logic will override the results of the Simple Conditional logic.</strong></p>' +
|
48
|
-
'<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>')
|
48
|
+
'<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', EditFormUtils.tokenVariableDescription())
|
49
49
|
];
|
50
50
|
/* eslint-enable quotes, max-len */
|