@formio/js 5.0.0-dev.5913.d415fcc → 5.0.0-dev.5914.76c64d9
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.form.js +579 -589
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -3
- package/dist/formio.full.js +580 -590
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -3
- package/dist/formio.js +3006 -287
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +12 -0
- package/dist/formio.utils.js +41 -51
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -3
- package/lib/cjs/Webform.d.ts +1 -1
- package/lib/cjs/Webform.js +27 -28
- package/lib/cjs/WebformBuilder.js +21 -18
- package/lib/cjs/Wizard.d.ts +2 -2
- package/lib/cjs/Wizard.js +42 -50
- package/lib/cjs/components/Components.d.ts +0 -7
- package/lib/cjs/components/Components.js +1 -33
- package/lib/cjs/components/_classes/component/Component.d.ts +24 -7
- package/lib/cjs/components/_classes/component/Component.js +47 -13
- package/lib/cjs/components/_classes/componentModal/ComponentModal.d.ts +1 -0
- package/lib/cjs/components/_classes/componentModal/ComponentModal.js +1 -0
- package/lib/cjs/components/_classes/nested/NestedComponent.d.ts +4 -19
- package/lib/cjs/components/_classes/nested/NestedComponent.js +39 -54
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -1
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +9 -46
- package/lib/cjs/components/datagrid/DataGrid.d.ts +0 -1
- package/lib/cjs/components/datagrid/DataGrid.js +1 -45
- package/lib/cjs/components/datamap/DataMap.js +1 -2
- package/lib/cjs/components/editgrid/EditGrid.js +6 -6
- package/lib/cjs/components/form/Form.d.ts +1 -3
- package/lib/cjs/components/form/Form.js +16 -24
- package/lib/cjs/components/selectboxes/SelectBoxes.js +8 -1
- package/lib/cjs/utils/conditionOperators/DateGreaterThan.js +2 -2
- package/lib/cjs/utils/conditionOperators/IsEmptyValue.d.ts +2 -2
- package/lib/cjs/utils/conditionOperators/IsEmptyValue.js +2 -2
- package/lib/cjs/utils/conditionOperators/IsEqualTo.d.ts +2 -2
- package/lib/cjs/utils/conditionOperators/IsEqualTo.js +2 -2
- package/lib/cjs/utils/formUtils.d.ts +25 -14
- package/lib/cjs/utils/formUtils.js +11 -16
- package/lib/cjs/utils/utils.d.ts +1 -2
- package/lib/cjs/utils/utils.js +15 -31
- package/lib/mjs/Webform.d.ts +1 -1
- package/lib/mjs/Webform.js +24 -27
- package/lib/mjs/WebformBuilder.js +21 -18
- package/lib/mjs/Wizard.d.ts +2 -2
- package/lib/mjs/Wizard.js +38 -45
- package/lib/mjs/components/Components.d.ts +0 -7
- package/lib/mjs/components/Components.js +1 -32
- package/lib/mjs/components/_classes/component/Component.d.ts +24 -7
- package/lib/mjs/components/_classes/component/Component.js +49 -14
- package/lib/mjs/components/_classes/componentModal/ComponentModal.d.ts +1 -0
- package/lib/mjs/components/_classes/componentModal/ComponentModal.js +1 -0
- package/lib/mjs/components/_classes/nested/NestedComponent.d.ts +4 -19
- package/lib/mjs/components/_classes/nested/NestedComponent.js +40 -55
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -1
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +8 -43
- package/lib/mjs/components/datagrid/DataGrid.d.ts +0 -1
- package/lib/mjs/components/datagrid/DataGrid.js +1 -45
- package/lib/mjs/components/datamap/DataMap.js +1 -2
- package/lib/mjs/components/editgrid/EditGrid.js +9 -6
- package/lib/mjs/components/form/Form.d.ts +1 -3
- package/lib/mjs/components/form/Form.js +17 -24
- package/lib/mjs/components/selectboxes/SelectBoxes.js +8 -1
- package/lib/mjs/utils/conditionOperators/DateGreaterThan.js +2 -2
- package/lib/mjs/utils/conditionOperators/IsEmptyValue.d.ts +2 -2
- package/lib/mjs/utils/conditionOperators/IsEmptyValue.js +2 -2
- package/lib/mjs/utils/conditionOperators/IsEqualTo.d.ts +2 -2
- package/lib/mjs/utils/conditionOperators/IsEqualTo.js +2 -2
- package/lib/mjs/utils/formUtils.d.ts +25 -14
- package/lib/mjs/utils/formUtils.js +2 -12
- package/lib/mjs/utils/utils.d.ts +1 -2
- package/lib/mjs/utils/utils.js +14 -29
- package/package.json +4 -4
package/lib/mjs/Wizard.js
CHANGED
|
@@ -29,6 +29,7 @@ export default class Wizard extends Webform {
|
|
|
29
29
|
this.originalComponents = [];
|
|
30
30
|
this.page = 0;
|
|
31
31
|
this.currentPanel = null;
|
|
32
|
+
this.currentPanels = null;
|
|
32
33
|
this.currentNextPage = 0;
|
|
33
34
|
this._seenPages = [0];
|
|
34
35
|
this.subWizards = [];
|
|
@@ -47,12 +48,12 @@ export default class Wizard extends Webform {
|
|
|
47
48
|
}
|
|
48
49
|
getPages(args = {}) {
|
|
49
50
|
const { all = false } = args;
|
|
50
|
-
const pages = this.
|
|
51
|
+
const pages = this.hasExtraPages ? this.components : this.pages;
|
|
51
52
|
const filteredPages = pages
|
|
52
53
|
.filter(all ? _.identity : (p, index) => this._seenPages.includes(index));
|
|
53
54
|
return filteredPages;
|
|
54
55
|
}
|
|
55
|
-
get
|
|
56
|
+
get hasExtraPages() {
|
|
56
57
|
return !_.isEmpty(this.subWizards);
|
|
57
58
|
}
|
|
58
59
|
get data() {
|
|
@@ -176,9 +177,9 @@ export default class Wizard extends Webform {
|
|
|
176
177
|
}
|
|
177
178
|
render() {
|
|
178
179
|
const ctx = this.renderContext;
|
|
179
|
-
if (this.component.
|
|
180
|
-
ctx.panels.
|
|
181
|
-
if (panel.
|
|
180
|
+
if (this.component.key) {
|
|
181
|
+
ctx.panels.map(panel => {
|
|
182
|
+
if (panel.key === this.component.key) {
|
|
182
183
|
this.currentPanel = panel;
|
|
183
184
|
ctx.wizardPageTooltip = this.getFormattedTooltip(panel.tooltip);
|
|
184
185
|
}
|
|
@@ -368,7 +369,7 @@ export default class Wizard extends Webform {
|
|
|
368
369
|
}
|
|
369
370
|
attachHeader() {
|
|
370
371
|
const isAllowPrevious = this.isAllowPrevious();
|
|
371
|
-
this.attachTooltips(this.refs[`${this.wizardKey}-tooltip`], this.currentPanel
|
|
372
|
+
this.attachTooltips(this.refs[`${this.wizardKey}-tooltip`], this.currentPanel?.tooltip);
|
|
372
373
|
if (this.isBreadcrumbClickable() || isAllowPrevious) {
|
|
373
374
|
this.refs[`${this.wizardKey}-link`]?.forEach((link, index) => {
|
|
374
375
|
if (!isAllowPrevious || index <= this.enabledIndex) {
|
|
@@ -579,7 +580,7 @@ export default class Wizard extends Webform {
|
|
|
579
580
|
this.pageFieldLogic(num);
|
|
580
581
|
this.getNextPage();
|
|
581
582
|
let parentNum = num;
|
|
582
|
-
if (this.
|
|
583
|
+
if (this.hasExtraPages) {
|
|
583
584
|
const pageFromPages = this.pages[num];
|
|
584
585
|
const pageFromComponents = this.components[num];
|
|
585
586
|
if (!pageFromComponents || pageFromPages?.id !== pageFromComponents.id) {
|
|
@@ -593,7 +594,10 @@ export default class Wizard extends Webform {
|
|
|
593
594
|
}
|
|
594
595
|
this.redraw().then(() => {
|
|
595
596
|
this.checkData(this.submission.data);
|
|
596
|
-
this.validateCurrentPage();
|
|
597
|
+
const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
|
|
598
|
+
if (this.alert) {
|
|
599
|
+
this.showErrors(errors, true, true);
|
|
600
|
+
}
|
|
597
601
|
});
|
|
598
602
|
return Promise.resolve();
|
|
599
603
|
}
|
|
@@ -688,9 +692,11 @@ export default class Wizard extends Webform {
|
|
|
688
692
|
});
|
|
689
693
|
});
|
|
690
694
|
}
|
|
691
|
-
// Validate the form
|
|
692
|
-
const
|
|
693
|
-
|
|
695
|
+
// Validate the form before going to the next page
|
|
696
|
+
const currentPageErrors = this.validateCurrentPage({ dirty: true });
|
|
697
|
+
const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : currentPageErrors;
|
|
698
|
+
// allow going to the next page if the current page is valid, even if there are form level errors
|
|
699
|
+
if (currentPageErrors.length === 0) {
|
|
694
700
|
this.checkData(this.submission.data);
|
|
695
701
|
return this.beforePage(true).then(() => {
|
|
696
702
|
return this.setPage(this.getNextPage()).then(() => {
|
|
@@ -705,12 +711,13 @@ export default class Wizard extends Webform {
|
|
|
705
711
|
else {
|
|
706
712
|
this.currentPage.components.forEach((comp) => comp.setPristine(false));
|
|
707
713
|
this.scrollIntoView(this.element, true);
|
|
708
|
-
return Promise.reject(
|
|
714
|
+
return Promise.reject(this.showErrors(errors, true));
|
|
709
715
|
}
|
|
710
716
|
}
|
|
711
717
|
validateCurrentPage(flags = {}) {
|
|
718
|
+
const components = this.currentPage?.components.map((component) => component.component);
|
|
712
719
|
// Accessing the parent ensures the right instance (whether it's the parent Wizard or a nested Wizard) performs its validation
|
|
713
|
-
return this.currentPage?.parent.validateComponents(
|
|
720
|
+
return this.currentPage?.parent.validateComponents(components, this.root.data, flags);
|
|
714
721
|
}
|
|
715
722
|
emitPrevPage() {
|
|
716
723
|
this.emit('prevPage', { page: this.page, submission: this.submission });
|
|
@@ -851,23 +858,29 @@ export default class Wizard extends Webform {
|
|
|
851
858
|
}
|
|
852
859
|
onChange(flags, changed, modified, changes) {
|
|
853
860
|
super.onChange(flags, changed, modified, changes);
|
|
854
|
-
|
|
861
|
+
// The onChange loop doesn't need all components for wizards
|
|
862
|
+
const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
|
|
855
863
|
if (this.alert) {
|
|
856
864
|
this.showErrors(errors, true, true);
|
|
857
865
|
}
|
|
858
866
|
// If the pages change, need to redraw the header.
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
this.establishPages();
|
|
862
|
-
const newPanels = this.pages;
|
|
867
|
+
let currentPanels;
|
|
868
|
+
let panels;
|
|
863
869
|
const currentNextPage = this.currentNextPage;
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
870
|
+
if (this.hasExtraPages) {
|
|
871
|
+
currentPanels = this.pages.map(page => page.component.key);
|
|
872
|
+
this.establishPages();
|
|
873
|
+
panels = this.pages.map(page => page.component.key);
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
currentPanels = this.currentPanels || this.pages.map(page => page.component.key);
|
|
877
|
+
panels = this.establishPages().map(panel => panel.key);
|
|
878
|
+
this.currentPanels = panels;
|
|
879
|
+
if (this.currentPanel?.key && this.currentPanels?.length) {
|
|
880
|
+
this.setPage(this.currentPanels.findIndex(panel => panel === this.currentPanel.key));
|
|
881
|
+
}
|
|
869
882
|
}
|
|
870
|
-
if (
|
|
883
|
+
if (!_.isEqual(panels, currentPanels) || (flags && flags.fromSubmission)) {
|
|
871
884
|
this.redrawHeader();
|
|
872
885
|
}
|
|
873
886
|
// If the next page changes, then make sure to redraw navigation.
|
|
@@ -878,12 +891,6 @@ export default class Wizard extends Webform {
|
|
|
878
891
|
this.redraw();
|
|
879
892
|
}
|
|
880
893
|
}
|
|
881
|
-
redraw() {
|
|
882
|
-
if (this.parent?.component?.modalEdit) {
|
|
883
|
-
return this.parent.redraw();
|
|
884
|
-
}
|
|
885
|
-
return super.redraw();
|
|
886
|
-
}
|
|
887
894
|
rebuild() {
|
|
888
895
|
const currentPage = this.page;
|
|
889
896
|
const setCurrentPage = () => this.setPage(currentPage);
|
|
@@ -900,21 +907,7 @@ export default class Wizard extends Webform {
|
|
|
900
907
|
return components.reduce((check, comp) => comp.checkValidity(data, dirty, row, currentPageOnly, childErrors) && check, true);
|
|
901
908
|
}
|
|
902
909
|
get errors() {
|
|
903
|
-
|
|
904
|
-
return this.currentPage.errors;
|
|
905
|
-
}
|
|
906
|
-
return super.errors;
|
|
907
|
-
}
|
|
908
|
-
showErrors(errors, triggerEvent) {
|
|
909
|
-
if (this.hasSubWizards) {
|
|
910
|
-
this.subWizards.forEach((subWizard) => {
|
|
911
|
-
if (Array.isArray(subWizard.errors)) {
|
|
912
|
-
errors = [...errors, ...subWizard.errors];
|
|
913
|
-
}
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
;
|
|
917
|
-
return super.showErrors(errors, triggerEvent);
|
|
910
|
+
return !this.isLastPage() && !this.submitted ? this.currentPage.errors : super.errors;
|
|
918
911
|
}
|
|
919
912
|
focusOnComponent(key) {
|
|
920
913
|
const component = this.getComponent(key);
|
|
@@ -256,13 +256,6 @@ export default class Components {
|
|
|
256
256
|
static setComponents(comps: any): void;
|
|
257
257
|
static addComponent(name: any, comp: any): void;
|
|
258
258
|
static setComponent(name: any, comp: any): void;
|
|
259
|
-
/**
|
|
260
|
-
* Return a path of component's value.
|
|
261
|
-
* @param {Component} component - The component instance.
|
|
262
|
-
* @returns {string} - The component's value path.
|
|
263
|
-
*/
|
|
264
|
-
static getComponentPath(component: Component): string;
|
|
265
259
|
static create(component: any, options: any, data: any): any;
|
|
266
260
|
}
|
|
267
261
|
import BaseEditForm from './_classes/component/Component.form';
|
|
268
|
-
import Component from './_classes/component/Component';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Component from './_classes/component/Component';
|
|
2
2
|
import EditFormUtils from './_classes/component/editForm/utils';
|
|
3
3
|
import BaseEditForm from './_classes/component/Component.form';
|
|
4
|
-
import { getComponentKey, getModelType } from '../utils/utils';
|
|
5
4
|
import _ from 'lodash';
|
|
6
5
|
export default class Components {
|
|
7
6
|
static _editFormUtils = EditFormUtils;
|
|
@@ -46,34 +45,6 @@ export default class Components {
|
|
|
46
45
|
static setComponent(name, comp) {
|
|
47
46
|
Components.components[name] = comp;
|
|
48
47
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Return a path of component's value.
|
|
51
|
-
* @param {Component} component - The component instance.
|
|
52
|
-
* @returns {string} - The component's value path.
|
|
53
|
-
*/
|
|
54
|
-
static getComponentPath(component) {
|
|
55
|
-
let path = '';
|
|
56
|
-
const componentKey = getComponentKey(component.component);
|
|
57
|
-
if (componentKey) {
|
|
58
|
-
let thisPath = component.options?.parent || component;
|
|
59
|
-
while (thisPath && !thisPath.allowData && thisPath.parent) {
|
|
60
|
-
thisPath = thisPath.parent;
|
|
61
|
-
}
|
|
62
|
-
// TODO: any component that is nested in e.g. a Data Grid or an Edit Grid is going to receive a row prop; the problem
|
|
63
|
-
// is that options.row is passed to each further nested component, which results in erroneous paths like
|
|
64
|
-
// `editGrid[0].container[0].textField` rather than `editGrid[0].container.textField`. This should be adapted for other
|
|
65
|
-
// components with a tree-like data model
|
|
66
|
-
const rowIndex = component.row;
|
|
67
|
-
const rowIndexPath = rowIndex && !['container'].includes(thisPath.component.type) ? `[${Number.parseInt(rowIndex)}]` : '';
|
|
68
|
-
path = `${thisPath.path}${rowIndexPath}.`;
|
|
69
|
-
if (rowIndexPath && getModelType(thisPath) === 'nestedDataArray') {
|
|
70
|
-
path = `${path}data.`;
|
|
71
|
-
}
|
|
72
|
-
path += componentKey;
|
|
73
|
-
return _.trim(path, '.');
|
|
74
|
-
}
|
|
75
|
-
return path;
|
|
76
|
-
}
|
|
77
48
|
static create(component, options, data) {
|
|
78
49
|
let comp = null;
|
|
79
50
|
if (component.type && Components.components.hasOwnProperty(component.type)) {
|
|
@@ -98,9 +69,7 @@ export default class Components {
|
|
|
98
69
|
else {
|
|
99
70
|
comp = new Component(component, options, data);
|
|
100
71
|
}
|
|
101
|
-
|
|
102
|
-
if (path) {
|
|
103
|
-
comp.path = path;
|
|
72
|
+
if (comp.path) {
|
|
104
73
|
comp.componentsMap[comp.path] = comp;
|
|
105
74
|
}
|
|
106
75
|
return comp;
|
|
@@ -42,14 +42,13 @@ declare class Component extends Element {
|
|
|
42
42
|
*/
|
|
43
43
|
private _hasCondition;
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* The row index for this component.
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
_rowIndex: number | undefined;
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @type {string}
|
|
49
|
+
* References to dom elements
|
|
51
50
|
*/
|
|
52
|
-
|
|
51
|
+
refs: {};
|
|
53
52
|
/**
|
|
54
53
|
* An array of all the children components errors.
|
|
55
54
|
*/
|
|
@@ -114,6 +113,11 @@ declare class Component extends Element {
|
|
|
114
113
|
* @type {Component}
|
|
115
114
|
*/
|
|
116
115
|
parent: Component;
|
|
116
|
+
/**
|
|
117
|
+
* The component paths for this component.
|
|
118
|
+
* @type {import('@formio/core').ComponentPaths} - The component paths.
|
|
119
|
+
*/
|
|
120
|
+
paths: import('@formio/core').ComponentPaths;
|
|
117
121
|
_path: string;
|
|
118
122
|
/**
|
|
119
123
|
* Determines if this component is visible, or not.
|
|
@@ -158,7 +162,7 @@ declare class Component extends Element {
|
|
|
158
162
|
* @type {*}
|
|
159
163
|
*/
|
|
160
164
|
info: any;
|
|
161
|
-
get componentsMap():
|
|
165
|
+
get componentsMap(): object;
|
|
162
166
|
set data(value: any);
|
|
163
167
|
get data(): any;
|
|
164
168
|
mergeSchema(component?: {}): any;
|
|
@@ -182,6 +186,17 @@ declare class Component extends Element {
|
|
|
182
186
|
* @returns {boolean} - TRUE if the component is disabled.
|
|
183
187
|
*/
|
|
184
188
|
get disabled(): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Set Row Index to row and update each component.
|
|
191
|
+
* @param {number} value - The row index.
|
|
192
|
+
* @returns {void}
|
|
193
|
+
*/
|
|
194
|
+
set rowIndex(value: number);
|
|
195
|
+
/**
|
|
196
|
+
* Get Row Index.
|
|
197
|
+
* @returns {number} - The row index.
|
|
198
|
+
*/
|
|
199
|
+
get rowIndex(): number;
|
|
185
200
|
afterComponentAssign(): void;
|
|
186
201
|
createAddon(addonConfiguration: any): any;
|
|
187
202
|
get shouldDisabled(): any;
|
|
@@ -190,6 +205,8 @@ declare class Component extends Element {
|
|
|
190
205
|
get hasInput(): any;
|
|
191
206
|
get defaultSchema(): any;
|
|
192
207
|
get key(): any;
|
|
208
|
+
set path(path: string | undefined);
|
|
209
|
+
get path(): string | undefined;
|
|
193
210
|
set parentVisible(value: any);
|
|
194
211
|
get parentVisible(): any;
|
|
195
212
|
set parentDisabled(value: boolean);
|
|
@@ -212,7 +229,7 @@ declare class Component extends Element {
|
|
|
212
229
|
_currentForm: any;
|
|
213
230
|
get fullMode(): boolean;
|
|
214
231
|
get builderMode(): boolean;
|
|
215
|
-
get calculatedPath(): string;
|
|
232
|
+
get calculatedPath(): string | undefined;
|
|
216
233
|
get labelPosition(): any;
|
|
217
234
|
get labelWidth(): any;
|
|
218
235
|
get labelMargin(): any;
|
|
@@ -6,7 +6,7 @@ import isMobile from 'ismobilejs';
|
|
|
6
6
|
import { processOne, processOneSync, validateProcessInfo } from '@formio/core/process';
|
|
7
7
|
import { Formio } from '../../../Formio';
|
|
8
8
|
import * as FormioUtils from '../../../utils/utils';
|
|
9
|
-
import { fastCloneDeep, boolValue,
|
|
9
|
+
import { fastCloneDeep, boolValue, isInsideScopingComponent, currentTimezone, getScriptPlugin, getContextualRowData } from '../../../utils/utils';
|
|
10
10
|
import Element from '../../../Element';
|
|
11
11
|
import ComponentModal from '../componentModal/ComponentModal';
|
|
12
12
|
import Widgets from '../../../widgets';
|
|
@@ -221,6 +221,10 @@ export default class Component extends Element {
|
|
|
221
221
|
* @private
|
|
222
222
|
*/
|
|
223
223
|
this._hasCondition = null;
|
|
224
|
+
/**
|
|
225
|
+
* The row index for this component.
|
|
226
|
+
*/
|
|
227
|
+
this._rowIndex = undefined;
|
|
224
228
|
/**
|
|
225
229
|
* References to dom elements
|
|
226
230
|
*/
|
|
@@ -231,11 +235,6 @@ export default class Component extends Element {
|
|
|
231
235
|
this.options.components[component.type]) {
|
|
232
236
|
_.merge(component, this.options.components[component.type]);
|
|
233
237
|
}
|
|
234
|
-
/**
|
|
235
|
-
* The data path to this specific component instance.
|
|
236
|
-
* @type {string}
|
|
237
|
-
*/
|
|
238
|
-
this.path = component?.key || '';
|
|
239
238
|
/**
|
|
240
239
|
* An array of all the children components errors.
|
|
241
240
|
*/
|
|
@@ -304,6 +303,14 @@ export default class Component extends Element {
|
|
|
304
303
|
* @type {Component}
|
|
305
304
|
*/
|
|
306
305
|
this.parent = this.options.parent;
|
|
306
|
+
/**
|
|
307
|
+
* The component paths for this component.
|
|
308
|
+
* @type {import('@formio/core').ComponentPaths} - The component paths.
|
|
309
|
+
*/
|
|
310
|
+
this.paths = FormioUtils.getComponentPaths(this.component, this.parent?.component, {
|
|
311
|
+
...this.parent?.paths,
|
|
312
|
+
dataIndex: this.options.rowIndex === undefined ? this.parent?.paths?.dataIndex : this.options.rowIndex
|
|
313
|
+
});
|
|
307
314
|
this.options.name = this.options.name || 'data';
|
|
308
315
|
this._path = '';
|
|
309
316
|
// Needs for Nextgen Rules Engine
|
|
@@ -409,12 +416,7 @@ export default class Component extends Element {
|
|
|
409
416
|
}
|
|
410
417
|
/* eslint-enable max-statements */
|
|
411
418
|
get componentsMap() {
|
|
412
|
-
|
|
413
|
-
return this.localRoot.childComponentsMap;
|
|
414
|
-
}
|
|
415
|
-
const localMap = {};
|
|
416
|
-
localMap[this.path] = this;
|
|
417
|
-
return localMap;
|
|
419
|
+
return this.root?.childComponentsMap || {};
|
|
418
420
|
}
|
|
419
421
|
get data() {
|
|
420
422
|
return this._data;
|
|
@@ -460,6 +462,25 @@ export default class Component extends Element {
|
|
|
460
462
|
this.component.addons.forEach((addon) => this.createAddon(addon));
|
|
461
463
|
}
|
|
462
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Get Row Index.
|
|
467
|
+
* @returns {number} - The row index.
|
|
468
|
+
*/
|
|
469
|
+
get rowIndex() {
|
|
470
|
+
return this._rowIndex;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Set Row Index to row and update each component.
|
|
474
|
+
* @param {number} value - The row index.
|
|
475
|
+
* @returns {void}
|
|
476
|
+
*/
|
|
477
|
+
set rowIndex(value) {
|
|
478
|
+
this.paths = FormioUtils.getComponentPaths(this.component, this.parent?.component, {
|
|
479
|
+
...(this.parent?.paths || {}),
|
|
480
|
+
...{ dataIndex: value }
|
|
481
|
+
});
|
|
482
|
+
this._rowIndex = value;
|
|
483
|
+
}
|
|
463
484
|
afterComponentAssign() {
|
|
464
485
|
//implement in extended classes
|
|
465
486
|
}
|
|
@@ -528,6 +549,12 @@ export default class Component extends Element {
|
|
|
528
549
|
get key() {
|
|
529
550
|
return _.get(this.component, 'key', '');
|
|
530
551
|
}
|
|
552
|
+
get path() {
|
|
553
|
+
return this.paths.dataPath;
|
|
554
|
+
}
|
|
555
|
+
set path(path) {
|
|
556
|
+
throw new Error('Should not be setting the path of a component.');
|
|
557
|
+
}
|
|
531
558
|
set parentVisible(value) {
|
|
532
559
|
this._parentVisible = value;
|
|
533
560
|
}
|
|
@@ -1246,7 +1273,7 @@ export default class Component extends Element {
|
|
|
1246
1273
|
if (refreshData === 'data') {
|
|
1247
1274
|
this.refresh(this.data, changed, flags);
|
|
1248
1275
|
}
|
|
1249
|
-
else if ((changePath &&
|
|
1276
|
+
else if ((changePath && (changed.instance?.paths?.localPath === refreshData)) && changed && changed.instance &&
|
|
1250
1277
|
// Make sure the changed component is not in a different "context". Solves issues where refreshOn being set
|
|
1251
1278
|
// in fields inside EditGrids could alter their state from other rows (which is bad).
|
|
1252
1279
|
this.inContext(changed.instance)) {
|
|
@@ -2857,6 +2884,9 @@ export default class Component extends Element {
|
|
|
2857
2884
|
* @returns {string} - The message to show when the component is invalid.
|
|
2858
2885
|
*/
|
|
2859
2886
|
invalidMessage(data, dirty, ignoreCondition, row) {
|
|
2887
|
+
if (!row) {
|
|
2888
|
+
row = getContextualRowData(this.component, data, this.paths);
|
|
2889
|
+
}
|
|
2860
2890
|
if (!ignoreCondition && !this.checkCondition(row, data)) {
|
|
2861
2891
|
return '';
|
|
2862
2892
|
}
|
|
@@ -2874,6 +2904,8 @@ export default class Component extends Element {
|
|
|
2874
2904
|
data,
|
|
2875
2905
|
row,
|
|
2876
2906
|
path: this.path || this.component.key,
|
|
2907
|
+
parent: this.parent?.component,
|
|
2908
|
+
paths: this.paths,
|
|
2877
2909
|
scope: validationScope,
|
|
2878
2910
|
instance: this,
|
|
2879
2911
|
processors: [
|
|
@@ -2926,7 +2958,7 @@ export default class Component extends Element {
|
|
|
2926
2958
|
if (flags.silentCheck) {
|
|
2927
2959
|
return [];
|
|
2928
2960
|
}
|
|
2929
|
-
let isDirty = this.dirty || flags.dirty;
|
|
2961
|
+
let isDirty = (flags.dirty === false) ? false : (this.dirty || flags.dirty);
|
|
2930
2962
|
if (this.options.alwaysDirty) {
|
|
2931
2963
|
isDirty = true;
|
|
2932
2964
|
}
|
|
@@ -2951,7 +2983,10 @@ export default class Component extends Element {
|
|
|
2951
2983
|
component: this.component,
|
|
2952
2984
|
data,
|
|
2953
2985
|
row,
|
|
2986
|
+
local: !!flags.local,
|
|
2954
2987
|
value: this.validationValue,
|
|
2988
|
+
parent: this.parent?.component,
|
|
2989
|
+
paths: this.paths,
|
|
2955
2990
|
path: this.path || this.component.key,
|
|
2956
2991
|
instance: this,
|
|
2957
2992
|
form: this.root ? this.root._form : {},
|
|
@@ -56,18 +56,6 @@ export default class NestedComponent extends Field {
|
|
|
56
56
|
* @returns {object} - The current form object.
|
|
57
57
|
*/
|
|
58
58
|
get currentForm(): object;
|
|
59
|
-
/**
|
|
60
|
-
* Set Row Index to row and update each component.
|
|
61
|
-
* @param {number} value - The row index.
|
|
62
|
-
* @returns {void}
|
|
63
|
-
*/
|
|
64
|
-
set rowIndex(value: number);
|
|
65
|
-
/**
|
|
66
|
-
* Get Row Index.
|
|
67
|
-
* @returns {number} - The row index.
|
|
68
|
-
*/
|
|
69
|
-
get rowIndex(): number;
|
|
70
|
-
_rowIndex: number | undefined;
|
|
71
59
|
/**
|
|
72
60
|
* Get Contextual data of the component.
|
|
73
61
|
* @returns {object} - The contextual data of the component.
|
|
@@ -115,14 +103,11 @@ export default class NestedComponent extends Field {
|
|
|
115
103
|
*/
|
|
116
104
|
eachComponent(fn: Function): void;
|
|
117
105
|
/**
|
|
118
|
-
* Returns a component provided a key. This performs a deep search within the
|
|
119
|
-
* component tree.
|
|
106
|
+
* Returns a component provided a key. This performs a deep search within the component tree.
|
|
120
107
|
* @param {string} path - The path to the component.
|
|
121
|
-
* @param {Function} [fn] - Called with the component once found.
|
|
122
|
-
* @param {string} [originalPath] - The original path to the component.
|
|
123
108
|
* @returns {any} - The component that is located.
|
|
124
109
|
*/
|
|
125
|
-
getComponent(path: string
|
|
110
|
+
getComponent(path: string): any;
|
|
126
111
|
/**
|
|
127
112
|
* Return a component provided the Id of the component.
|
|
128
113
|
* @param {string} id - The Id of the component.
|
|
@@ -211,12 +196,12 @@ export default class NestedComponent extends Field {
|
|
|
211
196
|
calculateValue(data: any, flags: any, row: any): any;
|
|
212
197
|
isLastPage(): boolean;
|
|
213
198
|
isValid(data: any, dirty: any): any;
|
|
214
|
-
validationProcessor({ scope, data, row, instance,
|
|
199
|
+
validationProcessor({ scope, data, row, instance, paths }: {
|
|
215
200
|
scope: any;
|
|
216
201
|
data: any;
|
|
217
202
|
row: any;
|
|
218
203
|
instance: any;
|
|
219
|
-
|
|
204
|
+
paths: any;
|
|
220
205
|
}, flags: any): void;
|
|
221
206
|
/**
|
|
222
207
|
* Perform a validation on all child components of this nested component.
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import Field from '../field/Field';
|
|
4
4
|
import Components from '../../Components';
|
|
5
|
-
|
|
5
|
+
'';
|
|
6
|
+
import { getComponentPaths, getRandomComponentId, componentMatches, getBestMatch, getStringFromComponentPath } from '../../../utils/utils';
|
|
6
7
|
import { process as processAsync, processSync } from '@formio/core/process';
|
|
7
8
|
/**
|
|
8
9
|
* NestedComponent class.
|
|
@@ -198,6 +199,10 @@ export default class NestedComponent extends Field {
|
|
|
198
199
|
*/
|
|
199
200
|
set rowIndex(value) {
|
|
200
201
|
this._rowIndex = value;
|
|
202
|
+
this.paths = getComponentPaths(this.component, this.parent?.component, {
|
|
203
|
+
...(this.parent?.paths || {}),
|
|
204
|
+
...{ dataIndex: value }
|
|
205
|
+
});
|
|
201
206
|
this.eachComponent((component) => {
|
|
202
207
|
component.rowIndex = value;
|
|
203
208
|
});
|
|
@@ -293,56 +298,36 @@ export default class NestedComponent extends Field {
|
|
|
293
298
|
});
|
|
294
299
|
}
|
|
295
300
|
/**
|
|
296
|
-
* Returns a component provided a key. This performs a deep search within the
|
|
297
|
-
* component tree.
|
|
301
|
+
* Returns a component provided a key. This performs a deep search within the component tree.
|
|
298
302
|
* @param {string} path - The path to the component.
|
|
299
|
-
* @param {Function} [fn] - Called with the component once found.
|
|
300
|
-
* @param {string} [originalPath] - The original path to the component.
|
|
301
303
|
* @returns {any} - The component that is located.
|
|
302
304
|
*/
|
|
303
|
-
getComponent(path
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const matchPath = component.hasInput && component.path ? pathStr.includes(component.path) : true;
|
|
328
|
-
if (component.component.key === key) {
|
|
329
|
-
possibleComp = component;
|
|
330
|
-
if (matchPath) {
|
|
331
|
-
comp = component;
|
|
332
|
-
if (remainingPath.length > 0 && 'getComponent' in component) {
|
|
333
|
-
comp = component.getComponent(remainingPath, fn, originalPath);
|
|
334
|
-
}
|
|
335
|
-
else if (fn) {
|
|
336
|
-
fn(component, components);
|
|
337
|
-
}
|
|
338
|
-
return false;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
305
|
+
getComponent(path) {
|
|
306
|
+
path = getStringFromComponentPath(path);
|
|
307
|
+
const matches = {
|
|
308
|
+
path: undefined,
|
|
309
|
+
fullPath: undefined,
|
|
310
|
+
localPath: undefined,
|
|
311
|
+
fullLocalPath: undefined,
|
|
312
|
+
dataPath: undefined,
|
|
313
|
+
localDataPath: undefined,
|
|
314
|
+
key: undefined,
|
|
315
|
+
};
|
|
316
|
+
this.everyComponent((component) => {
|
|
317
|
+
// All searches are relative to this component so replace this path from the child paths.
|
|
318
|
+
componentMatches(component.component, {
|
|
319
|
+
path: component.paths?.path?.replace(new RegExp(`^${this.paths?.path}\\.?`), ''),
|
|
320
|
+
fullPath: component.paths?.fullPath?.replace(new RegExp(`^${this.paths?.fullPath}\\.?`), ''),
|
|
321
|
+
localPath: component.paths?.localPath?.replace(new RegExp(`^${this.paths?.localPath}\\.?`), ''),
|
|
322
|
+
fullLocalPath: component.paths?.fullLocalPath?.replace(new RegExp(`^${this.paths?.fullLocalPath}\\.?`), ''),
|
|
323
|
+
dataPath: component.paths?.dataPath?.replace(new RegExp(`^${this.paths?.dataPath}\\.?`), ''),
|
|
324
|
+
localDataPath: component.paths?.localDataPath?.replace(new RegExp(`^${this.paths?.localDataPath}\\.?`), ''),
|
|
325
|
+
}, path, this.rowIndex, matches, (type, match) => {
|
|
326
|
+
match.instance = component;
|
|
327
|
+
return match;
|
|
328
|
+
});
|
|
341
329
|
});
|
|
342
|
-
|
|
343
|
-
comp = possibleComp;
|
|
344
|
-
}
|
|
345
|
-
return comp;
|
|
330
|
+
return getBestMatch(matches)?.instance;
|
|
346
331
|
}
|
|
347
332
|
/**
|
|
348
333
|
* Return a component provided the Id of the component.
|
|
@@ -678,19 +663,16 @@ export default class NestedComponent extends Field {
|
|
|
678
663
|
isValid(data, dirty) {
|
|
679
664
|
return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));
|
|
680
665
|
}
|
|
681
|
-
validationProcessor({ scope, data, row, instance,
|
|
666
|
+
validationProcessor({ scope, data, row, instance, paths }, flags) {
|
|
682
667
|
const { dirty } = flags;
|
|
683
|
-
if (this.root.
|
|
684
|
-
instance = this.
|
|
685
|
-
? this.
|
|
686
|
-
: this.getComponent(
|
|
668
|
+
if (this.root.hasExtraPages && this.page !== this.root.page) {
|
|
669
|
+
instance = this.componentsMap?.hasOwnProperty(paths.dataPath)
|
|
670
|
+
? this.componentsMap[paths.dataPath]
|
|
671
|
+
: this.getComponent(paths.dataPath);
|
|
687
672
|
}
|
|
688
673
|
if (!instance) {
|
|
689
674
|
return;
|
|
690
675
|
}
|
|
691
|
-
if (!instance.component.path) {
|
|
692
|
-
instance.component.path = component.path;
|
|
693
|
-
}
|
|
694
676
|
instance.checkComponentValidity(data, dirty, row, flags, scope.errors);
|
|
695
677
|
if (instance.processOwnValidation) {
|
|
696
678
|
scope.noRecurse = true;
|
|
@@ -722,7 +704,10 @@ export default class NestedComponent extends Field {
|
|
|
722
704
|
components,
|
|
723
705
|
instances: this.componentsMap,
|
|
724
706
|
data: data,
|
|
707
|
+
local: !!flags.local,
|
|
725
708
|
scope: { errors: [] },
|
|
709
|
+
parent: this.component,
|
|
710
|
+
parentPaths: this.paths,
|
|
726
711
|
processors: [
|
|
727
712
|
{
|
|
728
713
|
process: validationProcessorProcess,
|