@formio/js 5.0.0-dev.5896.56bf2bd → 5.0.0-dev.5902.1eb1690
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 +307 -10
- package/dist/formio.form.js +602 -590
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +2 -2
- package/dist/formio.full.js +604 -592
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +2 -2
- package/dist/formio.js +3131 -209
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +14 -0
- package/dist/formio.utils.js +58 -46
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +2 -2
- package/lib/cjs/Webform.d.ts +1 -1
- package/lib/cjs/Webform.js +27 -28
- package/lib/cjs/WebformBuilder.js +26 -35
- package/lib/cjs/Wizard.d.ts +0 -1
- package/lib/cjs/Wizard.js +19 -33
- 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 +39 -7
- package/lib/cjs/components/_classes/component/Component.js +106 -37
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
- package/lib/cjs/components/_classes/component/editForm/Component.edit.validation.js +1 -1
- 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 +54 -60
- 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 +2 -3
- package/lib/cjs/components/editgrid/EditGrid.js +13 -13
- package/lib/cjs/components/form/Form.d.ts +1 -3
- package/lib/cjs/components/form/Form.js +20 -28
- package/lib/cjs/components/hidden/Hidden.d.ts +0 -1
- package/lib/cjs/components/hidden/Hidden.js +1 -1
- package/lib/cjs/components/html/HTML.js +15 -3
- package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +1 -1
- package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -0
- package/lib/cjs/components/selectboxes/SelectBoxes.js +8 -1
- package/lib/cjs/components/signature/Signature.js +3 -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/i18n.js +5 -0
- package/lib/cjs/utils/utils.d.ts +1 -2
- package/lib/cjs/utils/utils.js +19 -35
- package/lib/mjs/Webform.d.ts +1 -1
- package/lib/mjs/Webform.js +24 -27
- package/lib/mjs/WebformBuilder.js +26 -35
- package/lib/mjs/Wizard.d.ts +0 -1
- package/lib/mjs/Wizard.js +16 -29
- 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 +39 -7
- package/lib/mjs/components/_classes/component/Component.js +108 -38
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
- package/lib/mjs/components/_classes/component/editForm/Component.edit.validation.js +1 -1
- 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 +55 -61
- 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 +2 -3
- package/lib/mjs/components/editgrid/EditGrid.js +15 -12
- package/lib/mjs/components/form/Form.d.ts +1 -3
- package/lib/mjs/components/form/Form.js +21 -28
- package/lib/mjs/components/hidden/Hidden.d.ts +0 -1
- package/lib/mjs/components/hidden/Hidden.js +1 -1
- package/lib/mjs/components/html/HTML.js +15 -3
- package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +1 -1
- package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -0
- package/lib/mjs/components/selectboxes/SelectBoxes.js +8 -1
- package/lib/mjs/components/signature/Signature.js +3 -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/i18n.js +4 -0
- package/lib/mjs/utils/utils.d.ts +1 -2
- package/lib/mjs/utils/utils.js +18 -33
- package/package.json +4 -4
|
@@ -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.
|
|
@@ -80,17 +81,26 @@ export default class NestedComponent extends Field {
|
|
|
80
81
|
const visibilityChanged = this._visible !== value;
|
|
81
82
|
this._visible = value;
|
|
82
83
|
const isVisible = this.visible;
|
|
84
|
+
const isConditionallyHidden = this.checkConditionallyHidden();
|
|
83
85
|
const forceShow = this.shouldForceShow();
|
|
84
86
|
const forceHide = this.shouldForceHide();
|
|
85
|
-
this.components.forEach(component => {
|
|
87
|
+
this.components.forEach((component) => {
|
|
86
88
|
// Set the parent visibility first since we may have nested components within nested components
|
|
87
89
|
// and they need to be able to determine their visibility based on the parent visibility.
|
|
88
90
|
component.parentVisible = isVisible;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
component._parentConditionallyHidden = isConditionallyHidden;
|
|
92
|
+
let visible;
|
|
93
|
+
if (component.hasCondition()) {
|
|
94
|
+
component._conditionallyHidden = component.checkConditionallyHidden() || component._parentConditionallyHidden;
|
|
95
|
+
visible = !component.conditionallyHidden;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
visible = !component.component.hidden;
|
|
99
|
+
}
|
|
100
|
+
if (forceShow || visible) {
|
|
91
101
|
component.visible = true;
|
|
92
102
|
}
|
|
93
|
-
else if (forceHide || !isVisible || !
|
|
103
|
+
else if (forceHide || !isVisible || !visible) {
|
|
94
104
|
component.visible = false;
|
|
95
105
|
}
|
|
96
106
|
// If hiding a nested component, clear all errors below.
|
|
@@ -99,7 +109,6 @@ export default class NestedComponent extends Field {
|
|
|
99
109
|
}
|
|
100
110
|
});
|
|
101
111
|
if (visibilityChanged) {
|
|
102
|
-
this.clearOnHide();
|
|
103
112
|
this.redraw();
|
|
104
113
|
}
|
|
105
114
|
}
|
|
@@ -198,6 +207,10 @@ export default class NestedComponent extends Field {
|
|
|
198
207
|
*/
|
|
199
208
|
set rowIndex(value) {
|
|
200
209
|
this._rowIndex = value;
|
|
210
|
+
this.paths = getComponentPaths(this.component, this.parent?.component, {
|
|
211
|
+
...(this.parent?.paths || {}),
|
|
212
|
+
...{ dataIndex: value }
|
|
213
|
+
});
|
|
201
214
|
this.eachComponent((component) => {
|
|
202
215
|
component.rowIndex = value;
|
|
203
216
|
});
|
|
@@ -293,56 +306,36 @@ export default class NestedComponent extends Field {
|
|
|
293
306
|
});
|
|
294
307
|
}
|
|
295
308
|
/**
|
|
296
|
-
* Returns a component provided a key. This performs a deep search within the
|
|
297
|
-
* component tree.
|
|
309
|
+
* Returns a component provided a key. This performs a deep search within the component tree.
|
|
298
310
|
* @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
311
|
* @returns {any} - The component that is located.
|
|
302
312
|
*/
|
|
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
|
-
}
|
|
313
|
+
getComponent(path) {
|
|
314
|
+
path = getStringFromComponentPath(path);
|
|
315
|
+
const matches = {
|
|
316
|
+
path: undefined,
|
|
317
|
+
fullPath: undefined,
|
|
318
|
+
localPath: undefined,
|
|
319
|
+
fullLocalPath: undefined,
|
|
320
|
+
dataPath: undefined,
|
|
321
|
+
localDataPath: undefined,
|
|
322
|
+
key: undefined,
|
|
323
|
+
};
|
|
324
|
+
this.everyComponent((component) => {
|
|
325
|
+
// All searches are relative to this component so replace this path from the child paths.
|
|
326
|
+
componentMatches(component.component, {
|
|
327
|
+
path: component.paths?.path?.replace(new RegExp(`^${this.paths?.path}\\.?`), ''),
|
|
328
|
+
fullPath: component.paths?.fullPath?.replace(new RegExp(`^${this.paths?.fullPath}\\.?`), ''),
|
|
329
|
+
localPath: component.paths?.localPath?.replace(new RegExp(`^${this.paths?.localPath}\\.?`), ''),
|
|
330
|
+
fullLocalPath: component.paths?.fullLocalPath?.replace(new RegExp(`^${this.paths?.fullLocalPath}\\.?`), ''),
|
|
331
|
+
dataPath: component.paths?.dataPath?.replace(new RegExp(`^${this.paths?.dataPath}\\.?`), ''),
|
|
332
|
+
localDataPath: component.paths?.localDataPath?.replace(new RegExp(`^${this.paths?.localDataPath}\\.?`), ''),
|
|
333
|
+
}, path, this.rowIndex, matches, (type, match) => {
|
|
334
|
+
match.instance = component;
|
|
335
|
+
return match;
|
|
336
|
+
});
|
|
341
337
|
});
|
|
342
|
-
|
|
343
|
-
comp = possibleComp;
|
|
344
|
-
}
|
|
345
|
-
return comp;
|
|
338
|
+
return getBestMatch(matches)?.instance;
|
|
346
339
|
}
|
|
347
340
|
/**
|
|
348
341
|
* Return a component provided the Id of the component.
|
|
@@ -380,6 +373,7 @@ export default class NestedComponent extends Field {
|
|
|
380
373
|
data = data || this.data;
|
|
381
374
|
options.parent = this;
|
|
382
375
|
options.parentVisible = this.visible;
|
|
376
|
+
options.parentConditionallyHidden = this.conditionallyHidden;
|
|
383
377
|
options.root = options?.root || this.root || this;
|
|
384
378
|
options.localRoot = this.localRoot;
|
|
385
379
|
options.skipInit = true;
|
|
@@ -638,7 +632,7 @@ export default class NestedComponent extends Field {
|
|
|
638
632
|
clearOnHide(show) {
|
|
639
633
|
super.clearOnHide(show);
|
|
640
634
|
if (this.component.clearOnHide) {
|
|
641
|
-
if (this.allowData && !this.hasValue() && !
|
|
635
|
+
if (this.allowData && !this.hasValue() && !this.conditionallyHidden) {
|
|
642
636
|
this.dataValue = this.defaultValue;
|
|
643
637
|
}
|
|
644
638
|
if (this.hasValue()) {
|
|
@@ -667,7 +661,7 @@ export default class NestedComponent extends Field {
|
|
|
667
661
|
}
|
|
668
662
|
calculateValue(data, flags, row) {
|
|
669
663
|
// Do not iterate into children and calculateValues if this nested component is conditionally hidden.
|
|
670
|
-
if (
|
|
664
|
+
if (this.conditionallyHidden) {
|
|
671
665
|
return false;
|
|
672
666
|
}
|
|
673
667
|
return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));
|
|
@@ -678,19 +672,16 @@ export default class NestedComponent extends Field {
|
|
|
678
672
|
isValid(data, dirty) {
|
|
679
673
|
return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));
|
|
680
674
|
}
|
|
681
|
-
validationProcessor({ scope, data, row, instance,
|
|
675
|
+
validationProcessor({ scope, data, row, instance, paths }, flags) {
|
|
682
676
|
const { dirty } = flags;
|
|
683
677
|
if (this.root.hasExtraPages && this.page !== this.root.page) {
|
|
684
|
-
instance = this.
|
|
685
|
-
? this.
|
|
686
|
-
: this.getComponent(
|
|
678
|
+
instance = this.componentsMap?.hasOwnProperty(paths.dataPath)
|
|
679
|
+
? this.componentsMap[paths.dataPath]
|
|
680
|
+
: this.getComponent(paths.dataPath);
|
|
687
681
|
}
|
|
688
682
|
if (!instance) {
|
|
689
683
|
return;
|
|
690
684
|
}
|
|
691
|
-
if (!instance.component.path) {
|
|
692
|
-
instance.component.path = component.path;
|
|
693
|
-
}
|
|
694
685
|
instance.checkComponentValidity(data, dirty, row, flags, scope.errors);
|
|
695
686
|
if (instance.processOwnValidation) {
|
|
696
687
|
scope.noRecurse = true;
|
|
@@ -722,7 +713,10 @@ export default class NestedComponent extends Field {
|
|
|
722
713
|
components,
|
|
723
714
|
instances: this.componentsMap,
|
|
724
715
|
data: data,
|
|
716
|
+
local: !!flags.local,
|
|
725
717
|
scope: { errors: [] },
|
|
718
|
+
parent: this.component,
|
|
719
|
+
parentPaths: this.paths,
|
|
726
720
|
processors: [
|
|
727
721
|
{
|
|
728
722
|
process: validationProcessorProcess,
|
|
@@ -2,6 +2,8 @@ export default class NestedArrayComponent extends NestedDataComponent {
|
|
|
2
2
|
static savedValueTypes(): string[];
|
|
3
3
|
componentContext(component: any): any;
|
|
4
4
|
get iteratableRows(): void;
|
|
5
|
+
set rowIndex(value: number | undefined);
|
|
6
|
+
get rowIndex(): number | undefined;
|
|
5
7
|
prevHasAddButton: any;
|
|
6
8
|
checkAddButtonChanged(): void;
|
|
7
9
|
checkData(data: any, flags: any, row: any): any;
|
|
@@ -10,7 +12,6 @@ export default class NestedArrayComponent extends NestedDataComponent {
|
|
|
10
12
|
checkRow(...args: any[]): any;
|
|
11
13
|
processRow(method: any, data: any, opts: any, row: any, components: any, silentCheck: any): any;
|
|
12
14
|
hasAddButton(): any;
|
|
13
|
-
getComponent(path: any, fn: any, originalPath: any): any;
|
|
14
15
|
everyComponent(fn: any, rowIndex: any, options?: {}): void;
|
|
15
16
|
_getEmailTableHeader(options: any): string;
|
|
16
17
|
_getEmailTableBody(options: any): string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
-
import {
|
|
3
|
+
import { Utils } from '@formio/core/utils';
|
|
4
|
+
const { getComponentPaths } = Utils;
|
|
5
|
+
import { componentValueTypes, isLayoutComponent } from '../../../utils/utils';
|
|
4
6
|
import Component from '../component/Component';
|
|
5
7
|
import NestedDataComponent from '../nesteddata/NestedDataComponent';
|
|
6
8
|
export default class NestedArrayComponent extends NestedDataComponent {
|
|
@@ -19,9 +21,13 @@ export default class NestedArrayComponent extends NestedDataComponent {
|
|
|
19
21
|
throw new Error('Getter #iteratableRows() is not implemented');
|
|
20
22
|
}
|
|
21
23
|
get rowIndex() {
|
|
22
|
-
return
|
|
24
|
+
return this._rowIndex;
|
|
23
25
|
}
|
|
24
26
|
set rowIndex(value) {
|
|
27
|
+
this.paths = getComponentPaths(this.component, this.parent?.component, {
|
|
28
|
+
...(this.parent?.paths || {}),
|
|
29
|
+
...{ dataIndex: value }
|
|
30
|
+
});
|
|
25
31
|
this._rowIndex = value;
|
|
26
32
|
}
|
|
27
33
|
init() {
|
|
@@ -84,47 +90,6 @@ export default class NestedArrayComponent extends NestedDataComponent {
|
|
|
84
90
|
value: this.dataValue,
|
|
85
91
|
}, 'show'));
|
|
86
92
|
}
|
|
87
|
-
getComponent(path, fn, originalPath) {
|
|
88
|
-
originalPath = originalPath || getStringFromComponentPath(path);
|
|
89
|
-
if (this.componentsMap.hasOwnProperty(originalPath)) {
|
|
90
|
-
if (fn) {
|
|
91
|
-
return fn(this.componentsMap[originalPath]);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
return this.componentsMap[originalPath];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
path = Array.isArray(path) ? path : [path];
|
|
98
|
-
let key = path.shift();
|
|
99
|
-
const remainingPath = path;
|
|
100
|
-
let result = [];
|
|
101
|
-
let possibleComp = null;
|
|
102
|
-
let comp = null;
|
|
103
|
-
let rowIndex = null;
|
|
104
|
-
if (_.isNumber(key)) {
|
|
105
|
-
rowIndex = key;
|
|
106
|
-
key = remainingPath.shift();
|
|
107
|
-
}
|
|
108
|
-
if (!_.isString(key)) {
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
this.everyComponent((component, components) => {
|
|
112
|
-
if (component.component.key === key) {
|
|
113
|
-
possibleComp = component;
|
|
114
|
-
if (remainingPath.length > 0 && 'getComponent' in component) {
|
|
115
|
-
comp = component.getComponent(remainingPath, fn, originalPath);
|
|
116
|
-
}
|
|
117
|
-
else if (fn) {
|
|
118
|
-
fn(component, components);
|
|
119
|
-
}
|
|
120
|
-
result = rowIndex !== null ? comp : result.concat(comp || possibleComp);
|
|
121
|
-
}
|
|
122
|
-
}, rowIndex);
|
|
123
|
-
if ((!result || result.length === 0) && possibleComp) {
|
|
124
|
-
result = rowIndex !== null ? possibleComp : [possibleComp];
|
|
125
|
-
}
|
|
126
|
-
return result;
|
|
127
|
-
}
|
|
128
93
|
everyComponent(fn, rowIndex, options = {}) {
|
|
129
94
|
if (_.isObject(rowIndex)) {
|
|
130
95
|
options = rowIndex;
|
|
@@ -87,7 +87,6 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
87
87
|
show: boolean;
|
|
88
88
|
};
|
|
89
89
|
checkComponentConditions(data: any, flags: any, row: any): boolean;
|
|
90
|
-
getComponent(path: any, fn: any): any;
|
|
91
90
|
toggleGroup(element: any, index: any): void;
|
|
92
91
|
}
|
|
93
92
|
import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
|
|
3
3
|
import { fastCloneDeep, getFocusableElements } from '../../utils/utils';
|
|
4
|
-
import Components from '../Components';
|
|
5
4
|
export default class DataGridComponent extends NestedArrayComponent {
|
|
6
5
|
static schema(...extend) {
|
|
7
6
|
return NestedArrayComponent.schema({
|
|
@@ -422,7 +421,6 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
422
421
|
}
|
|
423
422
|
component.rowIndex = rowIndex;
|
|
424
423
|
component.row = `${rowIndex}-${colIndex}`;
|
|
425
|
-
component.path = Components.getComponentPath(component);
|
|
426
424
|
});
|
|
427
425
|
}
|
|
428
426
|
updateRowsComponents(rowIndex) {
|
|
@@ -488,6 +486,7 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
488
486
|
const options = _.clone(this.options);
|
|
489
487
|
options.name += `[${rowIndex}]`;
|
|
490
488
|
options.row = `${rowIndex}-${colIndex}`;
|
|
489
|
+
options.rowIndex = rowIndex;
|
|
491
490
|
let columnComponent;
|
|
492
491
|
if (this.builderMode) {
|
|
493
492
|
col.id = col.id + rowIndex;
|
|
@@ -610,49 +609,6 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
610
609
|
restoreComponentsContext() {
|
|
611
610
|
this.rows.forEach((row, index) => _.forIn(row, (component) => component.data = this.dataValue[index]));
|
|
612
611
|
}
|
|
613
|
-
getComponent(path, fn) {
|
|
614
|
-
path = Array.isArray(path) ? path : [path];
|
|
615
|
-
const [key, ...remainingPath] = path;
|
|
616
|
-
let result = [];
|
|
617
|
-
if (_.isNumber(key) && remainingPath.length) {
|
|
618
|
-
const compKey = remainingPath.pop();
|
|
619
|
-
result = this.rows[key][compKey];
|
|
620
|
-
// If the component is inside a Layout Component, try to find it among all the row's components
|
|
621
|
-
if (!result) {
|
|
622
|
-
Object.entries(this.rows[key]).forEach(([, comp]) => {
|
|
623
|
-
if ('getComponent' in comp) {
|
|
624
|
-
const possibleResult = comp.getComponent([compKey], fn);
|
|
625
|
-
if (possibleResult) {
|
|
626
|
-
result = possibleResult;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
if (result && _.isFunction(fn)) {
|
|
632
|
-
fn(result, this.getComponents());
|
|
633
|
-
}
|
|
634
|
-
if (remainingPath.length && 'getComponent' in result) {
|
|
635
|
-
return result.getComponent(remainingPath, fn);
|
|
636
|
-
}
|
|
637
|
-
return result;
|
|
638
|
-
}
|
|
639
|
-
if (!_.isString(key)) {
|
|
640
|
-
return result;
|
|
641
|
-
}
|
|
642
|
-
this.everyComponent((component, components) => {
|
|
643
|
-
if (component.component.key === key) {
|
|
644
|
-
let comp = component;
|
|
645
|
-
if (remainingPath.length > 0 && 'getComponent' in component) {
|
|
646
|
-
comp = component.getComponent(remainingPath, fn);
|
|
647
|
-
}
|
|
648
|
-
else if (fn) {
|
|
649
|
-
fn(component, components);
|
|
650
|
-
}
|
|
651
|
-
result = result.concat(comp);
|
|
652
|
-
}
|
|
653
|
-
});
|
|
654
|
-
return result.length > 0 ? result : null;
|
|
655
|
-
}
|
|
656
612
|
toggleGroup(element, index) {
|
|
657
613
|
element.classList.toggle('collapsed');
|
|
658
614
|
_.each(this.refs.chunks[index], row => {
|
|
@@ -3,7 +3,6 @@ import DataGridComponent from '../datagrid/DataGrid';
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
import EventEmitter from 'eventemitter3';
|
|
5
5
|
import { componentValueTypes, getComponentSavedTypes, uniqueKey } from '../../utils/utils';
|
|
6
|
-
import Components from '../Components';
|
|
7
6
|
export default class DataMapComponent extends DataGridComponent {
|
|
8
7
|
static schema(...extend) {
|
|
9
8
|
return Component.schema({
|
|
@@ -70,7 +69,7 @@ export default class DataMapComponent extends DataGridComponent {
|
|
|
70
69
|
}
|
|
71
70
|
get dataValue() {
|
|
72
71
|
if (!this.key ||
|
|
73
|
-
(
|
|
72
|
+
(this.conditionallyHidden && this.component.clearOnHide)) {
|
|
74
73
|
return this.emptyValue;
|
|
75
74
|
}
|
|
76
75
|
if (!this.hasValue() && this.shouldAddDefaultValue) {
|
|
@@ -227,6 +226,7 @@ export default class DataMapComponent extends DataGridComponent {
|
|
|
227
226
|
options.events = new EventEmitter();
|
|
228
227
|
options.name += `[${rowIndex}]`;
|
|
229
228
|
options.row = `${rowIndex}`;
|
|
229
|
+
options.rowIndex = rowIndex;
|
|
230
230
|
const components = {};
|
|
231
231
|
components['__key'] = this.createComponent(this.keySchema, options, { __key: this.builderMode ? this.defaultRowKey : key });
|
|
232
232
|
components['__key'].on('componentChange', (event) => {
|
|
@@ -236,7 +236,6 @@ export default class DataMapComponent extends DataGridComponent {
|
|
|
236
236
|
delete dataValue[key];
|
|
237
237
|
const comp = components[this.valueKey];
|
|
238
238
|
comp.component.key = newKey;
|
|
239
|
-
comp.path = Components.getComponentPath(comp);
|
|
240
239
|
key = newKey;
|
|
241
240
|
});
|
|
242
241
|
const valueComponent = _.clone(this.component.valueComponent);
|
|
@@ -923,6 +923,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
923
923
|
const options = _.clone(this.options);
|
|
924
924
|
options.name += `[${rowIndex}]`;
|
|
925
925
|
options.row = `${rowIndex}-${colIndex}`;
|
|
926
|
+
options.rowIndex = rowIndex;
|
|
926
927
|
options.onChange = (flags = {}, changed, modified) => {
|
|
927
928
|
if (changed.instance.root?.id && (this.root?.id !== changed.instance.root.id)) {
|
|
928
929
|
changed.instance.root.triggerChange(flags, changed, modified);
|
|
@@ -939,7 +940,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
939
940
|
...flags,
|
|
940
941
|
changed,
|
|
941
942
|
}, editRow.data, editRow.components);
|
|
942
|
-
this.validateRow(editRow, false);
|
|
943
|
+
this.validateRow(editRow, false, false);
|
|
943
944
|
}
|
|
944
945
|
if (this.variableTypeComponentsIndexes.length) {
|
|
945
946
|
this.checkRowVariableTypeComponents(editRow, rowIndex);
|
|
@@ -979,22 +980,24 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
979
980
|
validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {
|
|
980
981
|
editRow.errors = [];
|
|
981
982
|
if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {
|
|
982
|
-
const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;
|
|
983
|
+
const silentCheck = forceSilentCheck === false ? false : ((this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck);
|
|
983
984
|
const rootValue = fastCloneDeep(this.rootValue);
|
|
984
985
|
const editGridValue = _.get(rootValue, this.path, []);
|
|
985
986
|
editGridValue[editRow.rowIndex] = editRow.data;
|
|
986
987
|
_.set(rootValue, this.path, editGridValue);
|
|
987
988
|
const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });
|
|
988
989
|
const errors = processSync({
|
|
989
|
-
components:
|
|
990
|
-
component.parentPath = `${this.path}[${editRow.rowIndex}]`;
|
|
991
|
-
return component;
|
|
992
|
-
}),
|
|
990
|
+
components: this.component.components,
|
|
993
991
|
data: rootValue,
|
|
994
992
|
row: editRow.data,
|
|
995
993
|
process: 'validateRow',
|
|
996
994
|
instances: this.componentsMap,
|
|
997
995
|
scope: { errors: [] },
|
|
996
|
+
parent: this.component,
|
|
997
|
+
parentPaths: {
|
|
998
|
+
...this.paths,
|
|
999
|
+
dataIndex: editRow.rowIndex
|
|
1000
|
+
},
|
|
998
1001
|
processors: [
|
|
999
1002
|
{
|
|
1000
1003
|
process: validationProcessorProcess,
|
|
@@ -1026,9 +1029,12 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1026
1029
|
});
|
|
1027
1030
|
}
|
|
1028
1031
|
}
|
|
1029
|
-
if (!this.component.rowDrafts || this.root?.submitted) {
|
|
1032
|
+
if (editRow.alerts && (!this.component.rowDrafts || this.root?.submitted)) {
|
|
1030
1033
|
this.showRowErrorAlerts(editRow, editRow.errors);
|
|
1031
1034
|
}
|
|
1035
|
+
else if (editRow.errors?.length) {
|
|
1036
|
+
this.setCustomValidity(editRow.errors, dirty);
|
|
1037
|
+
}
|
|
1032
1038
|
return editRow.errors;
|
|
1033
1039
|
}
|
|
1034
1040
|
showRowErrorAlerts(editRow, errors) {
|
|
@@ -1139,7 +1145,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1139
1145
|
}
|
|
1140
1146
|
}
|
|
1141
1147
|
const changed = this.hasChanged(value, this.dataValue);
|
|
1142
|
-
if (this.parent
|
|
1148
|
+
if (this.parent) {
|
|
1143
1149
|
this.parent.checkComponentConditions();
|
|
1144
1150
|
}
|
|
1145
1151
|
this.dataValue = value;
|
|
@@ -1172,10 +1178,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1172
1178
|
this.editRows = this.editRows.slice(0, dataLength);
|
|
1173
1179
|
this.openWhenEmpty();
|
|
1174
1180
|
this.updateOnChange(flags, changed);
|
|
1175
|
-
|
|
1176
|
-
if (!this.options.server) {
|
|
1177
|
-
this.checkData();
|
|
1178
|
-
}
|
|
1181
|
+
this.checkData();
|
|
1179
1182
|
this.changeState(changed, flags);
|
|
1180
1183
|
return changed;
|
|
1181
1184
|
}
|
|
@@ -21,7 +21,7 @@ export default class FormComponent extends Component {
|
|
|
21
21
|
get useOriginalRevision(): any;
|
|
22
22
|
setFormRevision(rev: any): void;
|
|
23
23
|
subFormRevision: any;
|
|
24
|
-
getComponent(path: any
|
|
24
|
+
getComponent(path: any): any;
|
|
25
25
|
getSubOptions(options?: {}): {};
|
|
26
26
|
render(): string;
|
|
27
27
|
asString(value: any): any;
|
|
@@ -55,8 +55,6 @@ export default class FormComponent extends Component {
|
|
|
55
55
|
*/
|
|
56
56
|
loadSubForm(fromAttach: boolean): Promise<any>;
|
|
57
57
|
subFormLoading: boolean | undefined;
|
|
58
|
-
get subFormData(): any;
|
|
59
|
-
checkComponentValidity(data: any, dirty: any, row: any, options: any, errors?: any[]): any;
|
|
60
58
|
checkComponentConditions(data: any, flags: any, row: any): any;
|
|
61
59
|
calculateValue(data: any, flags: any, row: any): any;
|
|
62
60
|
setPristine(pristine: any): void;
|
|
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
|
|
3
3
|
import Component from '../_classes/component/Component';
|
|
4
4
|
import ComponentModal from '../_classes/componentModal/ComponentModal';
|
|
5
5
|
import EventEmitter from 'eventemitter3';
|
|
6
|
-
import { isMongoId, eachComponent,
|
|
6
|
+
import { isMongoId, eachComponent, componentValueTypes } from '../../utils/utils';
|
|
7
7
|
import { Formio } from '../../Formio';
|
|
8
8
|
import Form from '../../Form';
|
|
9
9
|
export default class FormComponent extends Component {
|
|
@@ -127,15 +127,11 @@ export default class FormComponent extends Component {
|
|
|
127
127
|
this.subFormRevision = undefined;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
getComponent(path
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
path.shift();
|
|
134
|
-
}
|
|
135
|
-
const originalPathStr = `${this.path}.data.${getStringFromComponentPath(path)}`;
|
|
136
|
-
if (this.subForm) {
|
|
137
|
-
return this.subForm.getComponent(path, fn, originalPathStr);
|
|
130
|
+
getComponent(path) {
|
|
131
|
+
if (!this.subForm) {
|
|
132
|
+
return null;
|
|
138
133
|
}
|
|
134
|
+
return this.subForm.getComponent(path);
|
|
139
135
|
}
|
|
140
136
|
/* eslint-disable max-statements */
|
|
141
137
|
getSubOptions(options = {}) {
|
|
@@ -203,6 +199,7 @@ export default class FormComponent extends Component {
|
|
|
203
199
|
if (this.options.skipDraftRestore) {
|
|
204
200
|
options.skipDraftRestore = this.options.skipDraftRestore;
|
|
205
201
|
}
|
|
202
|
+
options.parent = this;
|
|
206
203
|
return options;
|
|
207
204
|
}
|
|
208
205
|
/* eslint-enable max-statements */
|
|
@@ -294,6 +291,7 @@ export default class FormComponent extends Component {
|
|
|
294
291
|
const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
|
|
295
292
|
const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
|
|
296
293
|
this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
|
|
294
|
+
this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;
|
|
297
295
|
this.setOpenModalElement();
|
|
298
296
|
}
|
|
299
297
|
this.calculateValue();
|
|
@@ -391,6 +389,10 @@ export default class FormComponent extends Component {
|
|
|
391
389
|
return (new Form(form, this.getSubOptions())).ready.then((instance) => {
|
|
392
390
|
this.subForm = instance;
|
|
393
391
|
this.subForm.currentForm = this;
|
|
392
|
+
const componentsMap = this.componentsMap;
|
|
393
|
+
const formComponentsMap = this.subForm.componentsMap;
|
|
394
|
+
_.assign(componentsMap, formComponentsMap);
|
|
395
|
+
this.component.components = this.subForm.components.map((comp) => comp.component);
|
|
394
396
|
this.subForm.parent = this;
|
|
395
397
|
this.subForm.parentVisible = this.visible;
|
|
396
398
|
this.subForm.on('change', () => {
|
|
@@ -409,6 +411,8 @@ export default class FormComponent extends Component {
|
|
|
409
411
|
this.valueChanged = this.hasSetValue;
|
|
410
412
|
this.onChange();
|
|
411
413
|
return this.subForm;
|
|
414
|
+
}).catch((err) => {
|
|
415
|
+
console.log(err);
|
|
412
416
|
});
|
|
413
417
|
}).then((subForm) => {
|
|
414
418
|
this.updateSubWizards(subForm);
|
|
@@ -417,10 +421,10 @@ export default class FormComponent extends Component {
|
|
|
417
421
|
return this.subFormReady;
|
|
418
422
|
}
|
|
419
423
|
hideSubmitButton(component) {
|
|
420
|
-
const isSubmitButton =
|
|
421
|
-
((component.action === 'submit') || !component.action);
|
|
424
|
+
const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);
|
|
422
425
|
if (isSubmitButton) {
|
|
423
426
|
component.hidden = true;
|
|
427
|
+
component.customConditional = 'show = false';
|
|
424
428
|
}
|
|
425
429
|
}
|
|
426
430
|
/**
|
|
@@ -429,7 +433,7 @@ export default class FormComponent extends Component {
|
|
|
429
433
|
* @returns {Promise} - The promise that resolves when the subform is loaded.
|
|
430
434
|
*/
|
|
431
435
|
loadSubForm(fromAttach) {
|
|
432
|
-
if (this.builderMode || this.
|
|
436
|
+
if (this.builderMode || this.conditionallyHidden || (this.isSubFormLazyLoad() && !fromAttach)) {
|
|
433
437
|
return Promise.resolve();
|
|
434
438
|
}
|
|
435
439
|
if (this.hasLoadedForm && !this.isRevisionChanged &&
|
|
@@ -464,17 +468,6 @@ export default class FormComponent extends Component {
|
|
|
464
468
|
}
|
|
465
469
|
return Promise.resolve();
|
|
466
470
|
}
|
|
467
|
-
get subFormData() {
|
|
468
|
-
return this.dataValue?.data || {};
|
|
469
|
-
}
|
|
470
|
-
checkComponentValidity(data, dirty, row, options, errors = []) {
|
|
471
|
-
options = options || {};
|
|
472
|
-
const silentCheck = options.silentCheck || false;
|
|
473
|
-
if (this.subForm && !this.isNestedWizard) {
|
|
474
|
-
return this.subForm.checkValidity(this.subFormData, dirty, null, silentCheck, errors);
|
|
475
|
-
}
|
|
476
|
-
return super.checkComponentValidity(data, dirty, row, options, errors);
|
|
477
|
-
}
|
|
478
471
|
checkComponentConditions(data, flags, row) {
|
|
479
472
|
const visible = super.checkComponentConditions(data, flags, row);
|
|
480
473
|
// Return if already hidden
|
|
@@ -482,14 +475,14 @@ export default class FormComponent extends Component {
|
|
|
482
475
|
return visible;
|
|
483
476
|
}
|
|
484
477
|
if (this.subForm) {
|
|
485
|
-
return this.subForm.checkConditions(
|
|
478
|
+
return this.subForm.checkConditions(data, flags, row);
|
|
486
479
|
}
|
|
487
480
|
// There are few cases when subForm is not loaded when a change is triggered,
|
|
488
481
|
// so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode
|
|
489
482
|
else if (this.subFormReady) {
|
|
490
483
|
this.subFormReady.then(() => {
|
|
491
484
|
if (this.subForm) {
|
|
492
|
-
return this.subForm.checkConditions(
|
|
485
|
+
return this.subForm.checkConditions(data, flags, row);
|
|
493
486
|
}
|
|
494
487
|
});
|
|
495
488
|
}
|
|
@@ -497,7 +490,7 @@ export default class FormComponent extends Component {
|
|
|
497
490
|
}
|
|
498
491
|
calculateValue(data, flags, row) {
|
|
499
492
|
if (this.subForm) {
|
|
500
|
-
return this.subForm.calculateValue(
|
|
493
|
+
return this.subForm.calculateValue(data, flags, row);
|
|
501
494
|
}
|
|
502
495
|
return super.calculateValue(data, flags, row);
|
|
503
496
|
}
|
|
@@ -512,7 +505,7 @@ export default class FormComponent extends Component {
|
|
|
512
505
|
* @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
|
|
513
506
|
*/
|
|
514
507
|
get shouldSubmit() {
|
|
515
|
-
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.
|
|
508
|
+
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.conditionallyHidden;
|
|
516
509
|
}
|
|
517
510
|
/**
|
|
518
511
|
* Returns the data for the subform.
|
|
@@ -539,7 +532,7 @@ export default class FormComponent extends Component {
|
|
|
539
532
|
}
|
|
540
533
|
this.subForm.nosubmit = false;
|
|
541
534
|
this.subForm.submitted = true;
|
|
542
|
-
return this.subForm.submitForm().then(result => {
|
|
535
|
+
return this.subForm.submitForm({}, true).then(result => {
|
|
543
536
|
this.subForm.loading = false;
|
|
544
537
|
this.subForm.showAllErrors = false;
|
|
545
538
|
this.dataValue = result.submission;
|