@formio/js 5.1.0-dev.6040.debc859 → 5.1.0-dev.6044.20a9acc

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.
@@ -1623,7 +1623,7 @@ class WebformBuilder extends Component_1.default {
1623
1623
  info.type);
1624
1624
  }
1625
1625
  hasEditTabs(type) {
1626
- const editTabs = (0, formUtils_1.getComponent)(Components_1.default.components[type].editForm().components, 'tabs', true).components;
1626
+ const editTabs = (0, formUtils_1.getComponent)(Components_1.default.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
1627
1627
  const hiddenEditTabs = lodash_1.default.filter(lodash_1.default.get(this.options, `editForm.${type}`, []), 'ignore');
1628
1628
  return lodash_1.default.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
1629
1629
  }
@@ -119,13 +119,6 @@ declare class Component extends Element {
119
119
  */
120
120
  paths: import('@formio/core').ComponentPaths;
121
121
  _path: string;
122
- /**
123
- * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.
124
- * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track
125
- * conditionallyHidden separately from "regular" visibility.
126
- */
127
- _parentConditionallyHidden: any;
128
- _conditionallyHidden: any;
129
122
  /**
130
123
  * Determines if this component is visible, or not.
131
124
  */
@@ -170,6 +163,7 @@ declare class Component extends Element {
170
163
  */
171
164
  info: any;
172
165
  get componentsMap(): object;
166
+ parentConditionallyHidden(): boolean;
173
167
  set data(value: any);
174
168
  get data(): any;
175
169
  mergeSchema(component?: {}): any;
@@ -231,14 +225,9 @@ declare class Component extends Element {
231
225
  * @returns {boolean} - Whether the component is visible or not.
232
226
  */
233
227
  get visible(): boolean;
234
- get conditionallyHidden(): any;
235
- /**
236
- * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).
237
- * @param {object} data - The data object to evaluate the condition against.
238
- * @param {object} row - The row object to evaluate the condition against.
239
- * @returns {boolean} - Whether the component is conditionally hidden.
240
- */
241
- checkConditionallyHidden(data?: object, row?: object): boolean;
228
+ get logicallyHidden(): any;
229
+ _logicallyHidden: any;
230
+ conditionallyHidden(skipParent?: boolean): any;
242
231
  set currentForm(instance: any);
243
232
  get currentForm(): any;
244
233
  _currentForm: any;
@@ -351,18 +351,11 @@ class Component extends Element_1.default {
351
351
  this._path = '';
352
352
  // Needs for Nextgen Rules Engine
353
353
  this.resetCaches();
354
- /**
355
- * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.
356
- * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track
357
- * conditionallyHidden separately from "regular" visibility.
358
- */
359
- this._parentConditionallyHidden = this.options.hasOwnProperty('parentConditionallyHidden') ? this.options.parentConditionallyHidden : false;
360
- this._conditionallyHidden = this.checkConditionallyHidden(null, data) || this._parentConditionallyHidden;
361
354
  /**
362
355
  * Determines if this component is visible, or not.
363
356
  */
364
357
  this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;
365
- this._visible = this._parentVisible && (this.hasCondition() ? !this._conditionallyHidden : !this.component.hidden);
358
+ this._visible = this._parentVisible && (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
366
359
  this._parentDisabled = false;
367
360
  /**
368
361
  * The reference attribute name for this component
@@ -431,7 +424,7 @@ class Component extends Element_1.default {
431
424
  if (this.allowData && this.key) {
432
425
  this.options.name += `[${this.key}]`;
433
426
  // If component is visible or not set to clear on hide, set the default value.
434
- if (!(this.conditionallyHidden && this.component.clearOnHide)) {
427
+ if (!(this.conditionallyHidden() && this.component.clearOnHide)) {
435
428
  if (!this.hasValue()) {
436
429
  if (this.shouldAddDefaultValue) {
437
430
  this.dataValue = this.defaultValue;
@@ -465,6 +458,16 @@ class Component extends Element_1.default {
465
458
  var _a;
466
459
  return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.childComponentsMap) || {};
467
460
  }
461
+ parentConditionallyHidden() {
462
+ let currentParent = this.parent;
463
+ while (currentParent) {
464
+ if (currentParent.conditionallyHidden(true)) {
465
+ return true;
466
+ }
467
+ currentParent = currentParent.parent;
468
+ }
469
+ return false;
470
+ }
468
471
  get data() {
469
472
  return this._data;
470
473
  }
@@ -505,8 +508,7 @@ class Component extends Element_1.default {
505
508
  init() {
506
509
  var _a;
507
510
  this.disabled = this.shouldDisabled;
508
- this._conditionallyHidden = this.checkConditionallyHidden();
509
- this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
511
+ this._visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
510
512
  if ((_a = this.component.addons) === null || _a === void 0 ? void 0 : _a.length) {
511
513
  this.component.addons.forEach((addon) => this.createAddon(addon));
512
514
  }
@@ -671,20 +673,17 @@ class Component extends Element_1.default {
671
673
  }
672
674
  return this._visible && this._parentVisible;
673
675
  }
674
- get conditionallyHidden() {
675
- return this._conditionallyHidden || this._parentConditionallyHidden;
676
+ get logicallyHidden() {
677
+ if (this._logicallyHidden && !this.component.hidden) {
678
+ this._logicallyHidden = false;
679
+ }
680
+ return this._logicallyHidden;
676
681
  }
677
- /**
678
- * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).
679
- * @param {object} data - The data object to evaluate the condition against.
680
- * @param {object} row - The row object to evaluate the condition against.
681
- * @returns {boolean} - Whether the component is conditionally hidden.
682
- */
683
- checkConditionallyHidden(data = null, row = null) {
682
+ conditionallyHidden(skipParent = false) {
684
683
  if (!this.hasCondition()) {
685
- return false;
684
+ return this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
686
685
  }
687
- return !this.conditionallyVisible(data, row);
686
+ return !this.conditionallyVisible() || this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
688
687
  }
689
688
  get currentForm() {
690
689
  return this._currentForm;
@@ -1852,7 +1851,7 @@ class Component extends Element_1.default {
1852
1851
  rebuild() {
1853
1852
  this.destroy();
1854
1853
  this.init();
1855
- this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
1854
+ this.visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
1856
1855
  return this.redraw();
1857
1856
  }
1858
1857
  /**
@@ -1950,23 +1949,12 @@ class Component extends Element_1.default {
1950
1949
  if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {
1951
1950
  this.redraw();
1952
1951
  }
1953
- // Check advanced conditions (and cache the result)
1954
- const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;
1955
- let shouldClear = false;
1956
- if (isConditionallyHidden !== this._conditionallyHidden) {
1957
- this._conditionallyHidden = isConditionallyHidden;
1958
- shouldClear = true;
1959
- }
1960
1952
  // Check visibility
1961
- const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
1953
+ const visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
1962
1954
  if (this.visible !== visible) {
1963
1955
  this.visible = visible;
1964
1956
  }
1965
- // Wait for visibility to update for nested components, so the component state is up-to-date when
1966
- // calling clearOnHide
1967
- if (shouldClear) {
1968
- this.clearOnHide();
1969
- }
1957
+ this.clearOnHide();
1970
1958
  return visible;
1971
1959
  }
1972
1960
  /**
@@ -2075,9 +2063,9 @@ class Component extends Element_1.default {
2075
2063
  if (!lodash_1.default.isEqual(lodash_1.default.get(this.component, property), lodash_1.default.get(newComponent, property))) {
2076
2064
  // Advanced Logic can modify the component's hidden property; because we track conditionally hidden state
2077
2065
  // separately from the component's hidden property, and technically this Advanced Logic conditionally hides
2078
- // a component, we need to set _conditionallyHidden to the new value
2066
+ // a component, we need to set a temporary variable to the new value
2079
2067
  if (property === 'hidden') {
2080
- this._conditionallyHidden = newComponent.hidden;
2068
+ this._logicallyHidden = newComponent.hidden;
2081
2069
  }
2082
2070
  changed = true;
2083
2071
  }
@@ -2092,7 +2080,7 @@ class Component extends Element_1.default {
2092
2080
  component: newComponent,
2093
2081
  result,
2094
2082
  });
2095
- if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {
2083
+ if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2096
2084
  this.setValue(newValue);
2097
2085
  if (this.viewOnly) {
2098
2086
  this.dataValue = newValue;
@@ -2125,7 +2113,7 @@ class Component extends Element_1.default {
2125
2113
  component: newComponent,
2126
2114
  result,
2127
2115
  }, 'value');
2128
- if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {
2116
+ if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2129
2117
  this.setValue(newValue);
2130
2118
  if (this.viewOnly) {
2131
2119
  this.dataValue = newValue;
@@ -2236,7 +2224,7 @@ class Component extends Element_1.default {
2236
2224
  this.component.clearOnHide !== false &&
2237
2225
  !this.options.readOnly &&
2238
2226
  !this.options.showHiddenFields) {
2239
- if (this.conditionallyHidden) {
2227
+ if (this.conditionallyHidden()) {
2240
2228
  this.deleteValue();
2241
2229
  }
2242
2230
  else if (!this.hasValue() && this.shouldAddDefaultValue) {
@@ -2494,27 +2482,17 @@ class Component extends Element_1.default {
2494
2482
  * @returns {*} - The value for this component.
2495
2483
  */
2496
2484
  get dataValue() {
2497
- if (!this.key ||
2498
- (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
2499
- return this.emptyValue;
2500
- }
2501
- if (!this.hasValue() && this.shouldAddDefaultValue) {
2502
- const empty = this.component.multiple ? [] : this.emptyValue;
2503
- if (!this.rootPristine) {
2504
- this.dataValue = empty;
2505
- }
2506
- return empty;
2485
+ if (!this.key) {
2486
+ return this.component.multiple ? [] : this.emptyValue;
2507
2487
  }
2508
- return lodash_1.default.get(this._data, this.key);
2488
+ return lodash_1.default.get(this._data, this.key, this.component.multiple ? [] : this.emptyValue);
2509
2489
  }
2510
2490
  /**
2511
2491
  * Sets the static value of this component.
2512
2492
  * @param {*} value - The value to set for this component.
2513
2493
  */
2514
2494
  set dataValue(value) {
2515
- if (!this.allowData ||
2516
- !this.key ||
2517
- (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
2495
+ if (!this.allowData || !this.key) {
2518
2496
  return;
2519
2497
  }
2520
2498
  if ((value !== null) && (value !== undefined)) {
@@ -2835,7 +2813,7 @@ class Component extends Element_1.default {
2835
2813
  // If no calculated value or
2836
2814
  // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
2837
2815
  const { clearOnHide } = this.component;
2838
- const shouldBeCleared = this.conditionallyHidden && clearOnHide;
2816
+ const shouldBeCleared = this.conditionallyHidden() && clearOnHide;
2839
2817
  const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);
2840
2818
  if (shouldBeCleared) {
2841
2819
  // remove calculated value so that the value is recalculated once component becomes visible
@@ -3485,7 +3463,7 @@ class Component extends Element_1.default {
3485
3463
  // If component definition changed, replace it.
3486
3464
  if (!lodash_1.default.isEqual(this.component, newComponent)) {
3487
3465
  this.component = newComponent;
3488
- const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
3466
+ const visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
3489
3467
  const disabled = this.shouldDisabled;
3490
3468
  // Change states which won't be recalculated during redrawing
3491
3469
  if (this.visible !== visible) {
@@ -85,18 +85,15 @@ class NestedComponent extends Field_1.default {
85
85
  const visibilityChanged = this._visible !== value;
86
86
  this._visible = value;
87
87
  const isVisible = this.visible;
88
- const isConditionallyHidden = this.checkConditionallyHidden();
89
88
  const forceShow = this.shouldForceShow();
90
89
  const forceHide = this.shouldForceHide();
91
90
  this.components.forEach((component) => {
92
91
  // Set the parent visibility first since we may have nested components within nested components
93
92
  // and they need to be able to determine their visibility based on the parent visibility.
94
93
  component.parentVisible = isVisible;
95
- component._parentConditionallyHidden = isConditionallyHidden;
96
94
  let visible;
97
95
  if (component.hasCondition()) {
98
- component._conditionallyHidden = component.checkConditionallyHidden() || component._parentConditionallyHidden;
99
- visible = !component.conditionallyHidden;
96
+ visible = !component.conditionallyHidden();
100
97
  }
101
98
  else {
102
99
  visible = !component.component.hidden;
@@ -377,7 +374,6 @@ class NestedComponent extends Field_1.default {
377
374
  data = data || this.data;
378
375
  options.parent = this;
379
376
  options.parentVisible = this.visible;
380
- options.parentConditionallyHidden = this.conditionallyHidden;
381
377
  options.root = (options === null || options === void 0 ? void 0 : options.root) || this.root || this;
382
378
  options.localRoot = this.localRoot;
383
379
  options.skipInit = true;
@@ -636,7 +632,7 @@ class NestedComponent extends Field_1.default {
636
632
  clearOnHide(show) {
637
633
  super.clearOnHide(show);
638
634
  if (this.component.clearOnHide) {
639
- if (this.allowData && !this.hasValue() && !this.conditionallyHidden) {
635
+ if (this.allowData && !this.hasValue() && !this.conditionallyHidden()) {
640
636
  this.dataValue = this.defaultValue;
641
637
  }
642
638
  if (this.hasValue()) {
@@ -665,7 +661,7 @@ class NestedComponent extends Field_1.default {
665
661
  }
666
662
  calculateValue(data, flags, row) {
667
663
  // Do not iterate into children and calculateValues if this nested component is conditionally hidden.
668
- if (this.conditionallyHidden) {
664
+ if (this.conditionallyHidden()) {
669
665
  return false;
670
666
  }
671
667
  return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));
@@ -73,14 +73,10 @@ class DataMapComponent extends DataGrid_1.default {
73
73
  return {};
74
74
  }
75
75
  get dataValue() {
76
- if (!this.key ||
77
- (this.conditionallyHidden && this.component.clearOnHide)) {
76
+ if (!this.key) {
78
77
  return this.emptyValue;
79
78
  }
80
- if (!this.hasValue() && this.shouldAddDefaultValue) {
81
- this.dataValue = this.emptyValue;
82
- }
83
- return lodash_1.default.get(this.data, this.key);
79
+ return lodash_1.default.get(this.data, this.key, this.emptyValue);
84
80
  }
85
81
  set dataValue(value) {
86
82
  super.dataValue = value;
@@ -1159,9 +1159,6 @@ class EditGridComponent extends NestedArrayComponent_1.default {
1159
1159
  }
1160
1160
  }
1161
1161
  const changed = this.hasChanged(value, this.dataValue);
1162
- if (this.parent) {
1163
- this.parent.checkComponentConditions();
1164
- }
1165
1162
  this.dataValue = value;
1166
1163
  // Refresh editRow data when data changes.
1167
1164
  this.dataValue.forEach((row, rowIndex) => {
@@ -1192,7 +1189,6 @@ class EditGridComponent extends NestedArrayComponent_1.default {
1192
1189
  this.editRows = this.editRows.slice(0, dataLength);
1193
1190
  this.openWhenEmpty();
1194
1191
  this.updateOnChange(flags, changed);
1195
- this.checkData();
1196
1192
  this.changeState(changed, flags);
1197
1193
  return changed;
1198
1194
  }
@@ -448,7 +448,7 @@ class FormComponent extends Component_1.default {
448
448
  loadSubForm(fromAttach, beforeSubmit) {
449
449
  var _a, _b, _c, _d, _e;
450
450
  const loadHiddenForm = beforeSubmit && !this.component.clearOnHide;
451
- if (this.builderMode || (this.conditionallyHidden && !loadHiddenForm) || (this.isSubFormLazyLoad() && !fromAttach)) {
451
+ if (this.builderMode || (this.conditionallyHidden() && !loadHiddenForm) || (this.isSubFormLazyLoad() && !fromAttach)) {
452
452
  return Promise.resolve();
453
453
  }
454
454
  if (this.hasLoadedForm && !this.isRevisionChanged &&
@@ -520,7 +520,7 @@ class FormComponent extends Component_1.default {
520
520
  * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
521
521
  */
522
522
  get shouldSubmit() {
523
- return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden || !this.component.clearOnHide);
523
+ return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden() || !this.component.clearOnHide);
524
524
  }
525
525
  /**
526
526
  * Returns the data for the subform.
@@ -58,8 +58,7 @@ class HTMLComponent extends Component_1.default {
58
58
  super.checkRefreshOn(changed);
59
59
  let visible;
60
60
  if (this.hasCondition()) {
61
- this._conditionallyHidden = this.checkConditionallyHidden();
62
- visible = !this.conditionallyHidden;
61
+ visible = !this.conditionallyHidden();
63
62
  }
64
63
  else {
65
64
  visible = !this.component.hidden;
@@ -365,7 +365,7 @@ class RadioComponent extends ListComponent_1.default {
365
365
  const value = this.dataValue;
366
366
  this.refs.wrapper.forEach((wrapper, index) => {
367
367
  const input = this.refs.input[index];
368
- const checked = (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());
368
+ const checked = (value === undefined || value === null) ? false : (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());
369
369
  if (checked) {
370
370
  //add class to container when selected
371
371
  this.addClass(wrapper, this.optionSelectedClass);
@@ -143,6 +143,7 @@ class TabsComponent extends NestedComponent_1.default {
143
143
  this.addClass(this.refs[this.tabLinkKey][index], 'active');
144
144
  this.addClass(this.refs[this.tabLinkKey][index], 'formio-tab-link-active');
145
145
  }
146
+ this.setValue(this.data);
146
147
  this.triggerChange();
147
148
  }
148
149
  beforeFocus(component) {
@@ -1626,7 +1626,7 @@ export default class WebformBuilder extends Component {
1626
1626
  info.type);
1627
1627
  }
1628
1628
  hasEditTabs(type) {
1629
- const editTabs = getComponent(Components.components[type].editForm().components, 'tabs', true).components;
1629
+ const editTabs = getComponent(Components.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
1630
1630
  const hiddenEditTabs = _.filter(_.get(this.options, `editForm.${type}`, []), 'ignore');
1631
1631
  return _.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
1632
1632
  }
@@ -119,13 +119,6 @@ declare class Component extends Element {
119
119
  */
120
120
  paths: import('@formio/core').ComponentPaths;
121
121
  _path: string;
122
- /**
123
- * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.
124
- * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track
125
- * conditionallyHidden separately from "regular" visibility.
126
- */
127
- _parentConditionallyHidden: any;
128
- _conditionallyHidden: any;
129
122
  /**
130
123
  * Determines if this component is visible, or not.
131
124
  */
@@ -170,6 +163,7 @@ declare class Component extends Element {
170
163
  */
171
164
  info: any;
172
165
  get componentsMap(): object;
166
+ parentConditionallyHidden(): boolean;
173
167
  set data(value: any);
174
168
  get data(): any;
175
169
  mergeSchema(component?: {}): any;
@@ -231,14 +225,9 @@ declare class Component extends Element {
231
225
  * @returns {boolean} - Whether the component is visible or not.
232
226
  */
233
227
  get visible(): boolean;
234
- get conditionallyHidden(): any;
235
- /**
236
- * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).
237
- * @param {object} data - The data object to evaluate the condition against.
238
- * @param {object} row - The row object to evaluate the condition against.
239
- * @returns {boolean} - Whether the component is conditionally hidden.
240
- */
241
- checkConditionallyHidden(data?: object, row?: object): boolean;
228
+ get logicallyHidden(): any;
229
+ _logicallyHidden: any;
230
+ conditionallyHidden(skipParent?: boolean): any;
242
231
  set currentForm(instance: any);
243
232
  get currentForm(): any;
244
233
  _currentForm: any;
@@ -316,18 +316,11 @@ export default class Component extends Element {
316
316
  this._path = '';
317
317
  // Needs for Nextgen Rules Engine
318
318
  this.resetCaches();
319
- /**
320
- * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.
321
- * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track
322
- * conditionallyHidden separately from "regular" visibility.
323
- */
324
- this._parentConditionallyHidden = this.options.hasOwnProperty('parentConditionallyHidden') ? this.options.parentConditionallyHidden : false;
325
- this._conditionallyHidden = this.checkConditionallyHidden(null, data) || this._parentConditionallyHidden;
326
319
  /**
327
320
  * Determines if this component is visible, or not.
328
321
  */
329
322
  this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;
330
- this._visible = this._parentVisible && (this.hasCondition() ? !this._conditionallyHidden : !this.component.hidden);
323
+ this._visible = this._parentVisible && (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
331
324
  this._parentDisabled = false;
332
325
  /**
333
326
  * The reference attribute name for this component
@@ -396,7 +389,7 @@ export default class Component extends Element {
396
389
  if (this.allowData && this.key) {
397
390
  this.options.name += `[${this.key}]`;
398
391
  // If component is visible or not set to clear on hide, set the default value.
399
- if (!(this.conditionallyHidden && this.component.clearOnHide)) {
392
+ if (!(this.conditionallyHidden() && this.component.clearOnHide)) {
400
393
  if (!this.hasValue()) {
401
394
  if (this.shouldAddDefaultValue) {
402
395
  this.dataValue = this.defaultValue;
@@ -429,6 +422,16 @@ export default class Component extends Element {
429
422
  get componentsMap() {
430
423
  return this.root?.childComponentsMap || {};
431
424
  }
425
+ parentConditionallyHidden() {
426
+ let currentParent = this.parent;
427
+ while (currentParent) {
428
+ if (currentParent.conditionallyHidden(true)) {
429
+ return true;
430
+ }
431
+ currentParent = currentParent.parent;
432
+ }
433
+ return false;
434
+ }
432
435
  get data() {
433
436
  return this._data;
434
437
  }
@@ -468,8 +471,7 @@ export default class Component extends Element {
468
471
  }
469
472
  init() {
470
473
  this.disabled = this.shouldDisabled;
471
- this._conditionallyHidden = this.checkConditionallyHidden();
472
- this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
474
+ this._visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
473
475
  if (this.component.addons?.length) {
474
476
  this.component.addons.forEach((addon) => this.createAddon(addon));
475
477
  }
@@ -635,20 +637,17 @@ export default class Component extends Element {
635
637
  }
636
638
  return this._visible && this._parentVisible;
637
639
  }
638
- get conditionallyHidden() {
639
- return this._conditionallyHidden || this._parentConditionallyHidden;
640
+ get logicallyHidden() {
641
+ if (this._logicallyHidden && !this.component.hidden) {
642
+ this._logicallyHidden = false;
643
+ }
644
+ return this._logicallyHidden;
640
645
  }
641
- /**
642
- * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).
643
- * @param {object} data - The data object to evaluate the condition against.
644
- * @param {object} row - The row object to evaluate the condition against.
645
- * @returns {boolean} - Whether the component is conditionally hidden.
646
- */
647
- checkConditionallyHidden(data = null, row = null) {
646
+ conditionallyHidden(skipParent = false) {
648
647
  if (!this.hasCondition()) {
649
- return false;
648
+ return this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
650
649
  }
651
- return !this.conditionallyVisible(data, row);
650
+ return !this.conditionallyVisible() || this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
652
651
  }
653
652
  get currentForm() {
654
653
  return this._currentForm;
@@ -1818,7 +1817,7 @@ export default class Component extends Element {
1818
1817
  rebuild() {
1819
1818
  this.destroy();
1820
1819
  this.init();
1821
- this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
1820
+ this.visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
1822
1821
  return this.redraw();
1823
1822
  }
1824
1823
  /**
@@ -1916,23 +1915,12 @@ export default class Component extends Element {
1916
1915
  if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {
1917
1916
  this.redraw();
1918
1917
  }
1919
- // Check advanced conditions (and cache the result)
1920
- const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;
1921
- let shouldClear = false;
1922
- if (isConditionallyHidden !== this._conditionallyHidden) {
1923
- this._conditionallyHidden = isConditionallyHidden;
1924
- shouldClear = true;
1925
- }
1926
1918
  // Check visibility
1927
- const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
1919
+ const visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
1928
1920
  if (this.visible !== visible) {
1929
1921
  this.visible = visible;
1930
1922
  }
1931
- // Wait for visibility to update for nested components, so the component state is up-to-date when
1932
- // calling clearOnHide
1933
- if (shouldClear) {
1934
- this.clearOnHide();
1935
- }
1923
+ this.clearOnHide();
1936
1924
  return visible;
1937
1925
  }
1938
1926
  /**
@@ -2041,9 +2029,9 @@ export default class Component extends Element {
2041
2029
  if (!_.isEqual(_.get(this.component, property), _.get(newComponent, property))) {
2042
2030
  // Advanced Logic can modify the component's hidden property; because we track conditionally hidden state
2043
2031
  // separately from the component's hidden property, and technically this Advanced Logic conditionally hides
2044
- // a component, we need to set _conditionallyHidden to the new value
2032
+ // a component, we need to set a temporary variable to the new value
2045
2033
  if (property === 'hidden') {
2046
- this._conditionallyHidden = newComponent.hidden;
2034
+ this._logicallyHidden = newComponent.hidden;
2047
2035
  }
2048
2036
  changed = true;
2049
2037
  }
@@ -2058,7 +2046,7 @@ export default class Component extends Element {
2058
2046
  component: newComponent,
2059
2047
  result,
2060
2048
  });
2061
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {
2049
+ if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2062
2050
  this.setValue(newValue);
2063
2051
  if (this.viewOnly) {
2064
2052
  this.dataValue = newValue;
@@ -2091,7 +2079,7 @@ export default class Component extends Element {
2091
2079
  component: newComponent,
2092
2080
  result,
2093
2081
  }, 'value');
2094
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {
2082
+ if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2095
2083
  this.setValue(newValue);
2096
2084
  if (this.viewOnly) {
2097
2085
  this.dataValue = newValue;
@@ -2202,7 +2190,7 @@ export default class Component extends Element {
2202
2190
  this.component.clearOnHide !== false &&
2203
2191
  !this.options.readOnly &&
2204
2192
  !this.options.showHiddenFields) {
2205
- if (this.conditionallyHidden) {
2193
+ if (this.conditionallyHidden()) {
2206
2194
  this.deleteValue();
2207
2195
  }
2208
2196
  else if (!this.hasValue() && this.shouldAddDefaultValue) {
@@ -2463,27 +2451,17 @@ export default class Component extends Element {
2463
2451
  * @returns {*} - The value for this component.
2464
2452
  */
2465
2453
  get dataValue() {
2466
- if (!this.key ||
2467
- (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
2468
- return this.emptyValue;
2469
- }
2470
- if (!this.hasValue() && this.shouldAddDefaultValue) {
2471
- const empty = this.component.multiple ? [] : this.emptyValue;
2472
- if (!this.rootPristine) {
2473
- this.dataValue = empty;
2474
- }
2475
- return empty;
2454
+ if (!this.key) {
2455
+ return this.component.multiple ? [] : this.emptyValue;
2476
2456
  }
2477
- return _.get(this._data, this.key);
2457
+ return _.get(this._data, this.key, this.component.multiple ? [] : this.emptyValue);
2478
2458
  }
2479
2459
  /**
2480
2460
  * Sets the static value of this component.
2481
2461
  * @param {*} value - The value to set for this component.
2482
2462
  */
2483
2463
  set dataValue(value) {
2484
- if (!this.allowData ||
2485
- !this.key ||
2486
- (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
2464
+ if (!this.allowData || !this.key) {
2487
2465
  return;
2488
2466
  }
2489
2467
  if ((value !== null) && (value !== undefined)) {
@@ -2803,7 +2781,7 @@ export default class Component extends Element {
2803
2781
  // If no calculated value or
2804
2782
  // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
2805
2783
  const { clearOnHide } = this.component;
2806
- const shouldBeCleared = this.conditionallyHidden && clearOnHide;
2784
+ const shouldBeCleared = this.conditionallyHidden() && clearOnHide;
2807
2785
  const allowOverride = _.get(this.component, 'allowCalculateOverride', false);
2808
2786
  if (shouldBeCleared) {
2809
2787
  // remove calculated value so that the value is recalculated once component becomes visible
@@ -3448,7 +3426,7 @@ export default class Component extends Element {
3448
3426
  // If component definition changed, replace it.
3449
3427
  if (!_.isEqual(this.component, newComponent)) {
3450
3428
  this.component = newComponent;
3451
- const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
3429
+ const visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
3452
3430
  const disabled = this.shouldDisabled;
3453
3431
  // Change states which won't be recalculated during redrawing
3454
3432
  if (this.visible !== visible) {