@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.
Files changed (94) hide show
  1. package/Changelog.md +307 -10
  2. package/dist/formio.form.js +602 -590
  3. package/dist/formio.form.min.js +1 -1
  4. package/dist/formio.form.min.js.LICENSE.txt +2 -2
  5. package/dist/formio.full.js +604 -592
  6. package/dist/formio.full.min.js +1 -1
  7. package/dist/formio.full.min.js.LICENSE.txt +2 -2
  8. package/dist/formio.js +3131 -209
  9. package/dist/formio.min.js +1 -1
  10. package/dist/formio.min.js.LICENSE.txt +14 -0
  11. package/dist/formio.utils.js +58 -46
  12. package/dist/formio.utils.min.js +1 -1
  13. package/dist/formio.utils.min.js.LICENSE.txt +2 -2
  14. package/lib/cjs/Webform.d.ts +1 -1
  15. package/lib/cjs/Webform.js +27 -28
  16. package/lib/cjs/WebformBuilder.js +26 -35
  17. package/lib/cjs/Wizard.d.ts +0 -1
  18. package/lib/cjs/Wizard.js +19 -33
  19. package/lib/cjs/components/Components.d.ts +0 -7
  20. package/lib/cjs/components/Components.js +1 -33
  21. package/lib/cjs/components/_classes/component/Component.d.ts +39 -7
  22. package/lib/cjs/components/_classes/component/Component.js +106 -37
  23. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
  24. package/lib/cjs/components/_classes/component/editForm/Component.edit.validation.js +1 -1
  25. package/lib/cjs/components/_classes/componentModal/ComponentModal.d.ts +1 -0
  26. package/lib/cjs/components/_classes/componentModal/ComponentModal.js +1 -0
  27. package/lib/cjs/components/_classes/nested/NestedComponent.d.ts +4 -19
  28. package/lib/cjs/components/_classes/nested/NestedComponent.js +54 -60
  29. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -1
  30. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +9 -46
  31. package/lib/cjs/components/datagrid/DataGrid.d.ts +0 -1
  32. package/lib/cjs/components/datagrid/DataGrid.js +1 -45
  33. package/lib/cjs/components/datamap/DataMap.js +2 -3
  34. package/lib/cjs/components/editgrid/EditGrid.js +13 -13
  35. package/lib/cjs/components/form/Form.d.ts +1 -3
  36. package/lib/cjs/components/form/Form.js +20 -28
  37. package/lib/cjs/components/hidden/Hidden.d.ts +0 -1
  38. package/lib/cjs/components/hidden/Hidden.js +1 -1
  39. package/lib/cjs/components/html/HTML.js +15 -3
  40. package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  41. package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -0
  42. package/lib/cjs/components/selectboxes/SelectBoxes.js +8 -1
  43. package/lib/cjs/components/signature/Signature.js +3 -1
  44. package/lib/cjs/utils/conditionOperators/DateGreaterThan.js +2 -2
  45. package/lib/cjs/utils/conditionOperators/IsEmptyValue.d.ts +2 -2
  46. package/lib/cjs/utils/conditionOperators/IsEmptyValue.js +2 -2
  47. package/lib/cjs/utils/conditionOperators/IsEqualTo.d.ts +2 -2
  48. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +2 -2
  49. package/lib/cjs/utils/formUtils.d.ts +25 -14
  50. package/lib/cjs/utils/formUtils.js +11 -16
  51. package/lib/cjs/utils/i18n.js +5 -0
  52. package/lib/cjs/utils/utils.d.ts +1 -2
  53. package/lib/cjs/utils/utils.js +19 -35
  54. package/lib/mjs/Webform.d.ts +1 -1
  55. package/lib/mjs/Webform.js +24 -27
  56. package/lib/mjs/WebformBuilder.js +26 -35
  57. package/lib/mjs/Wizard.d.ts +0 -1
  58. package/lib/mjs/Wizard.js +16 -29
  59. package/lib/mjs/components/Components.d.ts +0 -7
  60. package/lib/mjs/components/Components.js +1 -32
  61. package/lib/mjs/components/_classes/component/Component.d.ts +39 -7
  62. package/lib/mjs/components/_classes/component/Component.js +108 -38
  63. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +2 -2
  64. package/lib/mjs/components/_classes/component/editForm/Component.edit.validation.js +1 -1
  65. package/lib/mjs/components/_classes/componentModal/ComponentModal.d.ts +1 -0
  66. package/lib/mjs/components/_classes/componentModal/ComponentModal.js +1 -0
  67. package/lib/mjs/components/_classes/nested/NestedComponent.d.ts +4 -19
  68. package/lib/mjs/components/_classes/nested/NestedComponent.js +55 -61
  69. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -1
  70. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +8 -43
  71. package/lib/mjs/components/datagrid/DataGrid.d.ts +0 -1
  72. package/lib/mjs/components/datagrid/DataGrid.js +1 -45
  73. package/lib/mjs/components/datamap/DataMap.js +2 -3
  74. package/lib/mjs/components/editgrid/EditGrid.js +15 -12
  75. package/lib/mjs/components/form/Form.d.ts +1 -3
  76. package/lib/mjs/components/form/Form.js +21 -28
  77. package/lib/mjs/components/hidden/Hidden.d.ts +0 -1
  78. package/lib/mjs/components/hidden/Hidden.js +1 -1
  79. package/lib/mjs/components/html/HTML.js +15 -3
  80. package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  81. package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -0
  82. package/lib/mjs/components/selectboxes/SelectBoxes.js +8 -1
  83. package/lib/mjs/components/signature/Signature.js +3 -1
  84. package/lib/mjs/utils/conditionOperators/DateGreaterThan.js +2 -2
  85. package/lib/mjs/utils/conditionOperators/IsEmptyValue.d.ts +2 -2
  86. package/lib/mjs/utils/conditionOperators/IsEmptyValue.js +2 -2
  87. package/lib/mjs/utils/conditionOperators/IsEqualTo.d.ts +2 -2
  88. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +2 -2
  89. package/lib/mjs/utils/formUtils.d.ts +25 -14
  90. package/lib/mjs/utils/formUtils.js +2 -12
  91. package/lib/mjs/utils/i18n.js +4 -0
  92. package/lib/mjs/utils/utils.d.ts +1 -2
  93. package/lib/mjs/utils/utils.js +18 -33
  94. 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
