@formio/js 5.0.0-dev.5932.9b8cb6d → 5.0.0-dev.5933.3445318
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 +302 -10
- package/README.md +28 -1
- package/dist/formio.form.js +585 -595
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +2 -4
- package/dist/formio.full.js +586 -596
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +2 -4
- package/dist/formio.js +3006 -287
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +13 -1
- package/dist/formio.utils.js +41 -51
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +2 -4
- package/lib/cjs/Webform.d.ts +1 -1
- package/lib/cjs/Webform.js +27 -28
- package/lib/cjs/WebformBuilder.js +6 -13
- package/lib/cjs/Wizard.js +15 -20
- 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 +97 -29
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
- 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 +5 -46
- package/lib/cjs/components/datamap/DataMap.js +2 -3
- package/lib/cjs/components/editgrid/EditGrid.d.ts +1 -1
- package/lib/cjs/components/editgrid/EditGrid.js +20 -15
- package/lib/cjs/components/form/Form.d.ts +2 -3
- package/lib/cjs/components/form/Form.js +26 -28
- package/lib/cjs/components/html/HTML.js +15 -3
- package/lib/cjs/components/number/Number.js +11 -4
- package/lib/cjs/components/selectboxes/SelectBoxes.js +0 -1
- package/lib/cjs/formio.form.js +1 -0
- 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 +6 -13
- package/lib/mjs/Wizard.js +13 -17
- 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 +99 -30
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
- 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 +5 -46
- package/lib/mjs/components/datamap/DataMap.js +2 -3
- package/lib/mjs/components/editgrid/EditGrid.d.ts +1 -1
- package/lib/mjs/components/editgrid/EditGrid.js +22 -14
- package/lib/mjs/components/form/Form.d.ts +2 -3
- package/lib/mjs/components/form/Form.js +26 -28
- package/lib/mjs/components/html/HTML.js +15 -3
- package/lib/mjs/components/number/Number.js +11 -4
- package/lib/mjs/components/selectboxes/SelectBoxes.js +0 -1
- package/lib/mjs/formio.form.js +1 -0
- 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
|
@@ -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({
|
|
@@ -409,7 +408,7 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
409
408
|
row
|
|
410
409
|
});
|
|
411
410
|
this.checkConditions();
|
|
412
|
-
this.triggerChange();
|
|
411
|
+
this.triggerChange({ modified: true });
|
|
413
412
|
this.redraw().then(() => {
|
|
414
413
|
this.focusOnNewRowElement(this.rows[index]);
|
|
415
414
|
});
|
|
@@ -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,10 @@ 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;
|
|
490
|
+
options.onChange = (flags, changed, modified) => {
|
|
491
|
+
this.triggerChange({ modified });
|
|
492
|
+
};
|
|
491
493
|
let columnComponent;
|
|
492
494
|
if (this.builderMode) {
|
|
493
495
|
col.id = col.id + rowIndex;
|
|
@@ -610,49 +612,6 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
610
612
|
restoreComponentsContext() {
|
|
611
613
|
this.rows.forEach((row, index) => _.forIn(row, (component) => component.data = this.dataValue[index]));
|
|
612
614
|
}
|
|
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
615
|
toggleGroup(element, index) {
|
|
657
616
|
element.classList.toggle('collapsed');
|
|
658
617
|
_.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);
|
|
@@ -43,7 +43,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
43
43
|
get defaultValue(): any[];
|
|
44
44
|
hasRemoveButtons(): boolean;
|
|
45
45
|
editRows: any;
|
|
46
|
-
checkRowVariableTypeComponents(editRow: any, rowIndex: any):
|
|
46
|
+
checkRowVariableTypeComponents(editRow: any, rowIndex: any): boolean;
|
|
47
47
|
setVariableTypeComponents(): void;
|
|
48
48
|
variableTypeComponentsIndexes: any[] | undefined;
|
|
49
49
|
isOpen(editRow: any): boolean;
|
|
@@ -289,12 +289,15 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
289
289
|
}
|
|
290
290
|
checkRowVariableTypeComponents(editRow, rowIndex) {
|
|
291
291
|
const rowComponents = editRow.components;
|
|
292
|
+
let typeChanged = false;
|
|
292
293
|
if (_.some(this.variableTypeComponentsIndexes, (compIndex) => {
|
|
293
294
|
const variableTypeComp = rowComponents[compIndex];
|
|
294
295
|
return variableTypeComp.type !== variableTypeComp.component.type;
|
|
295
296
|
})) {
|
|
296
297
|
editRow.components = this.createRowComponents(editRow.data, rowIndex, true);
|
|
298
|
+
typeChanged = true;
|
|
297
299
|
}
|
|
300
|
+
return typeChanged;
|
|
298
301
|
}
|
|
299
302
|
setVariableTypeComponents() {
|
|
300
303
|
//set components which type is changing within a row (e.g.,by mergeComponentSchema action)
|
|
@@ -923,6 +926,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
923
926
|
const options = _.clone(this.options);
|
|
924
927
|
options.name += `[${rowIndex}]`;
|
|
925
928
|
options.row = `${rowIndex}-${colIndex}`;
|
|
929
|
+
options.rowIndex = rowIndex;
|
|
926
930
|
options.onChange = (flags = {}, changed, modified) => {
|
|
927
931
|
if (changed.instance.root?.id && (this.root?.id !== changed.instance.root.id)) {
|
|
928
932
|
changed.instance.root.triggerChange(flags, changed, modified);
|
|
@@ -939,11 +943,13 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
939
943
|
...flags,
|
|
940
944
|
changed,
|
|
941
945
|
}, editRow.data, editRow.components);
|
|
942
|
-
this.validateRow(editRow, false);
|
|
946
|
+
this.validateRow(editRow, false, false);
|
|
943
947
|
}
|
|
944
948
|
if (this.variableTypeComponentsIndexes.length) {
|
|
945
|
-
this.checkRowVariableTypeComponents(editRow, rowIndex);
|
|
946
|
-
|
|
949
|
+
const typeChanged = this.checkRowVariableTypeComponents(editRow, rowIndex);
|
|
950
|
+
if (typeChanged) {
|
|
951
|
+
this.redraw();
|
|
952
|
+
}
|
|
947
953
|
}
|
|
948
954
|
};
|
|
949
955
|
const comp = this.createComponent(_.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);
|
|
@@ -979,22 +985,24 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
979
985
|
validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {
|
|
980
986
|
editRow.errors = [];
|
|
981
987
|
if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {
|
|
982
|
-
const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;
|
|
988
|
+
const silentCheck = forceSilentCheck === false ? false : ((this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck);
|
|
983
989
|
const rootValue = fastCloneDeep(this.rootValue);
|
|
984
990
|
const editGridValue = _.get(rootValue, this.path, []);
|
|
985
991
|
editGridValue[editRow.rowIndex] = editRow.data;
|
|
986
992
|
_.set(rootValue, this.path, editGridValue);
|
|
987
993
|
const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });
|
|
988
994
|
const errors = processSync({
|
|
989
|
-
components:
|
|
990
|
-
component.parentPath = `${this.path}[${editRow.rowIndex}]`;
|
|
991
|
-
return component;
|
|
992
|
-
}),
|
|
995
|
+
components: this.component.components,
|
|
993
996
|
data: rootValue,
|
|
994
997
|
row: editRow.data,
|
|
995
998
|
process: 'validateRow',
|
|
996
999
|
instances: this.componentsMap,
|
|
997
1000
|
scope: { errors: [] },
|
|
1001
|
+
parent: this.component,
|
|
1002
|
+
parentPaths: {
|
|
1003
|
+
...this.paths,
|
|
1004
|
+
dataIndex: editRow.rowIndex
|
|
1005
|
+
},
|
|
998
1006
|
processors: [
|
|
999
1007
|
{
|
|
1000
1008
|
process: validationProcessorProcess,
|
|
@@ -1026,9 +1034,12 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1026
1034
|
});
|
|
1027
1035
|
}
|
|
1028
1036
|
}
|
|
1029
|
-
if (!this.component.rowDrafts || this.root?.submitted) {
|
|
1037
|
+
if (editRow.alerts && (!this.component.rowDrafts || this.root?.submitted)) {
|
|
1030
1038
|
this.showRowErrorAlerts(editRow, editRow.errors);
|
|
1031
1039
|
}
|
|
1040
|
+
else if (editRow.errors?.length) {
|
|
1041
|
+
this.setCustomValidity(editRow.errors, dirty);
|
|
1042
|
+
}
|
|
1032
1043
|
return editRow.errors;
|
|
1033
1044
|
}
|
|
1034
1045
|
showRowErrorAlerts(editRow, errors) {
|
|
@@ -1139,7 +1150,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1139
1150
|
}
|
|
1140
1151
|
}
|
|
1141
1152
|
const changed = this.hasChanged(value, this.dataValue);
|
|
1142
|
-
if (this.parent
|
|
1153
|
+
if (this.parent) {
|
|
1143
1154
|
this.parent.checkComponentConditions();
|
|
1144
1155
|
}
|
|
1145
1156
|
this.dataValue = value;
|
|
@@ -1172,10 +1183,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
|
1172
1183
|
this.editRows = this.editRows.slice(0, dataLength);
|
|
1173
1184
|
this.openWhenEmpty();
|
|
1174
1185
|
this.updateOnChange(flags, changed);
|
|
1175
|
-
|
|
1176
|
-
if (!this.options.server) {
|
|
1177
|
-
this.checkData();
|
|
1178
|
-
}
|
|
1186
|
+
this.checkData();
|
|
1179
1187
|
this.changeState(changed, flags);
|
|
1180
1188
|
return changed;
|
|
1181
1189
|
}
|
|
@@ -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;
|
|
@@ -32,6 +32,7 @@ export default class FormComponent extends Component {
|
|
|
32
32
|
attach(element: any): Promise<void>;
|
|
33
33
|
get hasLoadedForm(): any;
|
|
34
34
|
get isRevisionChanged(): any;
|
|
35
|
+
get subFormData(): any;
|
|
35
36
|
subFormReady: Promise<any> | null | undefined;
|
|
36
37
|
/**
|
|
37
38
|
* Pass everyComponent to subform.
|
|
@@ -55,8 +56,6 @@ export default class FormComponent extends Component {
|
|
|
55
56
|
*/
|
|
56
57
|
loadSubForm(fromAttach: boolean): Promise<any>;
|
|
57
58
|
subFormLoading: boolean | undefined;
|
|
58
|
-
get subFormData(): any;
|
|
59
|
-
checkComponentValidity(data: any, dirty: any, row: any, options: any, errors?: any[]): any;
|
|
60
59
|
checkComponentConditions(data: any, flags: any, row: any): any;
|
|
61
60
|
calculateValue(data: any, flags: any, row: any): any;
|
|
62
61
|
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,21 +127,19 @@ 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 = {}) {
|
|
142
138
|
options.events = this.createEmitter();
|
|
143
139
|
// Make sure to not show the submit button in wizards in the nested forms.
|
|
144
140
|
_.set(options, 'buttonSettings.showSubmit', false);
|
|
141
|
+
// Set the parent option to the subform so those references are stable when the subform is created
|
|
142
|
+
options.parent = this;
|
|
145
143
|
if (!this.options) {
|
|
146
144
|
return options;
|
|
147
145
|
}
|
|
@@ -203,6 +201,7 @@ export default class FormComponent extends Component {
|
|
|
203
201
|
if (this.options.skipDraftRestore) {
|
|
204
202
|
options.skipDraftRestore = this.options.skipDraftRestore;
|
|
205
203
|
}
|
|
204
|
+
options.parent = this;
|
|
206
205
|
return options;
|
|
207
206
|
}
|
|
208
207
|
/* eslint-enable max-statements */
|
|
@@ -294,6 +293,7 @@ export default class FormComponent extends Component {
|
|
|
294
293
|
const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
|
|
295
294
|
const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
|
|
296
295
|
this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
|
|
296
|
+
this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;
|
|
297
297
|
this.setOpenModalElement();
|
|
298
298
|
}
|
|
299
299
|
this.calculateValue();
|
|
@@ -329,6 +329,9 @@ export default class FormComponent extends Component {
|
|
|
329
329
|
&& _.isNumber(this.formObj._vid)
|
|
330
330
|
&& this.formObj._vid !== this.subFormRevision;
|
|
331
331
|
}
|
|
332
|
+
get subFormData() {
|
|
333
|
+
return this.dataValue?.data || {};
|
|
334
|
+
}
|
|
332
335
|
destroy(all = false) {
|
|
333
336
|
if (this.subForm) {
|
|
334
337
|
this.subForm.destroy(all);
|
|
@@ -391,8 +394,11 @@ export default class FormComponent extends Component {
|
|
|
391
394
|
return (new Form(form, this.getSubOptions())).ready.then((instance) => {
|
|
392
395
|
this.subForm = instance;
|
|
393
396
|
this.subForm.currentForm = this;
|
|
394
|
-
this.subForm.parent = this;
|
|
395
397
|
this.subForm.parentVisible = this.visible;
|
|
398
|
+
const componentsMap = this.componentsMap;
|
|
399
|
+
const formComponentsMap = this.subForm.componentsMap;
|
|
400
|
+
_.assign(componentsMap, formComponentsMap);
|
|
401
|
+
this.component.components = this.subForm.components.map((comp) => comp.component);
|
|
396
402
|
this.subForm.on('change', () => {
|
|
397
403
|
if (this.subForm) {
|
|
398
404
|
this.dataValue = this.subForm.getValue();
|
|
@@ -409,6 +415,8 @@ export default class FormComponent extends Component {
|
|
|
409
415
|
this.valueChanged = this.hasSetValue;
|
|
410
416
|
this.onChange();
|
|
411
417
|
return this.subForm;
|
|
418
|
+
}).catch((err) => {
|
|
419
|
+
console.log(err);
|
|
412
420
|
});
|
|
413
421
|
}).then((subForm) => {
|
|
414
422
|
this.updateSubWizards(subForm);
|
|
@@ -417,10 +425,11 @@ export default class FormComponent extends Component {
|
|
|
417
425
|
return this.subFormReady;
|
|
418
426
|
}
|
|
419
427
|
hideSubmitButton(component) {
|
|
420
|
-
const isSubmitButton =
|
|
421
|
-
((component.action === 'submit') || !component.action);
|
|
428
|
+
const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);
|
|
422
429
|
if (isSubmitButton) {
|
|
423
430
|
component.hidden = true;
|
|
431
|
+
// clearOnHide no longer clears from the JSON `hidden` flag, so we make the button conditionally hidden to clear its data
|
|
432
|
+
component.customConditional = 'show = false';
|
|
424
433
|
}
|
|
425
434
|
}
|
|
426
435
|
/**
|
|
@@ -429,7 +438,7 @@ export default class FormComponent extends Component {
|
|
|
429
438
|
* @returns {Promise} - The promise that resolves when the subform is loaded.
|
|
430
439
|
*/
|
|
431
440
|
loadSubForm(fromAttach) {
|
|
432
|
-
if (this.builderMode || this.
|
|
441
|
+
if (this.builderMode || this.conditionallyHidden || (this.isSubFormLazyLoad() && !fromAttach)) {
|
|
433
442
|
return Promise.resolve();
|
|
434
443
|
}
|
|
435
444
|
if (this.hasLoadedForm && !this.isRevisionChanged &&
|
|
@@ -464,17 +473,6 @@ export default class FormComponent extends Component {
|
|
|
464
473
|
}
|
|
465
474
|
return Promise.resolve();
|
|
466
475
|
}
|
|
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) {
|
|
474
|
-
return this.subForm.checkValidity(this.subFormData, dirty, null, silentCheck, errors);
|
|
475
|
-
}
|
|
476
|
-
return super.checkComponentValidity(data, dirty, row, options, errors);
|
|
477
|
-
}
|
|
478
476
|
checkComponentConditions(data, flags, row) {
|
|
479
477
|
const visible = super.checkComponentConditions(data, flags, row);
|
|
480
478
|
// Return if already hidden
|
|
@@ -482,14 +480,14 @@ export default class FormComponent extends Component {
|
|
|
482
480
|
return visible;
|
|
483
481
|
}
|
|
484
482
|
if (this.subForm) {
|
|
485
|
-
return this.subForm.checkConditions(this.subFormData);
|
|
483
|
+
return this.subForm.checkConditions(this.subFormData, flags);
|
|
486
484
|
}
|
|
487
485
|
// There are few cases when subForm is not loaded when a change is triggered,
|
|
488
486
|
// so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode
|
|
489
487
|
else if (this.subFormReady) {
|
|
490
488
|
this.subFormReady.then(() => {
|
|
491
489
|
if (this.subForm) {
|
|
492
|
-
return this.subForm.checkConditions(this.subFormData);
|
|
490
|
+
return this.subForm.checkConditions(this.subFormData, flags);
|
|
493
491
|
}
|
|
494
492
|
});
|
|
495
493
|
}
|
|
@@ -512,7 +510,7 @@ export default class FormComponent extends Component {
|
|
|
512
510
|
* @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
|
|
513
511
|
*/
|
|
514
512
|
get shouldSubmit() {
|
|
515
|
-
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.
|
|
513
|
+
return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.conditionallyHidden;
|
|
516
514
|
}
|
|
517
515
|
/**
|
|
518
516
|
* Returns the data for the subform.
|
|
@@ -539,7 +537,7 @@ export default class FormComponent extends Component {
|
|
|
539
537
|
}
|
|
540
538
|
this.subForm.nosubmit = false;
|
|
541
539
|
this.subForm.submitted = true;
|
|
542
|
-
return this.subForm.submitForm().then(result => {
|
|
540
|
+
return this.subForm.submitForm({}, true).then(result => {
|
|
543
541
|
this.subForm.loading = false;
|
|
544
542
|
this.subForm.showAllErrors = false;
|
|
545
543
|
this.dataValue = result.submission;
|
|
@@ -51,9 +51,21 @@ export default class HTMLComponent extends Component {
|
|
|
51
51
|
}
|
|
52
52
|
checkRefreshOn(changed) {
|
|
53
53
|
super.checkRefreshOn(changed);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this.
|
|
54
|
+
let visible;
|
|
55
|
+
if (this.hasCondition()) {
|
|
56
|
+
this._conditionallyHidden = this.checkConditionallyHidden();
|
|
57
|
+
visible = !this.conditionallyHidden;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
visible = !this.component.hidden;
|
|
61
|
+
}
|
|
62
|
+
const shouldSetContent = !this.builderMode
|
|
63
|
+
&& this.component.refreshOnChange
|
|
64
|
+
&& this.element
|
|
65
|
+
&& !_.isUndefined(changed)
|
|
66
|
+
&& ((_.isBoolean(changed) && changed) || !_.isEmpty(changed))
|
|
67
|
+
&& visible;
|
|
68
|
+
if (shouldSetContent) {
|
|
57
69
|
this.setContent(this.element, this.renderContent());
|
|
58
70
|
}
|
|
59
71
|
}
|
|
@@ -168,14 +168,21 @@ export default class NumberComponent extends Input {
|
|
|
168
168
|
if (typeof input === 'string') {
|
|
169
169
|
input = input.split(this.delimiter).join('').replace(this.decimalSeparator, '.');
|
|
170
170
|
}
|
|
171
|
-
let value
|
|
172
|
-
if (!_.isNaN(
|
|
171
|
+
let value;
|
|
172
|
+
if (!_.isNaN(input)) {
|
|
173
173
|
// Format scientific notation
|
|
174
|
-
if (/
|
|
174
|
+
if (/[0-9]+[eE]/.test(String(input))) {
|
|
175
|
+
// Convert to exponential notation will depend on the decimal limit set in the component
|
|
176
|
+
// Example: 1.23e-5 will be converted to 1.23e-5 if decimal limit is set to 2
|
|
177
|
+
// Example: 1.23e5 will be converted to 1.23e+5 if decimal limit is set to 2
|
|
178
|
+
// if decimal limit is 3, 1.23e5 will be converted to 1.230e+5
|
|
179
|
+
// if decimal limit is not set, 1.23e5 will be converted to 1.23000000000000000000e+5
|
|
180
|
+
value = parseFloat(input);
|
|
175
181
|
value = value.toExponential(this.decimalLimit);
|
|
176
182
|
}
|
|
177
183
|
else {
|
|
178
|
-
value =
|
|
184
|
+
value = parseFloat(input);
|
|
185
|
+
value = !_.isNaN(value) ? String(value).replace('.', this.decimalSeparator) : null;
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
188
|
else {
|
package/lib/mjs/formio.form.js
CHANGED
|
@@ -56,6 +56,7 @@ export function registerModule(mod, defaultFn = null, options = {}) {
|
|
|
56
56
|
case 'templates':
|
|
57
57
|
for (const framework of Object.keys(mod.templates)) {
|
|
58
58
|
Formio.Templates.extendTemplate(framework, mod.templates[framework]);
|
|
59
|
+
Formio.Templates.defaultTemplates = _.defaults(mod.templates[framework], Formio.Templates.defaultTemplates);
|
|
59
60
|
}
|
|
60
61
|
if (mod.templates[current]) {
|
|
61
62
|
Formio.Templates.current = mod.templates[current];
|
|
@@ -14,13 +14,13 @@ export default class DateGeaterThan extends ConditionOperator {
|
|
|
14
14
|
return { date, comparedDate };
|
|
15
15
|
}
|
|
16
16
|
execute(options, functionName = 'isAfter') {
|
|
17
|
-
const { value, instance,
|
|
17
|
+
const { value, instance, path } = options;
|
|
18
18
|
if (!value) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
let conditionTriggerComponent = null;
|
|
22
22
|
if (instance?.root?.getComponent) {
|
|
23
|
-
conditionTriggerComponent = instance.root.getComponent(
|
|
23
|
+
conditionTriggerComponent = instance.root.getComponent(path);
|
|
24
24
|
}
|
|
25
25
|
if (conditionTriggerComponent && conditionTriggerComponent.isPartialDay && conditionTriggerComponent.isPartialDay(value)) {
|
|
26
26
|
return false;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default class IsEmptyValue extends ConditionOperator {
|
|
2
|
-
execute({ value, instance,
|
|
2
|
+
execute({ value, instance, path }: {
|
|
3
3
|
value: any;
|
|
4
4
|
instance: any;
|
|
5
|
-
|
|
5
|
+
path: any;
|
|
6
6
|
}): any;
|
|
7
7
|
getResult(options: any): any;
|
|
8
8
|
}
|
|
@@ -10,10 +10,10 @@ export default class IsEmptyValue extends ConditionOperator {
|
|
|
10
10
|
static get requireValue() {
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
|
-
execute({ value, instance,
|
|
13
|
+
execute({ value, instance, path }) {
|
|
14
14
|
const isEmptyValue = _.isEmpty(_.isNumber(value) ? String(value) : value);
|
|
15
15
|
if (instance?.root?.getComponent) {
|
|
16
|
-
const conditionTriggerComponent = instance.root.getComponent(
|
|
16
|
+
const conditionTriggerComponent = instance.root.getComponent(path);
|
|
17
17
|
return conditionTriggerComponent?.isEmpty ? conditionTriggerComponent.isEmpty() : isEmptyValue;
|
|
18
18
|
}
|
|
19
19
|
return isEmptyValue;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export default class IsEqualTo extends ConditionOperator {
|
|
2
|
-
execute({ value, comparedValue, instance,
|
|
2
|
+
execute({ value, comparedValue, instance, path }: {
|
|
3
3
|
value: any;
|
|
4
4
|
comparedValue: any;
|
|
5
5
|
instance: any;
|
|
6
|
-
|
|
6
|
+
path: any;
|
|
7
7
|
}): any;
|
|
8
8
|
}
|
|
9
9
|
import ConditionOperator from './ConditionOperator';
|
|
@@ -8,7 +8,7 @@ export default class IsEqualTo extends ConditionOperator {
|
|
|
8
8
|
static get displayedName() {
|
|
9
9
|
return 'Is Equal To';
|
|
10
10
|
}
|
|
11
|
-
execute({ value, comparedValue, instance,
|
|
11
|
+
execute({ value, comparedValue, instance, path }) {
|
|
12
12
|
if ((value || value === false) && comparedValue && typeof value !== typeof comparedValue && _.isString(comparedValue)) {
|
|
13
13
|
try {
|
|
14
14
|
comparedValue = JSON.parse(comparedValue);
|
|
@@ -17,7 +17,7 @@ export default class IsEqualTo extends ConditionOperator {
|
|
|
17
17
|
catch (e) { }
|
|
18
18
|
}
|
|
19
19
|
if (instance?.root?.getComponent) {
|
|
20
|
-
const conditionTriggerComponent = instance.root.getComponent(
|
|
20
|
+
const conditionTriggerComponent = instance.root.getComponent(path);
|
|
21
21
|
if (conditionTriggerComponent
|
|
22
22
|
&& isSelectResourceWithObjectValue(conditionTriggerComponent.component)
|
|
23
23
|
&& conditionTriggerComponent.component?.template) {
|