@formio/js 5.1.0-dev.6039.a838d78 → 5.1.0-dev.6042.18ef5d3
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 +587 -576
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.full.js +609 -598
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.js +45 -12
- package/dist/formio.min.js +1 -1
- package/dist/formio.utils.js +46 -13
- 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 +6 -8
- package/lib/cjs/WebformBuilder.js +4 -0
- package/lib/cjs/Wizard.d.ts +1 -0
- package/lib/cjs/Wizard.js +23 -3
- package/lib/cjs/components/_classes/component/Component.d.ts +27 -17
- package/lib/cjs/components/_classes/component/Component.js +124 -70
- 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.js +11 -11
- 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/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 +0 -8
- package/lib/cjs/utils/utils.js +3 -23
- 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 +6 -8
- package/lib/mjs/WebformBuilder.js +4 -0
- package/lib/mjs/Wizard.d.ts +1 -0
- package/lib/mjs/Wizard.js +22 -2
- package/lib/mjs/components/_classes/component/Component.d.ts +27 -17
- package/lib/mjs/components/_classes/component/Component.js +125 -71
- 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.js +11 -11
- 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/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 +3 -47
- package/lib/mjs/utils/formUtils.d.ts +2 -2
- package/lib/mjs/utils/utils.d.ts +0 -8
- package/lib/mjs/utils/utils.js +2 -21
- 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,26 @@ export default class Component extends Element {
|
|
429
422
|
get componentsMap() {
|
430
423
|
return this.root?.childComponentsMap || {};
|
431
424
|
}
|
425
|
+
parentShouldConditionallyClear() {
|
426
|
+
let currentParent = this.parent;
|
427
|
+
while (currentParent) {
|
428
|
+
if (currentParent.shouldConditionallyClear(true)) {
|
429
|
+
return true;
|
430
|
+
}
|
431
|
+
currentParent = currentParent.parent;
|
432
|
+
}
|
433
|
+
return false;
|
434
|
+
}
|
435
|
+
parentConditionallyHidden() {
|
436
|
+
let currentParent = this.parent;
|
437
|
+
while (currentParent) {
|
438
|
+
if (currentParent.conditionallyHidden(true)) {
|
439
|
+
return true;
|
440
|
+
}
|
441
|
+
currentParent = currentParent.parent;
|
442
|
+
}
|
443
|
+
return false;
|
444
|
+
}
|
432
445
|
get data() {
|
433
446
|
return this._data;
|
434
447
|
}
|
@@ -468,8 +481,7 @@ export default class Component extends Element {
|
|
468
481
|
}
|
469
482
|
init() {
|
470
483
|
this.disabled = this.shouldDisabled;
|
471
|
-
this.
|
472
|
-
this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
|
484
|
+
this._visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
|
473
485
|
if (this.component.addons?.length) {
|
474
486
|
this.component.addons.forEach((addon) => this.createAddon(addon));
|
475
487
|
}
|
@@ -635,20 +647,54 @@ export default class Component extends Element {
|
|
635
647
|
}
|
636
648
|
return this._visible && this._parentVisible;
|
637
649
|
}
|
638
|
-
get
|
639
|
-
|
650
|
+
get logicallyHidden() {
|
651
|
+
if (this._logicallyHidden && !this.component.hidden) {
|
652
|
+
this._logicallyHidden = false;
|
653
|
+
}
|
654
|
+
return this._logicallyHidden;
|
640
655
|
}
|
641
|
-
|
642
|
-
|
643
|
-
|
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) {
|
648
|
-
if (!this.hasCondition()) {
|
656
|
+
shouldConditionallyClear(skipParent = false) {
|
657
|
+
// Skip if this component has clearOnHide set to false.
|
658
|
+
if (this.component.clearOnHide === false) {
|
649
659
|
return false;
|
650
660
|
}
|
651
|
-
|
661
|
+
// If the component is logically hidden, then it is conditionally hidden and should clear.
|
662
|
+
if (this.logicallyHidden) {
|
663
|
+
return true;
|
664
|
+
}
|
665
|
+
// If we have a condition and it is not conditionally visible, the it should conditionally clear.
|
666
|
+
if (this.hasCondition() && !this.conditionallyVisible()) {
|
667
|
+
return true;
|
668
|
+
}
|
669
|
+
if (skipParent) {
|
670
|
+
// Stop recurrsion for the parent checks.
|
671
|
+
return false;
|
672
|
+
}
|
673
|
+
// If this component has a set value, then it should ONLY clear if a parent is hidden
|
674
|
+
// and has the clearOnHide set to true.
|
675
|
+
if (this.hasSetValue) {
|
676
|
+
return this.parentShouldConditionallyClear();
|
677
|
+
}
|
678
|
+
// Clear the value if the parent is conditionally hidden.
|
679
|
+
return this.parentConditionallyHidden();
|
680
|
+
}
|
681
|
+
conditionallyHidden(skipParent = false) {
|
682
|
+
if (this.logicallyHidden) {
|
683
|
+
return true;
|
684
|
+
}
|
685
|
+
if (!this.hasCondition() && !skipParent) {
|
686
|
+
return this.parentConditionallyHidden();
|
687
|
+
}
|
688
|
+
// Return if we are not conditionally visible (conditionallyHidden)
|
689
|
+
if (!this.conditionallyVisible()) {
|
690
|
+
return true;
|
691
|
+
}
|
692
|
+
if (skipParent) {
|
693
|
+
// Stop recurrsion for the parent checks.
|
694
|
+
return false;
|
695
|
+
}
|
696
|
+
// Check the parent.
|
697
|
+
return this.parentConditionallyHidden();
|
652
698
|
}
|
653
699
|
get currentForm() {
|
654
700
|
return this._currentForm;
|
@@ -1818,7 +1864,7 @@ export default class Component extends Element {
|
|
1818
1864
|
rebuild() {
|
1819
1865
|
this.destroy();
|
1820
1866
|
this.init();
|
1821
|
-
this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
|
1867
|
+
this.visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
|
1822
1868
|
return this.redraw();
|
1823
1869
|
}
|
1824
1870
|
/**
|
@@ -1916,23 +1962,12 @@ export default class Component extends Element {
|
|
1916
1962
|
if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {
|
1917
1963
|
this.redraw();
|
1918
1964
|
}
|
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
1965
|
// Check visibility
|
1927
|
-
const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
|
1966
|
+
const visible = (this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden);
|
1928
1967
|
if (this.visible !== visible) {
|
1929
1968
|
this.visible = visible;
|
1930
1969
|
}
|
1931
|
-
|
1932
|
-
// calling clearOnHide
|
1933
|
-
if (shouldClear) {
|
1934
|
-
this.clearOnHide();
|
1935
|
-
}
|
1970
|
+
this.clearComponentOnHide();
|
1936
1971
|
return visible;
|
1937
1972
|
}
|
1938
1973
|
/**
|
@@ -2041,9 +2076,9 @@ export default class Component extends Element {
|
|
2041
2076
|
if (!_.isEqual(_.get(this.component, property), _.get(newComponent, property))) {
|
2042
2077
|
// Advanced Logic can modify the component's hidden property; because we track conditionally hidden state
|
2043
2078
|
// separately from the component's hidden property, and technically this Advanced Logic conditionally hides
|
2044
|
-
// a component, we need to set
|
2079
|
+
// a component, we need to set a temporary variable to the new value
|
2045
2080
|
if (property === 'hidden') {
|
2046
|
-
this.
|
2081
|
+
this._logicallyHidden = newComponent.hidden;
|
2047
2082
|
}
|
2048
2083
|
changed = true;
|
2049
2084
|
}
|
@@ -2058,7 +2093,7 @@ export default class Component extends Element {
|
|
2058
2093
|
component: newComponent,
|
2059
2094
|
result,
|
2060
2095
|
});
|
2061
|
-
if (!_.isEqual(oldValue, newValue) && !
|
2096
|
+
if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
|
2062
2097
|
this.setValue(newValue);
|
2063
2098
|
if (this.viewOnly) {
|
2064
2099
|
this.dataValue = newValue;
|
@@ -2091,7 +2126,7 @@ export default class Component extends Element {
|
|
2091
2126
|
component: newComponent,
|
2092
2127
|
result,
|
2093
2128
|
}, 'value');
|
2094
|
-
if (!_.isEqual(oldValue, newValue) && !
|
2129
|
+
if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
|
2095
2130
|
this.setValue(newValue);
|
2096
2131
|
if (this.viewOnly) {
|
2097
2132
|
this.dataValue = newValue;
|
@@ -2192,17 +2227,12 @@ export default class Component extends Element {
|
|
2192
2227
|
element.setAttribute('aria-invalid', invalid ? 'true' : 'false');
|
2193
2228
|
}
|
2194
2229
|
/**
|
2195
|
-
*
|
2230
|
+
* Clear any conditionally hidden components for this component only.
|
2196
2231
|
*/
|
2197
|
-
|
2232
|
+
clearComponentOnHide() {
|
2198
2233
|
// 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) {
|
2234
|
+
if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
|
2235
|
+
if (this.shouldConditionallyClear()) {
|
2206
2236
|
this.deleteValue();
|
2207
2237
|
}
|
2208
2238
|
else if (!this.hasValue() && this.shouldAddDefaultValue) {
|
@@ -2213,6 +2243,12 @@ export default class Component extends Element {
|
|
2213
2243
|
}
|
2214
2244
|
}
|
2215
2245
|
}
|
2246
|
+
/**
|
2247
|
+
* Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
|
2248
|
+
*/
|
2249
|
+
clearOnHide() {
|
2250
|
+
this.clearComponentOnHide();
|
2251
|
+
}
|
2216
2252
|
/**
|
2217
2253
|
* Triggers a debounced onChange event for the root component (usually Webform).
|
2218
2254
|
* @param {...any} args - The arguments to pass to the onChange event.
|
@@ -2463,27 +2499,17 @@ export default class Component extends Element {
|
|
2463
2499
|
* @returns {*} - The value for this component.
|
2464
2500
|
*/
|
2465
2501
|
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;
|
2502
|
+
if (!this.key) {
|
2503
|
+
return this.component.multiple ? [] : this.emptyValue;
|
2476
2504
|
}
|
2477
|
-
return _.get(this._data, this.key);
|
2505
|
+
return _.get(this._data, this.key, this.component.multiple ? [] : this.emptyValue);
|
2478
2506
|
}
|
2479
2507
|
/**
|
2480
2508
|
* Sets the static value of this component.
|
2481
2509
|
* @param {*} value - The value to set for this component.
|
2482
2510
|
*/
|
2483
2511
|
set dataValue(value) {
|
2484
|
-
if (!this.allowData ||
|
2485
|
-
!this.key ||
|
2486
|
-
(this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {
|
2512
|
+
if (!this.allowData || !this.key) {
|
2487
2513
|
return;
|
2488
2514
|
}
|
2489
2515
|
if ((value !== null) && (value !== undefined)) {
|
@@ -2526,13 +2552,30 @@ export default class Component extends Element {
|
|
2526
2552
|
}
|
2527
2553
|
getCustomDefaultValue(defaultValue) {
|
2528
2554
|
if (this.component.customDefaultValue && !this.options.preview) {
|
2529
|
-
defaultValue = this.evaluate(this.component.customDefaultValue, { value:
|
2555
|
+
defaultValue = this.evaluate(this.component.customDefaultValue, { value: this.dataValue }, 'value');
|
2530
2556
|
}
|
2531
2557
|
return defaultValue;
|
2532
2558
|
}
|
2559
|
+
/**
|
2560
|
+
* Returns if a component has a default value set.
|
2561
|
+
* @returns {boolean} - TRUE if a default value is set.
|
2562
|
+
*/
|
2563
|
+
get hasDefaultValue() {
|
2564
|
+
return this.component.customDefaultValue || (this.component.hasOwnProperty('defaultValue') &&
|
2565
|
+
(this.component.defaultValue !== null) &&
|
2566
|
+
(this.component.defaultValue !== undefined));
|
2567
|
+
}
|
2568
|
+
/**
|
2569
|
+
* Determine if we should add a default value for this component.
|
2570
|
+
* @returns {boolean} - TRUE if a default value should be set
|
2571
|
+
*/
|
2533
2572
|
get shouldAddDefaultValue() {
|
2534
|
-
return
|
2573
|
+
return this.pristine && this.allowData && (this.hasDefaultValue || !this.options.noDefaults);
|
2535
2574
|
}
|
2575
|
+
/**
|
2576
|
+
* Get the default value of this component.
|
2577
|
+
* @returns {*} - The default value for this component.
|
2578
|
+
*/
|
2536
2579
|
get defaultValue() {
|
2537
2580
|
let defaultValue = this.emptyValue;
|
2538
2581
|
if (this.component.defaultValue) {
|
@@ -2802,10 +2845,8 @@ export default class Component extends Element {
|
|
2802
2845
|
}
|
2803
2846
|
// If no calculated value or
|
2804
2847
|
// 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
2848
|
const allowOverride = _.get(this.component, 'allowCalculateOverride', false);
|
2808
|
-
if (
|
2849
|
+
if (this.shouldConditionallyClear()) {
|
2809
2850
|
// remove calculated value so that the value is recalculated once component becomes visible
|
2810
2851
|
if (this.hasOwnProperty('calculatedValue') && allowOverride) {
|
2811
2852
|
_.unset(this, 'calculatedValue');
|
@@ -2926,9 +2967,11 @@ export default class Component extends Element {
|
|
2926
2967
|
* @param {boolean} dirty - If the component is dirty.
|
2927
2968
|
* @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
|
2928
2969
|
* @param {*} row - Contextual row data for this component.
|
2970
|
+
* @param {*} options - Additional options for validation.
|
2929
2971
|
* @returns {string} - The message to show when the component is invalid.
|
2930
2972
|
*/
|
2931
|
-
invalidMessage(data, dirty, ignoreCondition, row) {
|
2973
|
+
invalidMessage(data, dirty, ignoreCondition, row, options = {}) {
|
2974
|
+
const { local } = options;
|
2932
2975
|
if (!row) {
|
2933
2976
|
row = getContextualRowData(this.component, data, this.paths);
|
2934
2977
|
}
|
@@ -2948,6 +2991,7 @@ export default class Component extends Element {
|
|
2948
2991
|
component: this.component,
|
2949
2992
|
data,
|
2950
2993
|
row,
|
2994
|
+
local,
|
2951
2995
|
path: this.path || this.component.key,
|
2952
2996
|
parent: this.parent?.component,
|
2953
2997
|
paths: this.paths,
|
@@ -3122,6 +3166,14 @@ export default class Component extends Element {
|
|
3122
3166
|
data = data || this.rootValue;
|
3123
3167
|
flags = flags || {};
|
3124
3168
|
row = row || this.data;
|
3169
|
+
// Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
|
3170
|
+
// as setValue. Historically, this was bypassed by a series of cached states around the data model
|
3171
|
+
// which caused its own problems. We need to ensure that premium and custom components do not fall into
|
3172
|
+
// an infinite loop by only checking this component once.
|
3173
|
+
if (this.checkingData) {
|
3174
|
+
return;
|
3175
|
+
}
|
3176
|
+
this.checkingData = true;
|
3125
3177
|
// Needs for Nextgen Rules Engine
|
3126
3178
|
this.resetCaches();
|
3127
3179
|
// Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners
|
@@ -3135,6 +3187,8 @@ export default class Component extends Element {
|
|
3135
3187
|
if (this.id !== flags.triggeredComponentId) {
|
3136
3188
|
this.calculateComponentValue(data, flags, row);
|
3137
3189
|
}
|
3190
|
+
// We are done checking data.
|
3191
|
+
this.checkingData = false;
|
3138
3192
|
}
|
3139
3193
|
checkModal(errors = [], dirty = false) {
|
3140
3194
|
const messages = errors.filter(error => !error.fromServer);
|
@@ -3448,7 +3502,7 @@ export default class Component extends Element {
|
|
3448
3502
|
// If component definition changed, replace it.
|
3449
3503
|
if (!_.isEqual(this.component, newComponent)) {
|
3450
3504
|
this.component = newComponent;
|
3451
|
-
const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;
|
3505
|
+
const visible = this.hasCondition() ? !this.conditionallyHidden() : !this.component.hidden;
|
3452
3506
|
const disabled = this.shouldDisabled;
|
3453
3507
|
// Change states which won't be recalculated during redrawing
|
3454
3508
|
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;
|
@@ -20,7 +20,6 @@ export default class AddressComponent extends ContainerComponent {
|
|
20
20
|
key: 'address',
|
21
21
|
switchToManualModeLabel: 'Can\'t find address? Switch to manual mode.',
|
22
22
|
provider: '',
|
23
|
-
providerOptions: {},
|
24
23
|
manualModeViewString: '',
|
25
24
|
hideLabel: false,
|
26
25
|
disableClearIcon: false,
|
@@ -113,20 +112,33 @@ export default class AddressComponent extends ContainerComponent {
|
|
113
112
|
NestedComponent.prototype.addComponents.call(this, this.manualMode ? this.address : {});
|
114
113
|
}
|
115
114
|
Field.prototype.init.call(this);
|
115
|
+
// Added for backwards compatibility
|
116
|
+
if (this.component.providerOptions) {
|
117
|
+
const { params, url, queryProperty, responseProperty, displayValueProperty } = this.component.providerOptions;
|
118
|
+
const key = params?.key;
|
119
|
+
const autocompleteOptions = params?.autocompleteOptions;
|
120
|
+
delete this.component.providerOptions;
|
121
|
+
this.component.url = url;
|
122
|
+
this.component.queryProperty = queryProperty;
|
123
|
+
this.component.responseProperty = responseProperty;
|
124
|
+
this.component.displayValueProperty = displayValueProperty;
|
125
|
+
this.component.apiKey = key;
|
126
|
+
this.component.autocompleteOptions = autocompleteOptions;
|
127
|
+
}
|
128
|
+
let provider = this.component.provider;
|
129
|
+
const providerOptions = this.providerOptions;
|
130
|
+
const map = this.component.map;
|
116
131
|
if (!this.builderMode) {
|
117
|
-
if (
|
118
|
-
const { provider, providerOptions, } = this.component;
|
132
|
+
if (provider) {
|
119
133
|
if (_.get(providerOptions, 'params.subscriptionKey')) {
|
120
134
|
_.set(providerOptions, "params['subscription-key']", _.get(providerOptions, 'params.subscriptionKey'));
|
121
135
|
_.unset(providerOptions, 'params.subscriptionKey');
|
122
136
|
}
|
123
137
|
this.provider = this.initializeProvider(provider, providerOptions);
|
124
138
|
}
|
125
|
-
else if (
|
139
|
+
else if (map) {
|
126
140
|
// Fallback to legacy version where Google Maps was the only provider.
|
127
|
-
this.component.provider = GoogleAddressProvider.name;
|
128
|
-
this.component.providerOptions = this.component.providerOptions || {};
|
129
|
-
const { map, provider, providerOptions, } = this.component;
|
141
|
+
provider = this.component.provider = GoogleAddressProvider.name;
|
130
142
|
const { key, region, } = map;
|
131
143
|
if (key) {
|
132
144
|
_.set(providerOptions, 'params.key', key);
|
@@ -258,6 +270,16 @@ export default class AddressComponent extends ContainerComponent {
|
|
258
270
|
? (this.refs[AddressComponent.modeSwitcherRef] || null)
|
259
271
|
: null;
|
260
272
|
}
|
273
|
+
get providerOptions() {
|
274
|
+
return {
|
275
|
+
params: { subscriptionKey: this.component.subscriptionKey, key: this.component.apiKey, ...this.component.params },
|
276
|
+
url: this.component.url,
|
277
|
+
queryProperty: this.component.queryProperty,
|
278
|
+
responseProperty: this.component.responseProperty,
|
279
|
+
displayValueProperty: this.component.displayValueProperty,
|
280
|
+
autocompleteOptions: this.component.autocompleteOptions
|
281
|
+
};
|
282
|
+
}
|
261
283
|
get removeValueIcon() {
|
262
284
|
return this.refs
|
263
285
|
? (this.refs[AddressComponent.removeValueIconRef] || null)
|
@@ -371,7 +393,8 @@ export default class AddressComponent extends ContainerComponent {
|
|
371
393
|
const result = ((this.builderMode || this.manualMode) ? super.attach : Field.prototype.attach).call(this, element);
|
372
394
|
if (!this.builderMode) {
|
373
395
|
if (!this.provider && this.component.provider) {
|
374
|
-
const
|
396
|
+
const provider = this.component.provider;
|
397
|
+
const providerOptions = this.providerOptions;
|
375
398
|
this.provider = this.initializeProvider(provider, providerOptions);
|
376
399
|
}
|
377
400
|
}
|