- import { getArrayFromComponentPath, getStringFromComponentPath, getRandomComponentId } from '../../../utils/utils';
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
- const conditionallyVisible = component.conditionallyVisible();
90
- if (forceShow || conditionallyVisible) {
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 || !conditionallyVisible) {
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, fn, originalPath) {
304
- originalPath = originalPath || getStringFromComponentPath(path);
305
- if (this.componentsMap.hasOwnProperty(originalPath)) {
306
- if (fn) {
307
- return fn(this.componentsMap[originalPath]);
308
- }
309
- else {
310
- return this.componentsMap[originalPath];
311
- }
312
- }
313
- path = getArrayFromComponentPath(path);
314
- const pathStr = originalPath;
315
- const newPath = _.clone(path);
316
- let key = newPath.shift();
317
- const remainingPath = newPath;
318
- let comp = null;
319
- let possibleComp = null;
320
- if (_.isNumber(key)) {
321
- key = remainingPath.shift();
322
- }
323
- if (!_.isString(key)) {
324
- return comp;
325
- }
326
- this.everyComponent((component, components) => {
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
- if (!comp) {
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() && !(this.options.server && !this.visible)) {
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 (!this.conditionallyVisible()) {
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, component }, flags) {
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.childComponentsMap?.hasOwnProperty(component.path)
685
- ? this.childComponentsMap[component.path]
686
- : this.getComponent(component.path);
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 { componentValueTypes, getStringFromComponentPath, isLayoutComponent } from '../../../utils/utils';
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 super.rowIndex;
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
- (!this.visible && this.component.clearOnHide)) {
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: fastCloneDeep(this.component.components).map((component) => {
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 && !this.options.server) {
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
- // do not call checkData with server option, it is called when change is triggered in updateOnChange
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, fn: any): 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, getStringFromComponentPath, getArrayFromComponentPath, componentValueTypes } from '../../utils/utils';
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, fn) {
131
- path = getArrayFromComponentPath(path);
132
- if (path[0] === 'data') {
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 = (component.type === 'button') &&
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.isHidden() || (this.isSubFormLazyLoad() && !fromAttach)) {
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(this.subFormData);
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(this.subFormData);
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(this.subFormData, flags);
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.isHidden();
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;
@@ -10,7 +10,6 @@ export default class HiddenComponent extends Input {
10
10
  };
11
11
  get inputInfo(): any;
12
12
  labelIsHidden(): boolean;
13
- get emptyValue(): string;
14
13
  setValue(value: any, flags?: {}): boolean;
15
14
  }
16
15
  import Input from '../_classes/input/Input';