@formio/js 5.1.0-dev.6040.debc859 → 5.1.0-dev.6042.6e62a7a
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 +140 -6
- package/dist/formio.form.js +591 -580
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.full.js +613 -602
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.js +47 -14
- package/dist/formio.min.js +1 -1
- package/dist/formio.utils.js +48 -15
- package/dist/formio.utils.min.js +1 -1
- package/lib/cjs/Element.d.ts +2 -1
- package/lib/cjs/Element.js +6 -4
- package/lib/cjs/Webform.d.ts +2 -2
- package/lib/cjs/Webform.js +9 -9
- package/lib/cjs/WebformBuilder.js +5 -1
- package/lib/cjs/Wizard.d.ts +1 -0
- package/lib/cjs/Wizard.js +23 -3
- package/lib/cjs/components/_classes/component/Component.d.ts +50 -15
- package/lib/cjs/components/_classes/component/Component.js +153 -69
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +19 -0
- package/lib/cjs/components/_classes/component/editForm/utils.js +1 -1
- package/lib/cjs/components/_classes/list/ListComponent.js +2 -2
- package/lib/cjs/components/_classes/nested/NestedComponent.d.ts +0 -1
- package/lib/cjs/components/_classes/nested/NestedComponent.form.js +13 -0
- package/lib/cjs/components/_classes/nested/NestedComponent.js +10 -18
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.d.ts +0 -2
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +0 -11
- package/lib/cjs/components/address/Address.d.ts +9 -0
- package/lib/cjs/components/address/Address.js +31 -8
- package/lib/cjs/components/address/editForm/Address.edit.display.d.ts +4 -0
- package/lib/cjs/components/address/editForm/Address.edit.display.js +1 -0
- package/lib/cjs/components/address/editForm/Address.edit.provider.js +8 -8
- package/lib/cjs/components/content/editForm/Content.edit.display.js +8 -0
- package/lib/cjs/components/currency/editForm/Currency.edit.display.js +12 -0
- package/lib/cjs/components/datagrid/DataGrid.js +0 -3
- package/lib/cjs/components/datamap/DataMap.js +2 -6
- package/lib/cjs/components/datetime/editForm/DateTime.edit.validation.d.ts +66 -15
- package/lib/cjs/components/datetime/editForm/DateTime.edit.validation.js +68 -47
- package/lib/cjs/components/day/editForm/Day.edit.display.js +8 -0
- package/lib/cjs/components/editgrid/EditGrid.js +3 -13
- package/lib/cjs/components/email/editForm/Email.edit.display.js +12 -0
- package/lib/cjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
- package/lib/cjs/components/file/File.js +7 -2
- package/lib/cjs/components/file/editForm/File.edit.file.d.ts +13 -0
- package/lib/cjs/components/file/editForm/File.edit.file.js +1 -0
- package/lib/cjs/components/form/Form.d.ts +0 -1
- package/lib/cjs/components/form/Form.js +18 -22
- package/lib/cjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
- package/lib/cjs/components/html/HTML.js +1 -2
- package/lib/cjs/components/html/editForm/HTML.edit.display.js +8 -0
- package/lib/cjs/components/number/editForm/Number.edit.display.js +12 -0
- package/lib/cjs/components/password/editForm/Password.edit.display.js +13 -1
- package/lib/cjs/components/phonenumber/PhoneNumber.form.js +9 -1
- package/lib/cjs/components/radio/Radio.js +1 -1
- package/lib/cjs/components/select/Select.js +1 -1
- package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +68 -110
- package/lib/cjs/components/select/editForm/Select.edit.data.js +2 -37
- package/lib/cjs/components/selectboxes/SelectBoxes.js +3 -0
- package/lib/cjs/components/survey/Survey.js +1 -1
- package/lib/cjs/components/tabs/Tabs.js +1 -0
- package/lib/cjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
- package/lib/cjs/components/textarea/TextArea.js +9 -1
- package/lib/cjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
- package/lib/cjs/components/textfield/TextField.js +2 -2
- package/lib/cjs/components/unknown/Unknown.form.d.ts +2 -1
- package/lib/cjs/components/unknown/Unknown.form.js +13 -9
- package/lib/cjs/components/url/editForm/Url.edit.display.js +12 -0
- package/lib/cjs/components/well/editForm/Well.edit.display.js +8 -0
- package/lib/cjs/formio.form.js +2 -2
- package/lib/cjs/providers/storage/uploadAdapter.js +5 -3
- package/lib/cjs/translations/en.d.ts +1 -234
- package/lib/cjs/translations/en.js +4 -2
- package/lib/cjs/utils/formUtils.d.ts +2 -2
- package/lib/cjs/utils/utils.d.ts +9 -8
- package/lib/cjs/utils/utils.js +18 -23
- package/lib/cjs/widgets/CalendarWidget.js +6 -1
- package/lib/mjs/Element.d.ts +2 -1
- package/lib/mjs/Element.js +6 -4
- package/lib/mjs/Webform.d.ts +2 -2
- package/lib/mjs/Webform.js +9 -9
- package/lib/mjs/WebformBuilder.js +5 -1
- package/lib/mjs/Wizard.d.ts +1 -0
- package/lib/mjs/Wizard.js +22 -2
- package/lib/mjs/components/_classes/component/Component.d.ts +50 -15
- package/lib/mjs/components/_classes/component/Component.js +154 -70
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +19 -0
- package/lib/mjs/components/_classes/component/editForm/utils.js +1 -1
- package/lib/mjs/components/_classes/list/ListComponent.js +2 -2
- package/lib/mjs/components/_classes/nested/NestedComponent.d.ts +0 -1
- package/lib/mjs/components/_classes/nested/NestedComponent.form.js +13 -0
- package/lib/mjs/components/_classes/nested/NestedComponent.js +10 -18
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.d.ts +0 -2
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +0 -11
- package/lib/mjs/components/address/Address.d.ts +9 -0
- package/lib/mjs/components/address/Address.js +31 -8
- package/lib/mjs/components/address/editForm/Address.edit.display.d.ts +4 -0
- package/lib/mjs/components/address/editForm/Address.edit.display.js +1 -0
- package/lib/mjs/components/address/editForm/Address.edit.provider.js +8 -8
- package/lib/mjs/components/content/editForm/Content.edit.display.js +8 -0
- package/lib/mjs/components/currency/editForm/Currency.edit.display.js +12 -0
- package/lib/mjs/components/datagrid/DataGrid.js +0 -3
- package/lib/mjs/components/datamap/DataMap.js +2 -6
- package/lib/mjs/components/datetime/editForm/DateTime.edit.validation.d.ts +66 -15
- package/lib/mjs/components/datetime/editForm/DateTime.edit.validation.js +68 -47
- package/lib/mjs/components/day/editForm/Day.edit.display.js +8 -0
- package/lib/mjs/components/editgrid/EditGrid.js +3 -12
- package/lib/mjs/components/email/editForm/Email.edit.display.js +12 -0
- package/lib/mjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
- package/lib/mjs/components/file/File.js +7 -2
- package/lib/mjs/components/file/editForm/File.edit.file.d.ts +13 -0
- package/lib/mjs/components/file/editForm/File.edit.file.js +1 -0
- package/lib/mjs/components/form/Form.d.ts +0 -1
- package/lib/mjs/components/form/Form.js +18 -22
- package/lib/mjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
- package/lib/mjs/components/html/HTML.js +1 -2
- package/lib/mjs/components/html/editForm/HTML.edit.display.js +8 -0
- package/lib/mjs/components/number/editForm/Number.edit.display.js +12 -0
- package/lib/mjs/components/password/editForm/Password.edit.display.js +13 -1
- package/lib/mjs/components/phonenumber/PhoneNumber.form.js +9 -1
- package/lib/mjs/components/radio/Radio.js +1 -1
- package/lib/mjs/components/select/Select.js +1 -1
- package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +68 -110
- package/lib/mjs/components/select/editForm/Select.edit.data.js +2 -37
- package/lib/mjs/components/selectboxes/SelectBoxes.js +3 -0
- package/lib/mjs/components/survey/Survey.js +1 -1
- package/lib/mjs/components/tabs/Tabs.js +1 -0
- package/lib/mjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
- package/lib/mjs/components/textarea/TextArea.js +9 -1
- package/lib/mjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
- package/lib/mjs/components/textfield/TextField.js +2 -2
- package/lib/mjs/components/unknown/Unknown.form.d.ts +2 -1
- package/lib/mjs/components/unknown/Unknown.form.js +13 -9
- package/lib/mjs/components/url/editForm/Url.edit.display.js +12 -0
- package/lib/mjs/components/well/editForm/Well.edit.display.js +8 -0
- package/lib/mjs/formio.form.js +1 -1
- package/lib/mjs/providers/storage/uploadAdapter.js +5 -3
- package/lib/mjs/translations/en.d.ts +1 -234
- package/lib/mjs/translations/en.js +5 -47
- package/lib/mjs/utils/formUtils.d.ts +2 -2
- package/lib/mjs/utils/utils.d.ts +9 -8
- package/lib/mjs/utils/utils.js +16 -21
- package/lib/mjs/widgets/CalendarWidget.js +7 -2
- package/package.json +2 -2
- package/lib/cjs/i18n.d.ts +0 -13
- package/lib/cjs/i18n.js +0 -19
- package/lib/cjs/utils/i18n.d.ts +0 -19
- package/lib/cjs/utils/i18n.js +0 -120
- package/lib/mjs/i18n.d.ts +0 -13
- package/lib/mjs/i18n.js +0 -14
- package/lib/mjs/utils/i18n.d.ts +0 -19
- package/lib/mjs/utils/i18n.js +0 -112
@@ -6,7 +6,7 @@ import isMobile from 'ismobilejs';
|
|
6
6
|
import { processOne, processOneSync, validateProcessInfo } from '@formio/core/process';
|
7
7
|
import { Formio } from '../../../Formio';
|
8
8
|
import * as FormioUtils from '../../../utils/utils';
|
9
|
-
import { fastCloneDeep, boolValue,
|
9
|
+
import { fastCloneDeep, boolValue, currentTimezone, getScriptPlugin, getContextualRowData } from '../../../utils/utils';
|
10
10
|
import Element from '../../../Element';
|
11
11
|
import ComponentModal from '../componentModal/ComponentModal';
|
12
12
|
import Widgets from '../../../widgets';
|
@@ -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.
|
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 (!
|
392
|
+
if (!this.shouldConditionallyClear()) {
|
400
393
|
if (!this.hasValue()) {
|
401
394
|
if (this.shouldAddDefaultValue) {
|
402
395
|
this.dataValue = this.defaultValue;
|
@@ -429,6 +422,46 @@ export default class Component extends Element {
|
|
429
422
|
get componentsMap() {
|
430
423
|
return this.root?.childComponentsMap || {};
|
431
424
|
}
|
425
|
+
/**
|
426
|
+
* Returns if the parent should conditionally clear.
|
427
|
+
*
|
428
|
+
* @returns {boolean} - If the parent should conditionally clear.
|
429
|
+
*/
|
430
|
+
parentShouldConditionallyClear() {
|
431
|
+
let currentParent = this.parent;
|
432
|
+
while (currentParent) {
|
433
|
+
if ((currentParent.allowData && currentParent._conditionallyClear) ||
|
434
|
+
(!currentParent.allowData && currentParent._conditionallyHidden)) {
|
435
|
+
return true;
|
436
|
+
}
|
437
|
+
currentParent = currentParent.parent;
|
438
|
+
}
|
439
|
+
return false;
|
440
|
+
}
|
441
|
+
parentConditionallyHidden() {
|
442
|
+
let currentParent = this.parent;
|
443
|
+
while (currentParent) {
|
444
|
+
if (currentParent._conditionallyHidden) {
|
445
|
+
return true;
|
446
|
+
}
|
447
|
+
currentParent = currentParent.parent;
|
448
|
+
}
|
449
|
+
return false;
|
450
|
+
}
|
451
|
+
/**
|
452
|
+
* Returns true if any of the parents default their component "hidden" property to true.
|
453
|
+
* @returns {boolean} - If any parent defaults the hidden property to true.
|
454
|
+
*/
|
455
|
+
anyParentDefaultsHidden() {
|
456
|
+
let currentParent = this.parent;
|
457
|
+
while (currentParent) {
|
458
|
+
if (currentParent.component.hidden) {
|
459
|
+
return true;
|
460
|
+
}
|
461
|
+
currentParent = currentParent.parent;
|
462
|
+
}
|
463
|
+
return false;
|
464
|
+
}
|
432
465
|
get data() {
|
433
466
|
return this._data;
|
434
467
|
}
|
@@ -468,8 +501,7 @@ export default class Component extends Element {
|
|
468
501
|
}
|
469
502
|
init() {
|
470
503
|
this.disabled = this.shouldDisabled;
|
471
|
-
this.
|
472
|
-
this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
|
504
|
+
this._visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
|
473
505
|
if (this.component.addons?.length) {
|
474
506
|
this.component.addons.forEach((addon) => this.createAddon(addon));
|
475
507
|
}
|
@@ -635,20 +667,64 @@ export default class Component extends Element {
|
|
635
667
|
}
|
636
668
|
return this._visible && this._parentVisible;
|
637
669
|
}
|
638
|
-
get
|
639
|
-
|
670
|
+
get logicallyHidden() {
|
671
|
+
if (this._logicallyHidden && !this.component.hidden) {
|
672
|
+
this._logicallyHidden = false;
|
673
|
+
}
|
674
|
+
return this._logicallyHidden;
|
640
675
|
}
|
641
676
|
/**
|
642
|
-
*
|
643
|
-
* @
|
644
|
-
* @param {object} row - The row object to evaluate the condition against.
|
645
|
-
* @returns {boolean} - Whether the component is conditionally hidden.
|
677
|
+
* Determines if the component should clear its value when the root form is pristine.
|
678
|
+
* @returns {boolean} - If the component should clear its value when the root form is pristine.
|
646
679
|
*/
|
647
|
-
|
648
|
-
|
649
|
-
|
680
|
+
shouldConditionallyClearOnPristine() {
|
681
|
+
// If the form is pristine, we should NOT clear the value of a conditionally hidden child component
|
682
|
+
// of a layout component that defaults to hidden using the "hidden" component property.
|
683
|
+
return !this.anyParentDefaultsHidden();
|
684
|
+
}
|
685
|
+
/**
|
686
|
+
* Returns if the component should clear its value when conditionally hidden.
|
687
|
+
* @returns {boolean} - If the component should clear its value when conditionally hidden.
|
688
|
+
*/
|
689
|
+
shouldConditionallyClear() {
|
690
|
+
// Skip if this component has clearOnHide set to false.
|
691
|
+
if (this.component.clearOnHide === false) {
|
692
|
+
this._conditionallyClear = false;
|
693
|
+
return this._conditionallyClear;
|
650
694
|
}
|
651
|
-
|
695
|
+
// If the component is logically hidden, then it is conditionally hidden and should clear.
|
696
|
+
if (this.logicallyHidden) {
|
697
|
+
this._conditionallyClear = true;
|
698
|
+
return this._conditionallyClear;
|
699
|
+
}
|
700
|
+
// If we have a condition and it is not conditionally visible, the it should conditionally clear.
|
701
|
+
if (this.hasCondition() &&
|
702
|
+
!this.conditionallyVisible() &&
|
703
|
+
(!this.rootPristine || this.shouldConditionallyClearOnPristine())) {
|
704
|
+
this._conditionallyClear = true;
|
705
|
+
return this._conditionallyClear;
|
706
|
+
}
|
707
|
+
this._conditionallyClear = this.hasSetValue ? false : this.parentShouldConditionallyClear();
|
708
|
+
return this._conditionallyClear;
|
709
|
+
}
|
710
|
+
/**
|
711
|
+
* Returns if the component is conditionally hidden.
|
712
|
+
* @returns {boolean} - If the component is conditionally hidden.
|
713
|
+
*/
|
714
|
+
conditionallyHidden() {
|
715
|
+
// If it is logically hidden, then it is conditionally hidden.
|
716
|
+
if (this.logicallyHidden) {
|
717
|
+
this._conditionallyHidden = true;
|
718
|
+
return this._conditionallyHidden;
|
719
|
+
}
|
720
|
+
// If it has a condition, and is not conditionally visible, then it is conditionally hidden.
|
721
|
+
if (this.hasCondition() && !this.conditionallyVisible()) {
|
722
|
+
this._conditionallyHidden = true;
|
723
|
+
return this._conditionallyHidden;
|
724
|
+
}
|
725
|
+
// It is conditionally hidden if its parent is conditionally hidden.
|
726
|
+
this._conditionallyHidden = this.parentConditionallyHidden();
|
727
|
+
return this._conditionallyHidden;
|
652
728
|
}
|
653
729
|
get currentForm() {
|
654
730
|
return this._currentForm;
|
@@ -1818,7 +1894,7 @@ export default class Component extends Element {
|
|
1818
1894
|
rebuild() {
|
1819
1895
|
this.destroy();
|
1820
1896
|
this.init();
|
1821
|
-
this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
|
1897
|
+
this.visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
|
1822
1898
|
return this.redraw();
|
1823
1899
|
}
|
1824
1900
|
/**
|
@@ -1916,23 +1992,12 @@ export default class Component extends Element {
|
|
1916
1992
|
if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {
|
1917
1993
|
this.redraw();
|
1918
1994
|
}
|
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
1995
|
// Check visibility
|
1927
|
-
const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
|
1996
|
+
const visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
|
1928
1997
|
if (this.visible !== visible) {
|
1929
1998
|
this.visible = visible;
|
1930
1999
|
}
|
1931
|
-
|
1932
|
-
// calling clearOnHide
|
1933
|
-
if (shouldClear) {
|
1934
|
-
this.clearOnHide();
|
1935
|
-
}
|
2000
|
+
this.clearComponentOnHide();
|
1936
2001
|
return visible;
|
1937
2002
|
}
|
1938
2003
|
/**
|
@@ -2041,9 +2106,9 @@ export default class Component extends Element {
|
|
2041
2106
|
if (!_.isEqual(_.get(this.component, property), _.get(newComponent, property))) {
|
2042
2107
|
// Advanced Logic can modify the component's hidden property; because we track conditionally hidden state
|
2043
2108
|
// separately from the component's hidden property, and technically this Advanced Logic conditionally hides
|
2044
|
-
// a component, we need to set
|
2109
|
+
// a component, we need to set a temporary variable to the new value
|
2045
2110
|
if (property === 'hidden') {
|
2046
|
-
this.
|
2111
|
+
this._logicallyHidden = newComponent.hidden;
|
2047
2112
|
}
|
2048
2113
|
changed = true;
|
2049
2114
|
}
|
@@ -2058,7 +2123,7 @@ export default class Component extends Element {
|
|
2058
2123
|
component: newComponent,
|
2059
2124
|
result,
|
2060
2125
|
});
|
2061
|
-
if (!_.isEqual(oldValue, newValue) && !
|
2126
|
+
if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
|
2062
2127
|
this.setValue(newValue);
|
2063
2128
|
if (this.viewOnly) {
|
2064
2129
|
this.dataValue = newValue;
|
@@ -2091,7 +2156,7 @@ export default class Component extends Element {
|
|
2091
2156
|
component: newComponent,
|
2092
2157
|
result,
|
2093
2158
|
}, 'value');
|
2094
|
-
if (!_.isEqual(oldValue, newValue) && !
|
2159
|
+
if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
|
2095
2160
|
this.setValue(newValue);
|
2096
2161
|
if (this.viewOnly) {
|
2097
2162
|
this.dataValue = newValue;
|
@@ -2192,17 +2257,12 @@ export default class Component extends Element {
|
|
2192
2257
|
element.setAttribute('aria-invalid', invalid ? 'true' : 'false');
|
2193
2258
|
}
|
2194
2259
|
/**
|
2195
|
-
*
|
2260
|
+
* Clear any conditionally hidden components for this component only.
|
2196
2261
|
*/
|
2197
|
-
|
2262
|
+
clearComponentOnHide() {
|
2198
2263
|
// clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
|
2199
|
-
if (
|
2200
|
-
|
2201
|
-
(!this.rootPristine || this.options.server || isInsideScopingComponent(this)) &&
|
2202
|
-
this.component.clearOnHide !== false &&
|
2203
|
-
!this.options.readOnly &&
|
2204
|
-
!this.options.showHiddenFields) {
|
2205
|
-
if (this.conditionallyHidden) {
|
2264
|
+
if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
|
2265
|
+
if (this.shouldConditionallyClear()) {
|
2206
2266
|
this.deleteValue();
|
2207
2267
|
}
|
2208
2268
|
else if (!this.hasValue() && this.shouldAddDefaultValue) {
|
@@ -2213,6 +2273,12 @@ export default class Component extends Element {
|
|
2213
2273
|
}
|
2214
2274
|
}
|
2215
2275
|
}
|
2276
|
+
/**
|
2277
|
+
* Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
|
2278
|
+
*/
|
2279
|
+
clearOnHide() {
|
2280
|
+
this.clearComponentOnHide();
|
2281
|
+
}
|
2216
2282
|
/**
|
2217
2283
|
* Triggers a debounced onChange event for the root component (usually Webform).
|
2218
2284
|
* @param {...any} args - The arguments to pass to the onChange event.
|
@@ -2463,27 +2529,17 @@ export default class Component extends Element {
|
|
2463
2529
|
* @returns {*} - The value for this component.
|
2464
2530
|
*/
|
2465
2531
|
get dataValue() {
|
2466
|
-
if (!this.key
|
2467
|
-
|
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;
|
2532
|
+
if (!this.key) {
|
2533
|
+
return this.component.multiple ? [] : this.emptyValue;
|
2476
2534
|
}
|
2477
|
-
return _.get(this._data, this.key);
|
2535
|
+
return _.get(this._data, this.key, this.component.multiple ? [] : this.emptyValue);
|
2478
2536
|
}
|
2479
2537
|
/**
|
2480
2538
|
* Sets the static value of this component.
|
2481
2539
|
* @param {*} value - The value to set for this component.
|
2482
2540
|
*/
|
2483
2541
|
set dataValue(value) {
|
2484
|
-
if (!this.allowData ||
|
2485
|
-
!this.key ||
|
2486
|
-
(this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
|
2542
|
+
if (!this.allowData || !this.key) {
|
2487
2543
|
return;
|
2488
2544
|
}
|
2489
2545
|
if ((value !== null) && (value !== undefined)) {
|
@@ -2526,13 +2582,30 @@ export default class Component extends Element {
|
|
2526
2582
|
}
|
2527
2583
|
getCustomDefaultValue(defaultValue) {
|
2528
2584
|
if (this.component.customDefaultValue && !this.options.preview) {
|
2529
|
-
defaultValue = this.evaluate(this.component.customDefaultValue, { value:
|
2585
|
+
defaultValue = this.evaluate(this.component.customDefaultValue, { value: this.dataValue }, 'value');
|
2530
2586
|
}
|
2531
2587
|
return defaultValue;
|
2532
2588
|
}
|
2589
|
+
/**
|
2590
|
+
* Returns if a component has a default value set.
|
2591
|
+
* @returns {boolean} - TRUE if a default value is set.
|
2592
|
+
*/
|
2593
|
+
get hasDefaultValue() {
|
2594
|
+
return this.component.customDefaultValue || (this.component.hasOwnProperty('defaultValue') &&
|
2595
|
+
(this.component.defaultValue !== null) &&
|
2596
|
+
(this.component.defaultValue !== undefined));
|
2597
|
+
}
|
2598
|
+
/**
|
2599
|
+
* Determine if we should add a default value for this component.
|
2600
|
+
* @returns {boolean} - TRUE if a default value should be set
|
2601
|
+
*/
|
2533
2602
|
get shouldAddDefaultValue() {
|
2534
|
-
return
|
2603
|
+
return this.pristine && this.allowData && (this.hasDefaultValue || !this.options.noDefaults);
|
2535
2604
|
}
|
2605
|
+
/**
|
2606
|
+
* Get the default value of this component.
|
2607
|
+
* @returns {*} - The default value for this component.
|
2608
|
+
*/
|
2536
2609
|
get defaultValue() {
|
2537
2610
|
let defaultValue = this.emptyValue;
|
2538
2611
|
if (this.component.defaultValue) {
|
@@ -2802,10 +2875,8 @@ export default class Component extends Element {
|
|
2802
2875
|
}
|
2803
2876
|
// If no calculated value or
|
2804
2877
|
// hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
|
2805
|
-
const { clearOnHide } = this.component;
|
2806
|
-
const shouldBeCleared = this.conditionallyHidden && clearOnHide;
|
2807
2878
|
const allowOverride = _.get(this.component, 'allowCalculateOverride', false);
|
2808
|
-
if (
|
2879
|
+
if (this.shouldConditionallyClear()) {
|
2809
2880
|
// remove calculated value so that the value is recalculated once component becomes visible
|
2810
2881
|
if (this.hasOwnProperty('calculatedValue') && allowOverride) {
|
2811
2882
|
_.unset(this, 'calculatedValue');
|
@@ -2926,9 +2997,11 @@ export default class Component extends Element {
|
|
2926
2997
|
* @param {boolean} dirty - If the component is dirty.
|
2927
2998
|
* @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
|
2928
2999
|
* @param {*} row - Contextual row data for this component.
|
3000
|
+
* @param {*} options - Additional options for validation.
|
2929
3001
|
* @returns {string} - The message to show when the component is invalid.
|
2930
3002
|
*/
|
2931
|
-
invalidMessage(data, dirty, ignoreCondition, row) {
|
3003
|
+
invalidMessage(data, dirty, ignoreCondition, row, options = {}) {
|
3004
|
+
const { local } = options;
|
2932
3005
|
if (!row) {
|
2933
3006
|
row = getContextualRowData(this.component, data, this.paths);
|
2934
3007
|
}
|
@@ -2948,6 +3021,7 @@ export default class Component extends Element {
|
|
2948
3021
|
component: this.component,
|
2949
3022
|
data,
|
2950
3023
|
row,
|
3024
|
+
local,
|
2951
3025
|
path: this.path || this.component.key,
|
2952
3026
|
parent: this.parent?.component,
|
2953
3027
|
paths: this.paths,
|
@@ -3122,6 +3196,14 @@ export default class Component extends Element {
|
|
3122
3196
|
data = data || this.rootValue;
|
3123
3197
|
flags = flags || {};
|
3124
3198
|
row = row || this.data;
|
3199
|
+
// Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
|
3200
|
+
// as setValue. Historically, this was bypassed by a series of cached states around the data model
|
3201
|
+
// which caused its own problems. We need to ensure that premium and custom components do not fall into
|
3202
|
+
// an infinite loop by only checking this component once.
|
3203
|
+
if (this.checkingData) {
|
3204
|
+
return;
|
3205
|
+
}
|
3206
|
+
this.checkingData = true;
|
3125
3207
|
// Needs for Nextgen Rules Engine
|
3126
3208
|
this.resetCaches();
|
3127
3209
|
// Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners
|
@@ -3135,6 +3217,8 @@ export default class Component extends Element {
|
|
3135
3217
|
if (this.id !== flags.triggeredComponentId) {
|
3136
3218
|
this.calculateComponentValue(data, flags, row);
|
3137
3219
|
}
|
3220
|
+
// We are done checking data.
|
3221
|
+
this.checkingData = false;
|
3138
3222
|
}
|
3139
3223
|
checkModal(errors = [], dirty = false) {
|
3140
3224
|
const messages = errors.filter(error => !error.fromServer);
|
@@ -3448,7 +3532,7 @@ export default class Component extends Element {
|
|
3448
3532
|
// If component definition changed, replace it.
|
3449
3533
|
if (!_.isEqual(this.component, newComponent)) {
|
3450
3534
|
this.component = newComponent;
|
3451
|
-
const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
|
3535
|
+
const visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
|
3452
3536
|
const disabled = this.shouldDisabled;
|
3453
3537
|
// Change states which won't be recalculated during redrawing
|
3454
3538
|
if (this.visible !== visible) {
|
@@ -76,6 +76,25 @@ export default [
|
|
76
76
|
}
|
77
77
|
]
|
78
78
|
},
|
79
|
+
{
|
80
|
+
name: 'hide',
|
81
|
+
trigger: {
|
82
|
+
type: 'javascript',
|
83
|
+
javascript: 'result = instance.root.options.editJson === false;'
|
84
|
+
},
|
85
|
+
actions: [
|
86
|
+
{
|
87
|
+
name: 'hide',
|
88
|
+
type: 'property',
|
89
|
+
property: {
|
90
|
+
label: 'Hidden',
|
91
|
+
value: 'hidden',
|
92
|
+
type: 'boolean'
|
93
|
+
},
|
94
|
+
state: true
|
95
|
+
}
|
96
|
+
]
|
97
|
+
},
|
79
98
|
{
|
80
99
|
name: 'disabledToolTip',
|
81
100
|
trigger: {
|
@@ -6,7 +6,7 @@ const EditFormUtils = {
|
|
6
6
|
},
|
7
7
|
unifyComponents(objValue, srcValue) {
|
8
8
|
if (objValue.key && srcValue.key) {
|
9
|
-
if (objValue.skipMerge || srcValue.skipMerge) {
|
9
|
+
if ((objValue.skipMerge || srcValue.skipMerge) && !objValue.ignore) {
|
10
10
|
return false;
|
11
11
|
}
|
12
12
|
if (objValue.key === srcValue.key) {
|
@@ -24,9 +24,9 @@ export default class ListComponent extends Field {
|
|
24
24
|
get dataReady() {
|
25
25
|
// If the root submission has been set, and we are still not attached, then assume
|
26
26
|
// that our data is ready.
|
27
|
-
if (this.root &&
|
27
|
+
if ((this.root &&
|
28
28
|
this.root.submissionSet &&
|
29
|
-
!this.attached) {
|
29
|
+
!this.attached) || !this.visible) {
|
30
30
|
return Promise.resolve();
|
31
31
|
}
|
32
32
|
return this.itemsLoaded;
|
@@ -181,7 +181,6 @@ export default class NestedComponent extends Field {
|
|
181
181
|
checkData(data: any, flags: any, row: any, components: any): true | undefined;
|
182
182
|
checkConditions(data: any, flags: any, row: any): boolean;
|
183
183
|
clearOnHide(show: any): void;
|
184
|
-
restoreComponentsContext(): void;
|
185
184
|
/**
|
186
185
|
* Allow components to hook into the next page trigger to perform their own logic.
|
187
186
|
* @param {Function} next - The callback to continue to the next page.
|
@@ -6,6 +6,19 @@ import Components from '../../Components';
|
|
6
6
|
*/
|
7
7
|
export default function (...extend) {
|
8
8
|
return Components.baseEditForm([
|
9
|
+
{
|
10
|
+
key: 'display',
|
11
|
+
components: [
|
12
|
+
{
|
13
|
+
key: 'labelWidth',
|
14
|
+
ignore: true
|
15
|
+
},
|
16
|
+
{
|
17
|
+
key: 'labelMargin',
|
18
|
+
ignore: true
|
19
|
+
}
|
20
|
+
]
|
21
|
+
},
|
9
22
|
{
|
10
23
|
key: 'data',
|
11
24
|
ignore: true
|
@@ -81,18 +81,15 @@ export default class NestedComponent extends Field {
|
|
81
81
|
const visibilityChanged = this._visible !== value;
|
82
82
|
this._visible = value;
|
83
83
|
const isVisible = this.visible;
|
84
|
-
const isConditionallyHidden = this.checkConditionallyHidden();
|
85
84
|
const forceShow = this.shouldForceShow();
|
86
85
|
const forceHide = this.shouldForceHide();
|
87
86
|
this.components.forEach((component) => {
|
88
87
|
// Set the parent visibility first since we may have nested components within nested components
|
89
88
|
// and they need to be able to determine their visibility based on the parent visibility.
|
90
89
|
component.parentVisible = isVisible;
|
91
|
-
component._parentConditionallyHidden = isConditionallyHidden;
|
92
90
|
let visible;
|
93
91
|
if (component.hasCondition()) {
|
94
|
-
|
95
|
-
visible = !component.conditionallyHidden;
|
92
|
+
visible = !component.conditionallyHidden();
|
96
93
|
}
|
97
94
|
else {
|
98
95
|
visible = !component.component.hidden;
|
@@ -373,7 +370,6 @@ export default class NestedComponent extends Field {
|
|
373
370
|
data = data || this.data;
|
374
371
|
options.parent = this;
|
375
372
|
options.parentVisible = this.visible;
|
376
|
-
options.parentConditionallyHidden = this.conditionallyHidden;
|
377
373
|
options.root = options?.root || this.root || this;
|
378
374
|
options.localRoot = this.localRoot;
|
379
375
|
options.skipInit = true;
|
@@ -631,19 +627,8 @@ export default class NestedComponent extends Field {
|
|
631
627
|
}
|
632
628
|
clearOnHide(show) {
|
633
629
|
super.clearOnHide(show);
|
634
|
-
if (this.component.clearOnHide) {
|
635
|
-
if (this.allowData && !this.hasValue() && !this.conditionallyHidden) {
|
636
|
-
this.dataValue = this.defaultValue;
|
637
|
-
}
|
638
|
-
if (this.hasValue()) {
|
639
|
-
this.restoreComponentsContext();
|
640
|
-
}
|
641
|
-
}
|
642
630
|
this.getComponents().forEach(component => component.clearOnHide(show));
|
643
631
|
}
|
644
|
-
restoreComponentsContext() {
|
645
|
-
this.getComponents().forEach((component) => component.data = this.dataValue);
|
646
|
-
}
|
647
632
|
/**
|
648
633
|
* Allow components to hook into the next page trigger to perform their own logic.
|
649
634
|
* @param {Function} next - The callback to continue to the next page.
|
@@ -661,7 +646,7 @@ export default class NestedComponent extends Field {
|
|
661
646
|
}
|
662
647
|
calculateValue(data, flags, row) {
|
663
648
|
// Do not iterate into children and calculateValues if this nested component is conditionally hidden.
|
664
|
-
if (this.conditionallyHidden) {
|
649
|
+
if (this.conditionallyHidden()) {
|
665
650
|
return false;
|
666
651
|
}
|
667
652
|
return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));
|
@@ -831,7 +816,7 @@ export default class NestedComponent extends Field {
|
|
831
816
|
else if (value && component.hasValue(value)) {
|
832
817
|
return component.setValue(_.get(value, component.key), flags);
|
833
818
|
}
|
834
|
-
else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {
|
819
|
+
else if ((!this.rootPristine || component.visible) && (flags.resetValue || component.shouldAddDefaultValue)) {
|
835
820
|
flags.noValidate = !flags.dirty;
|
836
821
|
flags.resetValue = true;
|
837
822
|
return component.setValue(component.defaultValue, flags);
|
@@ -841,6 +826,13 @@ export default class NestedComponent extends Field {
|
|
841
826
|
if (!value) {
|
842
827
|
return false;
|
843
828
|
}
|
829
|
+
// If the value is equal to the empty value, then this means we need to reset the values.
|
830
|
+
if (_.isEqual(value, this.emptyValue)) {
|
831
|
+
// TO-DO: For a future major release, we need to investigate removing the need for the
|
832
|
+
// "resetValue" flag. This seems like a hack that is no longer necessary and the renderer
|
833
|
+
// may behave more deterministically without it.
|
834
|
+
flags.resetValue = true;
|
835
|
+
}
|
844
836
|
return this.getComponents().reduce((changed, component) => {
|
845
837
|
return this.setNestedValue(component, value, flags, changed) || changed;
|
846
838
|
}, false);
|
@@ -3,11 +3,9 @@ export default class NestedDataComponent extends NestedComponent {
|
|
3
3
|
hasChanged(newValue: any, oldValue: any): boolean;
|
4
4
|
get allowData(): boolean;
|
5
5
|
get emptyValue(): {};
|
6
|
-
get shouldAddDefaultValue(): boolean;
|
7
6
|
componentContext(): any;
|
8
7
|
getValueAsString(value: any, options: any): string;
|
9
8
|
getDataValueAsTable(value: any, options: any): string;
|
10
|
-
everyComponent(fn: any, options?: {}): void;
|
11
9
|
/**
|
12
10
|
* Get the value of this component.
|
13
11
|
* @returns {any} - Return the value of this component.
|
@@ -90,17 +90,6 @@ export default class NestedDataComponent extends NestedComponent {
|
|
90
90
|
`);
|
91
91
|
return result;
|
92
92
|
}
|
93
|
-
everyComponent(fn, options = {}) {
|
94
|
-
if (options?.email) {
|
95
|
-
if (options.fromRoot) {
|
96
|
-
delete options.fromRoot;
|
97
|
-
}
|
98
|
-
else {
|
99
|
-
return;
|
100
|
-
}
|
101
|
-
}
|
102
|
-
return super.everyComponent(fn, options);
|
103
|
-
}
|
104
93
|
/**
|
105
94
|
* Get the value of this component.
|
106
95
|
* @returns {any} - Return the value of this component.
|
@@ -36,12 +36,21 @@ export default class AddressComponent extends ContainerComponent {
|
|
36
36
|
get autocompleteMode(): boolean;
|
37
37
|
get manualMode(): boolean;
|
38
38
|
get manualModeEnabled(): boolean;
|
39
|
+
restoreComponentsContext(): void;
|
39
40
|
get isMultiple(): boolean;
|
40
41
|
set address(value: any);
|
41
42
|
get address(): any;
|
42
43
|
isValueInLegacyFormat(value: any): any;
|
43
44
|
normalizeValue(value: any): any;
|
44
45
|
get modeSwitcher(): any;
|
46
|
+
get providerOptions(): {
|
47
|
+
params: any;
|
48
|
+
url: any;
|
49
|
+
queryProperty: any;
|
50
|
+
responseProperty: any;
|
51
|
+
displayValueProperty: any;
|
52
|
+
autocompleteOptions: any;
|
53
|
+
};
|
45
54
|
get removeValueIcon(): any;
|
46
55
|
get searchInput(): any;
|
47
56
|
get addRowButton(): any;
|