@formio/js 5.2.0 → 5.2.1-dev.6202.2449b29
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/Changelog.md +6969 -0
- package/dist/formio.builder.css +15 -17
- package/dist/formio.builder.min.css +1 -1
- 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.css +15 -17
- package/dist/formio.form.js +49 -60
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +3 -3
- package/dist/formio.full.css +15 -17
- package/dist/formio.full.js +51 -62
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +3 -3
- package/dist/formio.js +20 -31
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +19 -30
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Embed.js +1 -1
- package/lib/cjs/Formio.js +1 -1
- package/lib/cjs/PDFBuilder.js +8 -6
- package/lib/cjs/Webform.js +11 -2
- package/lib/cjs/WebformBuilder.js +29 -14
- package/lib/cjs/Wizard.d.ts +1 -2
- package/lib/cjs/Wizard.js +22 -23
- package/lib/cjs/components/Components.js +1 -1
- package/lib/cjs/components/_classes/component/Component.d.ts +23 -2
- package/lib/cjs/components/_classes/component/Component.js +61 -35
- package/lib/cjs/components/_classes/nested/NestedComponent.js +6 -5
- package/lib/cjs/components/datagrid/DataGrid.js +8 -1
- package/lib/cjs/components/file/File.d.ts +1 -1
- package/lib/cjs/components/file/File.js +6 -1
- package/lib/cjs/components/form/Form.d.ts +0 -2
- package/lib/cjs/components/form/Form.js +12 -20
- package/lib/cjs/components/radio/Radio.js +1 -1
- package/lib/cjs/components/select/Select.d.ts +1 -1
- package/lib/cjs/components/select/Select.js +17 -26
- package/lib/cjs/components/tags/Tags.d.ts +1 -1
- package/lib/cjs/components/tags/Tags.js +2 -2
- package/lib/cjs/formio.form.js +1 -0
- package/lib/cjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/cjs/utils/ChoicesWrapper.js +47 -124
- package/lib/cjs/utils/formUtils.d.ts +3 -3
- package/lib/cjs/utils/index.d.ts +5 -5
- package/lib/cjs/utils/utils.d.ts +4 -4
- package/lib/cjs/utils/utils.js +2 -2
- package/lib/cjs/widgets/CalendarWidget.d.ts +1 -1
- package/lib/cjs/widgets/CalendarWidget.js +1 -1
- package/lib/mjs/Embed.js +1 -1
- package/lib/mjs/Formio.js +1 -1
- package/lib/mjs/PDFBuilder.js +8 -6
- package/lib/mjs/Webform.js +10 -2
- package/lib/mjs/WebformBuilder.js +30 -15
- package/lib/mjs/Wizard.d.ts +1 -2
- package/lib/mjs/Wizard.js +21 -22
- package/lib/mjs/components/Components.js +1 -1
- package/lib/mjs/components/_classes/component/Component.d.ts +23 -2
- package/lib/mjs/components/_classes/component/Component.js +61 -35
- package/lib/mjs/components/_classes/nested/NestedComponent.js +5 -5
- package/lib/mjs/components/datagrid/DataGrid.js +7 -1
- package/lib/mjs/components/file/File.d.ts +1 -1
- package/lib/mjs/components/file/File.js +6 -1
- package/lib/mjs/components/form/Form.d.ts +0 -2
- package/lib/mjs/components/form/Form.js +12 -20
- package/lib/mjs/components/radio/Radio.js +1 -1
- package/lib/mjs/components/select/Select.d.ts +1 -1
- package/lib/mjs/components/select/Select.js +17 -25
- package/lib/mjs/components/tags/Tags.d.ts +1 -1
- package/lib/mjs/components/tags/Tags.js +2 -2
- package/lib/mjs/formio.form.js +1 -0
- package/lib/mjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/mjs/utils/ChoicesWrapper.js +26 -119
- package/lib/mjs/utils/formUtils.d.ts +3 -3
- package/lib/mjs/utils/index.d.ts +5 -5
- package/lib/mjs/utils/utils.d.ts +4 -4
- package/lib/mjs/utils/utils.js +2 -2
- package/lib/mjs/widgets/CalendarWidget.d.ts +1 -1
- package/lib/mjs/widgets/CalendarWidget.js +1 -1
- package/package.json +5 -5
package/lib/mjs/Webform.js
CHANGED
@@ -323,6 +323,14 @@ export default class Webform extends NestedDataComponent {
|
|
323
323
|
get shadowRoot() {
|
324
324
|
return this.options.shadowRoot;
|
325
325
|
}
|
326
|
+
// Webforms have no default value setting, so this should be always false
|
327
|
+
// I does not affect setting default value to nested forms
|
328
|
+
get shouldAddDefaultValue() {
|
329
|
+
return false;
|
330
|
+
}
|
331
|
+
get componentsMap() {
|
332
|
+
return this.childComponentsMap || {};
|
333
|
+
}
|
326
334
|
/**
|
327
335
|
* Add a language for translations
|
328
336
|
* @param {string} code - The language code for the language being added.
|
@@ -744,7 +752,7 @@ export default class Webform extends NestedDataComponent {
|
|
744
752
|
this.emit(restoreDraft ? "restoreDraftError" : "saveDraftError", errDetails || errorMessage);
|
745
753
|
}
|
746
754
|
saveDraft() {
|
747
|
-
if (!this.draftEnabled) {
|
755
|
+
if (!this.draftEnabled || this.parent?.component.reference === false) {
|
748
756
|
return;
|
749
757
|
}
|
750
758
|
if (!this.formio) {
|
@@ -1116,7 +1124,7 @@ export default class Webform extends NestedDataComponent {
|
|
1116
1124
|
// Mark any components as invalid if in a custom message.
|
1117
1125
|
const componentErrors = {};
|
1118
1126
|
errors.forEach((err) => {
|
1119
|
-
const path = err.path || err.context?.path || err.component?.key;
|
1127
|
+
const path = getStringFromComponentPath(err.path) || err.context?.path || err.component?.key;
|
1120
1128
|
if (!componentErrors[path]) {
|
1121
1129
|
componentErrors[path] = [];
|
1122
1130
|
}
|
@@ -3,7 +3,7 @@ import Component from './components/_classes/component/Component';
|
|
3
3
|
import tippy from 'tippy.js';
|
4
4
|
import Components from './components/Components';
|
5
5
|
import { Formio } from './Formio';
|
6
|
-
import { fastCloneDeep, bootstrapVersion, getArrayFromComponentPath, getStringFromComponentPath, eachComponent, getComponent, } from './utils';
|
6
|
+
import { fastCloneDeep, bootstrapVersion, getArrayFromComponentPath, getStringFromComponentPath, eachComponent, getComponent, componentInfo } from './utils';
|
7
7
|
import BuilderUtils from './utils/builder';
|
8
8
|
import _ from 'lodash';
|
9
9
|
import autoScroll from 'dom-autoscroller';
|
@@ -63,8 +63,16 @@ export default class WebformBuilder extends Component {
|
|
63
63
|
}
|
64
64
|
this.groupOrder = this.groupOrder
|
65
65
|
.filter(group => group && !group.ignore)
|
66
|
-
.sort((a, b) => a.weight - b.weight)
|
67
|
-
|
66
|
+
.sort((a, b) => a.weight - b.weight);
|
67
|
+
const defaultOpenedGroup = this.groupOrder.find(x => x.key !== 'basic' && x.default);
|
68
|
+
if (defaultOpenedGroup) {
|
69
|
+
this.groupOrder.forEach(x => {
|
70
|
+
if ('default' in x && x.key !== defaultOpenedGroup.key) {
|
71
|
+
x.default = false;
|
72
|
+
}
|
73
|
+
});
|
74
|
+
}
|
75
|
+
this.groupOrder = this.groupOrder.map(group => group.key);
|
68
76
|
for (const type in Components.components) {
|
69
77
|
const component = Components.components[type];
|
70
78
|
if (component.builderInfo && component.builderInfo.schema) {
|
@@ -1084,7 +1092,7 @@ export default class WebformBuilder extends Component {
|
|
1084
1092
|
const newComp = parentComponent.addComponent(defaultValueComponent.component, defaultValueComponent.data, sibling);
|
1085
1093
|
_.pull(newComp.validators, 'required');
|
1086
1094
|
parentComponent.tabs[tabIndex].splice(index, 1, newComp);
|
1087
|
-
newComp.
|
1095
|
+
newComp.processOwnValidation = true;
|
1088
1096
|
newComp.build(defaultValueComponent.element);
|
1089
1097
|
if (this.preview && !this.preview.defaultChanged) {
|
1090
1098
|
const defaultValue = _.get(this.preview._data, this.editForm._data.key);
|
@@ -1115,15 +1123,18 @@ export default class WebformBuilder extends Component {
|
|
1115
1123
|
const keys = new Map();
|
1116
1124
|
eachComponent(this.form.components, (comp, path, components, parent, paths) => {
|
1117
1125
|
const isRadioCheckbox = comp.type === 'checkbox' && comp.inputType === 'radio';
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1126
|
+
const isLayout = componentInfo(comp).layout;
|
1127
|
+
if (!isLayout) {
|
1128
|
+
if (keys.has(paths.dataPath)) {
|
1129
|
+
const onlyRadioCheckboxes = repeatablePaths[paths.dataPath]?.onlyRadioCheckboxes === false ? false : isRadioCheckbox;
|
1130
|
+
repeatablePaths[paths.dataPath] = {
|
1131
|
+
comps: [...(repeatablePaths[paths.dataPath]?.comps || []), keys.get(paths.dataPath), comp],
|
1132
|
+
onlyRadioCheckboxes,
|
1133
|
+
};
|
1134
|
+
}
|
1135
|
+
else {
|
1136
|
+
keys.set(paths.dataPath, comp);
|
1137
|
+
}
|
1127
1138
|
}
|
1128
1139
|
}, true);
|
1129
1140
|
const componentsWithRepeatablePaths = [];
|
@@ -1143,6 +1154,9 @@ export default class WebformBuilder extends Component {
|
|
1143
1154
|
comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
|
1144
1155
|
hasInvalidComponents = true;
|
1145
1156
|
}
|
1157
|
+
else {
|
1158
|
+
comp.setCustomValidity();
|
1159
|
+
}
|
1146
1160
|
});
|
1147
1161
|
this.emit('builderFormValidityChange', hasInvalidComponents);
|
1148
1162
|
}
|
@@ -1261,7 +1275,8 @@ export default class WebformBuilder extends Component {
|
|
1261
1275
|
helplinks: this.helplinks,
|
1262
1276
|
}));
|
1263
1277
|
this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
|
1264
|
-
this.
|
1278
|
+
const editFormData = this.editForm.submission?.data;
|
1279
|
+
this.updateComponent(editFormData?.componentJson || editFormData || component);
|
1265
1280
|
this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
|
1266
1281
|
});
|
1267
1282
|
});
|
@@ -1648,7 +1663,7 @@ export default class WebformBuilder extends Component {
|
|
1648
1663
|
}
|
1649
1664
|
hasEditTabs(type) {
|
1650
1665
|
// If the component type does not exist then it has no edit tabs
|
1651
|
-
if (!Components.components[type]) {
|
1666
|
+
if (!Components.components[type === 'custom' ? 'unknown' : type]) {
|
1652
1667
|
return false;
|
1653
1668
|
}
|
1654
1669
|
const editTabs = getComponent(Components.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
|
package/lib/mjs/Wizard.d.ts
CHANGED
@@ -6,7 +6,6 @@ declare class Wizard extends Webform {
|
|
6
6
|
originalComponents: any[];
|
7
7
|
page: number;
|
8
8
|
currentPanel: any;
|
9
|
-
currentPanels: any[] | null;
|
10
9
|
currentNextPage: number;
|
11
10
|
_seenPages: number[];
|
12
11
|
subWizards: any[];
|
@@ -17,7 +16,7 @@ declare class Wizard extends Webform {
|
|
17
16
|
originalOptions: any;
|
18
17
|
isLastPage(): any;
|
19
18
|
getPages(args?: {}): any[];
|
20
|
-
get
|
19
|
+
get hasSubWizards(): boolean;
|
21
20
|
get localData(): any;
|
22
21
|
get wizardKey(): string;
|
23
22
|
set wizard(form: object);
|
package/lib/mjs/Wizard.js
CHANGED
@@ -29,7 +29,6 @@ export default class Wizard extends Webform {
|
|
29
29
|
this.originalComponents = [];
|
30
30
|
this.page = 0;
|
31
31
|
this.currentPanel = null;
|
32
|
-
this.currentPanels = null;
|
33
32
|
this.currentNextPage = 0;
|
34
33
|
this._seenPages = [0];
|
35
34
|
this.subWizards = [];
|
@@ -48,12 +47,12 @@ export default class Wizard extends Webform {
|
|
48
47
|
}
|
49
48
|
getPages(args = {}) {
|
50
49
|
const { all = false } = args;
|
51
|
-
const pages = this.
|
50
|
+
const pages = this.hasSubWizards ? this.components : this.pages;
|
52
51
|
const filteredPages = pages
|
53
52
|
.filter(all ? _.identity : (p, index) => this._seenPages.includes(index));
|
54
53
|
return filteredPages;
|
55
54
|
}
|
56
|
-
get
|
55
|
+
get hasSubWizards() {
|
57
56
|
return !_.isEmpty(this.subWizards);
|
58
57
|
}
|
59
58
|
get data() {
|
@@ -177,9 +176,9 @@ export default class Wizard extends Webform {
|
|
177
176
|
}
|
178
177
|
render() {
|
179
178
|
const ctx = this.renderContext;
|
180
|
-
if (this.component.
|
181
|
-
ctx.panels.
|
182
|
-
if (panel.
|
179
|
+
if (this.component.id) {
|
180
|
+
ctx.panels.forEach(panel => {
|
181
|
+
if (panel.id === this.component.id) {
|
183
182
|
this.currentPanel = panel;
|
184
183
|
ctx.wizardPageTooltip = this.getFormattedTooltip(panel.tooltip);
|
185
184
|
}
|
@@ -580,7 +579,7 @@ export default class Wizard extends Webform {
|
|
580
579
|
this.pageFieldLogic(num);
|
581
580
|
this.getNextPage();
|
582
581
|
let parentNum = num;
|
583
|
-
if (this.
|
582
|
+
if (this.hasSubWizards) {
|
584
583
|
const pageFromPages = this.pages[num];
|
585
584
|
const pageFromComponents = this.components[num];
|
586
585
|
if (!pageFromComponents || pageFromPages?.id !== pageFromComponents.id) {
|
@@ -811,6 +810,11 @@ export default class Wizard extends Webform {
|
|
811
810
|
}
|
812
811
|
}
|
813
812
|
setValue(submission, flags = {}, ignoreEstablishment) {
|
813
|
+
if (!submission || !submission.data) {
|
814
|
+
submission = {
|
815
|
+
data: {},
|
816
|
+
};
|
817
|
+
}
|
814
818
|
const changed = this.getPages({ all: true }).reduce((changed, page) => {
|
815
819
|
return this.setNestedValue(page, submission.data, flags, changed) || changed;
|
816
820
|
}, false);
|
@@ -869,23 +873,18 @@ export default class Wizard extends Webform {
|
|
869
873
|
this.showErrors(errors, true, true);
|
870
874
|
}
|
871
875
|
// If the pages change, need to redraw the header.
|
872
|
-
|
873
|
-
|
876
|
+
const currentPanels = this.pages;
|
877
|
+
// calling this.establishPages() updates/mutates this.pages to be the current pages
|
878
|
+
this.establishPages();
|
879
|
+
const newPanels = this.pages;
|
874
880
|
const currentNextPage = this.currentNextPage;
|
875
|
-
|
876
|
-
|
877
|
-
this.
|
878
|
-
|
879
|
-
|
880
|
-
else {
|
881
|
-
currentPanels = this.currentPanels || this.pages.map(page => page.component.key);
|
882
|
-
panels = this.establishPages().map(panel => panel.key);
|
883
|
-
this.currentPanels = panels;
|
884
|
-
if (this.currentPanel?.key && this.currentPanels?.length) {
|
885
|
-
this.setPage(this.currentPanels.findIndex(panel => panel === this.currentPanel.key));
|
886
|
-
}
|
881
|
+
const panelsUpdated = !_.isEqual(newPanels, currentPanels);
|
882
|
+
if (this.currentPanel?.id && this.pages.length && (!this.hasSubWizards || (this.hasSubWizards && panelsUpdated))) {
|
883
|
+
const newIndex = this.pages.findIndex(page => page.id === this.currentPanel.id);
|
884
|
+
if (newIndex !== -1)
|
885
|
+
this.setPage(newIndex);
|
887
886
|
}
|
888
|
-
if (
|
887
|
+
if (panelsUpdated || (flags && flags.fromSubmission)) {
|
889
888
|
this.redrawHeader();
|
890
889
|
}
|
891
890
|
// If the next page changes, then make sure to redraw navigation.
|
@@ -54,7 +54,7 @@ export default class Components {
|
|
54
54
|
// eslint-disable-next-line new-cap
|
55
55
|
comp = new Components.components['datagrid'](component, options, data);
|
56
56
|
}
|
57
|
-
else if (component.tree) {
|
57
|
+
else if (component.tree || (component.input && Array.isArray(component.components))) {
|
58
58
|
// eslint-disable-next-line new-cap
|
59
59
|
comp = new Components.components['nesteddata'](component, options, data);
|
60
60
|
}
|
@@ -165,10 +165,16 @@ declare class Component extends Element {
|
|
165
165
|
get componentsMap(): object;
|
166
166
|
/**
|
167
167
|
* Returns if the parent should conditionally clear.
|
168
|
+
*
|
168
169
|
* @returns {boolean} - If the parent should conditionally clear.
|
169
170
|
*/
|
170
171
|
parentShouldConditionallyClear(): boolean;
|
171
172
|
parentConditionallyHidden(): boolean;
|
173
|
+
/**
|
174
|
+
* Returns true if any of the parents default their component "hidden" property to true.
|
175
|
+
* @returns {boolean} - If any parent defaults the hidden property to true.
|
176
|
+
*/
|
177
|
+
anyParentDefaultsHidden(): boolean;
|
172
178
|
set data(value: any);
|
173
179
|
get data(): any;
|
174
180
|
mergeSchema(component?: {}): any;
|
@@ -232,8 +238,23 @@ declare class Component extends Element {
|
|
232
238
|
get visible(): boolean;
|
233
239
|
get logicallyHidden(): any;
|
234
240
|
_logicallyHidden: any;
|
235
|
-
|
236
|
-
|
241
|
+
/**
|
242
|
+
* Determines if the component should clear its value when the root form is pristine.
|
243
|
+
* @returns {boolean} - If the component should clear its value when the root form is pristine.
|
244
|
+
*/
|
245
|
+
shouldConditionallyClearOnPristine(): boolean;
|
246
|
+
/**
|
247
|
+
* Returns if the component should clear its value when conditionally hidden.
|
248
|
+
* @returns {boolean} - If the component should clear its value when conditionally hidden.
|
249
|
+
*/
|
250
|
+
shouldConditionallyClear(): boolean;
|
251
|
+
_conditionallyClear: boolean | undefined;
|
252
|
+
/**
|
253
|
+
* Returns if the component is conditionally hidden.
|
254
|
+
* @returns {boolean} - If the component is conditionally hidden.
|
255
|
+
*/
|
256
|
+
conditionallyHidden(): boolean;
|
257
|
+
_conditionallyHidden: boolean | undefined;
|
237
258
|
set currentForm(instance: any);
|
238
259
|
get currentForm(): any;
|
239
260
|
_currentForm: any;
|
@@ -420,12 +420,14 @@ export default class Component extends Element {
|
|
420
420
|
}
|
421
421
|
/**
|
422
422
|
* Returns if the parent should conditionally clear.
|
423
|
+
*
|
423
424
|
* @returns {boolean} - If the parent should conditionally clear.
|
424
425
|
*/
|
425
426
|
parentShouldConditionallyClear() {
|
426
427
|
let currentParent = this.parent;
|
427
428
|
while (currentParent) {
|
428
|
-
if (currentParent.
|
429
|
+
if ((currentParent.allowData && currentParent._conditionallyClear) ||
|
430
|
+
(!currentParent.allowData && currentParent._conditionallyHidden)) {
|
429
431
|
return true;
|
430
432
|
}
|
431
433
|
currentParent = currentParent.parent;
|
@@ -435,7 +437,21 @@ export default class Component extends Element {
|
|
435
437
|
parentConditionallyHidden() {
|
436
438
|
let currentParent = this.parent;
|
437
439
|
while (currentParent) {
|
438
|
-
if (currentParent.
|
440
|
+
if (currentParent._conditionallyHidden) {
|
441
|
+
return true;
|
442
|
+
}
|
443
|
+
currentParent = currentParent.parent;
|
444
|
+
}
|
445
|
+
return false;
|
446
|
+
}
|
447
|
+
/**
|
448
|
+
* Returns true if any of the parents default their component "hidden" property to true.
|
449
|
+
* @returns {boolean} - If any parent defaults the hidden property to true.
|
450
|
+
*/
|
451
|
+
anyParentDefaultsHidden() {
|
452
|
+
let currentParent = this.parent;
|
453
|
+
while (currentParent) {
|
454
|
+
if (currentParent.component.hidden) {
|
439
455
|
return true;
|
440
456
|
}
|
441
457
|
currentParent = currentParent.parent;
|
@@ -650,48 +666,58 @@ export default class Component extends Element {
|
|
650
666
|
}
|
651
667
|
return this._logicallyHidden;
|
652
668
|
}
|
653
|
-
|
669
|
+
/**
|
670
|
+
* Determines if the component should clear its value when the root form is pristine.
|
671
|
+
* @returns {boolean} - If the component should clear its value when the root form is pristine.
|
672
|
+
*/
|
673
|
+
shouldConditionallyClearOnPristine() {
|
674
|
+
// If the form is pristine, we should NOT clear the value of a conditionally hidden child component
|
675
|
+
// of a layout component that defaults to hidden using the "hidden" component property.
|
676
|
+
return !this.anyParentDefaultsHidden();
|
677
|
+
}
|
678
|
+
/**
|
679
|
+
* Returns if the component should clear its value when conditionally hidden.
|
680
|
+
* @returns {boolean} - If the component should clear its value when conditionally hidden.
|
681
|
+
*/
|
682
|
+
shouldConditionallyClear() {
|
654
683
|
// Skip if this component has clearOnHide set to false.
|
655
684
|
if (this.component.clearOnHide === false) {
|
656
|
-
|
685
|
+
this._conditionallyClear = false;
|
686
|
+
return this._conditionallyClear;
|
657
687
|
}
|
658
688
|
// If the component is logically hidden, then it is conditionally hidden and should clear.
|
659
689
|
if (this.logicallyHidden) {
|
660
|
-
|
690
|
+
this._conditionallyClear = true;
|
691
|
+
return this._conditionallyClear;
|
661
692
|
}
|
662
693
|
// If we have a condition and it is not conditionally visible, the it should conditionally clear.
|
663
|
-
if (this.hasCondition() &&
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
return false;
|
669
|
-
}
|
670
|
-
// If this component has a set value, then it should ONLY clear if a parent is hidden
|
671
|
-
// and has the clearOnHide set to true.
|
672
|
-
if (this.hasSetValue) {
|
673
|
-
return this.parentShouldConditionallyClear();
|
694
|
+
if (this.hasCondition() &&
|
695
|
+
!this.conditionallyVisible() &&
|
696
|
+
(!this.rootPristine || this.shouldConditionallyClearOnPristine())) {
|
697
|
+
this._conditionallyClear = true;
|
698
|
+
return this._conditionallyClear;
|
674
699
|
}
|
675
|
-
|
676
|
-
return this.
|
700
|
+
this._conditionallyClear = this.hasSetValue ? false : this.parentShouldConditionallyClear();
|
701
|
+
return this._conditionallyClear;
|
677
702
|
}
|
678
|
-
|
703
|
+
/**
|
704
|
+
* Returns if the component is conditionally hidden.
|
705
|
+
* @returns {boolean} - If the component is conditionally hidden.
|
706
|
+
*/
|
707
|
+
conditionallyHidden() {
|
708
|
+
// If it is logically hidden, then it is conditionally hidden.
|
679
709
|
if (this.logicallyHidden) {
|
680
|
-
|
710
|
+
this._conditionallyHidden = true;
|
711
|
+
return this._conditionallyHidden;
|
681
712
|
}
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
if (!this.conditionallyVisible()) {
|
687
|
-
return true;
|
688
|
-
}
|
689
|
-
if (skipParent) {
|
690
|
-
// Stop recurrsion for the parent checks.
|
691
|
-
return false;
|
713
|
+
// If it has a condition, and is not conditionally visible, then it is conditionally hidden.
|
714
|
+
if (this.hasCondition() && !this.conditionallyVisible()) {
|
715
|
+
this._conditionallyHidden = true;
|
716
|
+
return this._conditionallyHidden;
|
692
717
|
}
|
693
|
-
//
|
694
|
-
|
718
|
+
// It is conditionally hidden if its parent is conditionally hidden.
|
719
|
+
this._conditionallyHidden = this.parentConditionallyHidden();
|
720
|
+
return this._conditionallyHidden;
|
695
721
|
}
|
696
722
|
get currentForm() {
|
697
723
|
return this._currentForm;
|
@@ -3162,6 +3188,9 @@ export default class Component extends Element {
|
|
3162
3188
|
data = data || this.rootValue;
|
3163
3189
|
flags = flags || {};
|
3164
3190
|
row = row || this.data;
|
3191
|
+
if (flags.noCheck) {
|
3192
|
+
return true;
|
3193
|
+
}
|
3165
3194
|
// Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
|
3166
3195
|
// as setValue. Historically, this was bypassed by a series of cached states around the data model
|
3167
3196
|
// which caused its own problems. We need to ensure that premium and custom components do not fall into
|
@@ -3176,9 +3205,6 @@ export default class Component extends Element {
|
|
3176
3205
|
if (!flags.fromBlur) {
|
3177
3206
|
this.checkRefreshOn(flags.changes, flags);
|
3178
3207
|
}
|
3179
|
-
if (flags.noCheck) {
|
3180
|
-
return true;
|
3181
|
-
}
|
3182
3208
|
this.checkComponentConditions(data, flags, row);
|
3183
3209
|
if (this.id !== flags.triggeredComponentId) {
|
3184
3210
|
this.calculateComponentValue(data, flags, row);
|
@@ -560,6 +560,9 @@ export default class NestedComponent extends Field {
|
|
560
560
|
if (this.componentsMap[component.path]) {
|
561
561
|
delete this.componentsMap[component.path];
|
562
562
|
}
|
563
|
+
if (this.root?.componentsMap[component.path]) {
|
564
|
+
delete this.root?.componentsMap[component.path];
|
565
|
+
}
|
563
566
|
}
|
564
567
|
/**
|
565
568
|
* Removes a component provided the API key of that component.
|
@@ -667,7 +670,7 @@ export default class NestedComponent extends Field {
|
|
667
670
|
}
|
668
671
|
validationProcessor({ scope, data, row, instance, paths }, flags) {
|
669
672
|
const { dirty } = flags;
|
670
|
-
if (this.root.
|
673
|
+
if (this.root && this.root.hasSubWizards && this.page !== this.root.page) {
|
671
674
|
instance = this.componentsMap?.hasOwnProperty(paths.dataPath)
|
672
675
|
? this.componentsMap[paths.dataPath]
|
673
676
|
: this.getComponent(paths.dataPath);
|
@@ -816,7 +819,7 @@ export default class NestedComponent extends Field {
|
|
816
819
|
return false;
|
817
820
|
}
|
818
821
|
if (component.type === 'components') {
|
819
|
-
if (component.tree && component.hasValue(value)) {
|
822
|
+
if ((component.tree || component.hasInput) && component.hasValue(value)) {
|
820
823
|
return component.setValue(_.get(value, component.key), flags);
|
821
824
|
}
|
822
825
|
return component.setValue(value, flags);
|
@@ -831,9 +834,6 @@ export default class NestedComponent extends Field {
|
|
831
834
|
}
|
832
835
|
}
|
833
836
|
setValue(value, flags = {}) {
|
834
|
-
if (!value) {
|
835
|
-
return false;
|
836
|
-
}
|
837
837
|
// If the value is equal to the empty value, then this means we need to reset the values.
|
838
838
|
if (_.isEqual(value, this.emptyValue)) {
|
839
839
|
// TO-DO: For a future major release, we need to investigate removing the need for the
|
@@ -477,7 +477,13 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
477
477
|
const formComp = getComponent(this.component.components, changed.component.key);
|
478
478
|
_.set(formComp, 'components', changed.component.components);
|
479
479
|
}
|
480
|
-
|
480
|
+
// If we're in a nested form we need to ensure our changes are triggered upstream
|
481
|
+
if (changed.instance.root?.id && (this.root?.id !== changed.instance.root.id)) {
|
482
|
+
changed.instance.root.triggerChange(flags, changed, modified);
|
483
|
+
}
|
484
|
+
else {
|
485
|
+
this.triggerChange({ modified });
|
486
|
+
}
|
481
487
|
};
|
482
488
|
let columnComponent;
|
483
489
|
if (this.builderMode) {
|
@@ -33,7 +33,7 @@ export default class FileComponent extends Field {
|
|
33
33
|
get dataReady(): Promise<any>;
|
34
34
|
loadImage(fileInfo: any): any;
|
35
35
|
get emptyValue(): never[];
|
36
|
-
getValueAsString(value: any): any;
|
36
|
+
getValueAsString(value: any, options: any): any;
|
37
37
|
get defaultValue(): any[];
|
38
38
|
get hasTypes(): any;
|
39
39
|
_fileBrowseHidden: any;
|
@@ -103,7 +103,12 @@ export default class FileComponent extends Field {
|
|
103
103
|
get emptyValue() {
|
104
104
|
return [];
|
105
105
|
}
|
106
|
-
getValueAsString(value) {
|
106
|
+
getValueAsString(value, options) {
|
107
|
+
if (options?.review && !this.component.uploadOnly) {
|
108
|
+
return _.map(value, (val, index) => {
|
109
|
+
return `<a href="${val.url || '#'}" target="_blank" data-path='${this.path}' data-fileindex='${index}'>${val.originalName}</a>`;
|
110
|
+
}).join(', ');
|
111
|
+
}
|
107
112
|
if (_.isArray(value)) {
|
108
113
|
return _.map(value, 'originalName').join(', ');
|
109
114
|
}
|
@@ -98,8 +98,6 @@ export default class FormComponent extends Component {
|
|
98
98
|
* @returns {void}
|
99
99
|
*/
|
100
100
|
onSetSubFormValue(submission: object | null | undefined, flags: object | null | undefined): void;
|
101
|
-
areAllComponentsEmpty(data: any): boolean;
|
102
|
-
conditionallyHidden(): boolean;
|
103
101
|
updateSubFormVisibility(): void;
|
104
102
|
/**
|
105
103
|
* Determines if this form is a Nested Wizard
|
@@ -96,6 +96,9 @@ export default class FormComponent extends Component {
|
|
96
96
|
}
|
97
97
|
return this.createSubForm();
|
98
98
|
}
|
99
|
+
shouldConditionallyClearOnPristine() {
|
100
|
+
return !this.hasSetValue && super.shouldConditionallyClearOnPristine();
|
101
|
+
}
|
99
102
|
get dataReady() {
|
100
103
|
return this.subFormReady || Promise.resolve();
|
101
104
|
}
|
@@ -289,11 +292,13 @@ export default class FormComponent extends Component {
|
|
289
292
|
}
|
290
293
|
this.subForm.attach(element);
|
291
294
|
this.valueChanged = this.hasSetValue;
|
292
|
-
if (!this.
|
293
|
-
this.
|
294
|
-
|
295
|
-
|
296
|
-
|
295
|
+
if (!this.shouldConditionallyClear()) {
|
296
|
+
if (!this.valueChanged && this.dataValue.state !== 'submitted') {
|
297
|
+
this.setDefaultValue();
|
298
|
+
}
|
299
|
+
else {
|
300
|
+
this.restoreValue();
|
301
|
+
}
|
297
302
|
}
|
298
303
|
}
|
299
304
|
if (!this.builderMode && this.component.modalEdit) {
|
@@ -409,7 +414,7 @@ export default class FormComponent extends Component {
|
|
409
414
|
this.component.components = this.subForm._form?.components;
|
410
415
|
this.component.display = this.subForm._form?.display;
|
411
416
|
this.subForm.on('change', () => {
|
412
|
-
if (this.subForm) {
|
417
|
+
if (this.subForm && !this.shouldConditionallyClear()) {
|
413
418
|
this.dataValue = this.subForm.getValue();
|
414
419
|
this.triggerChange({
|
415
420
|
noEmit: true
|
@@ -669,20 +674,7 @@ export default class FormComponent extends Component {
|
|
669
674
|
this.subForm.setValue(submission, flags);
|
670
675
|
}
|
671
676
|
isEmpty(value = this.dataValue) {
|
672
|
-
return value === null || _.isEqual(value, this.emptyValue)
|
673
|
-
}
|
674
|
-
areAllComponentsEmpty(data) {
|
675
|
-
let res = true;
|
676
|
-
if (this.subForm) {
|
677
|
-
this.subForm.everyComponent((comp) => {
|
678
|
-
const componentValue = _.get(data, comp.key);
|
679
|
-
res &= comp.isEmpty(componentValue);
|
680
|
-
});
|
681
|
-
}
|
682
|
-
else {
|
683
|
-
res = false;
|
684
|
-
}
|
685
|
-
return res;
|
677
|
+
return value === null || _.isEqual(value, this.emptyValue);
|
686
678
|
}
|
687
679
|
getValue() {
|
688
680
|
if (this.subForm) {
|
@@ -142,7 +142,7 @@ export default class RadioComponent extends ListComponent {
|
|
142
142
|
});
|
143
143
|
this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';
|
144
144
|
this.loadedOptions = [];
|
145
|
-
if (!this.visible) {
|
145
|
+
if (!this.visible || this.optionsLoaded) {
|
146
146
|
this.itemsLoadedResolve();
|
147
147
|
}
|
148
148
|
// Get the template keys for this radio component.
|
@@ -89,6 +89,7 @@ export default class SelectComponent extends ListComponent {
|
|
89
89
|
disableInfiniteScroll(): void;
|
90
90
|
set serverCount(value: any);
|
91
91
|
get serverCount(): any;
|
92
|
+
shouldResetChoicesItems(items: any): boolean;
|
92
93
|
setItems(items: any, fromSearch: any): void;
|
93
94
|
selectItems: any;
|
94
95
|
set downloadedResources(value: any);
|
@@ -126,7 +127,6 @@ export default class SelectComponent extends ListComponent {
|
|
126
127
|
get isLoadingAvailable(): any;
|
127
128
|
onScroll(): void;
|
128
129
|
attachRefreshOnBlur(): void;
|
129
|
-
addPlaceholderItem(placeholderValue: any): void;
|
130
130
|
update(): void;
|
131
131
|
addCurrentChoices(values: any, items: any, keyValue: any): any;
|
132
132
|
getValueAsString(data: any, options: any): any;
|