@formio/js 5.1.0-rc.27 → 5.1.0-rc.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/formio.embed.js +1 -1
  2. package/dist/formio.embed.min.js +1 -1
  3. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  4. package/dist/formio.form.js +5 -5
  5. package/dist/formio.form.min.js +1 -1
  6. package/dist/formio.form.min.js.LICENSE.txt +1 -1
  7. package/dist/formio.full.js +8 -8
  8. package/dist/formio.full.min.js +1 -1
  9. package/dist/formio.full.min.js.LICENSE.txt +1 -1
  10. package/dist/formio.js +2 -2
  11. package/dist/formio.min.js +1 -1
  12. package/dist/formio.min.js.LICENSE.txt +1 -1
  13. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  14. package/lib/cjs/Embed.js +1 -1
  15. package/lib/cjs/Formio.js +1 -1
  16. package/lib/cjs/components/_classes/component/Component.d.ts +13 -2
  17. package/lib/cjs/components/_classes/component/Component.js +69 -19
  18. package/lib/cjs/components/address/editForm/Address.edit.display.d.ts +4 -0
  19. package/lib/cjs/components/address/editForm/Address.edit.display.js +1 -0
  20. package/lib/cjs/components/editgrid/EditGrid.js +3 -1
  21. package/lib/cjs/components/form/Form.js +1 -1
  22. package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  23. package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -0
  24. package/lib/cjs/components/unknown/Unknown.form.d.ts +1 -0
  25. package/lib/cjs/components/unknown/Unknown.form.js +1 -0
  26. package/lib/mjs/Embed.js +1 -1
  27. package/lib/mjs/Formio.js +1 -1
  28. package/lib/mjs/components/_classes/component/Component.d.ts +13 -2
  29. package/lib/mjs/components/_classes/component/Component.js +69 -19
  30. package/lib/mjs/components/address/editForm/Address.edit.display.d.ts +4 -0
  31. package/lib/mjs/components/address/editForm/Address.edit.display.js +1 -0
  32. package/lib/mjs/components/editgrid/EditGrid.js +3 -1
  33. package/lib/mjs/components/form/Form.js +1 -1
  34. package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  35. package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -0
  36. package/lib/mjs/components/unknown/Unknown.form.d.ts +1 -0
  37. package/lib/mjs/components/unknown/Unknown.form.js +1 -0
  38. package/package.json +1 -1
@@ -20,7 +20,7 @@
20
20
 
21
21
  /*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE */
22
22
 
23
- /*! formiojs v5.1.0-rc.27 | https://unpkg.com/formiojs@5.1.0-rc.27/LICENSE.txt */
23
+ /*! formiojs v5.1.0-rc.29 | https://unpkg.com/formiojs@5.1.0-rc.29/LICENSE.txt */
24
24
 
25
25
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
26
26
 
@@ -20,7 +20,7 @@
20
20
 
21
21
  /*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE */
22
22
 
23
- /*! formiojs v5.1.0-rc.27 | https://unpkg.com/formiojs@5.1.0-rc.27/LICENSE.txt */
23
+ /*! formiojs v5.1.0-rc.29 | https://unpkg.com/formiojs@5.1.0-rc.29/LICENSE.txt */
24
24
 
25
25
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
26
26
 
package/lib/cjs/Embed.js CHANGED
@@ -418,7 +418,7 @@ Formio.formioReady = new Promise((ready, reject) => {
418
418
  _a._formioReady = ready;
419
419
  _a._formioReadyReject = reject;
420
420
  });
421
- Formio.version = '5.1.0-rc.27';
421
+ Formio.version = '5.1.0-rc.29';
422
422
  // Create a report.
423
423
  Formio.Report = {
424
424
  create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
package/lib/cjs/Formio.js CHANGED
@@ -11,7 +11,7 @@ const CDN_1 = __importDefault(require("./CDN"));
11
11
  const providers_1 = __importDefault(require("./providers"));
12
12
  sdk_1.Formio.cdn = new CDN_1.default();
13
13
  sdk_1.Formio.Providers = providers_1.default;
14
- sdk_1.Formio.version = '5.1.0-rc.27';
14
+ sdk_1.Formio.version = '5.1.0-rc.29';
15
15
  CDN_1.default.defaultCDN = sdk_1.Formio.version.includes('rc') ? 'https://cdn.test-form.io' : 'https://cdn.form.io';
16
16
  const isNil = (val) => val === null || val === undefined;
17
17
  sdk_1.Formio.prototype.uploadFile = function (storage, file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, uploadStartCallback, abortCallback, multipartOptions) {
@@ -163,6 +163,7 @@ declare class Component extends Element {
163
163
  */
164
164
  info: any;
165
165
  get componentsMap(): object;
166
+ parentShouldConditionallyClear(): boolean;
166
167
  parentConditionallyHidden(): boolean;
167
168
  set data(value: any);
168
169
  get data(): any;
@@ -227,7 +228,8 @@ declare class Component extends Element {
227
228
  get visible(): boolean;
228
229
  get logicallyHidden(): any;
229
230
  _logicallyHidden: any;
230
- conditionallyHidden(skipParent?: boolean): any;
231
+ shouldConditionallyClear(skipParent?: boolean): boolean;
232
+ conditionallyHidden(skipParent?: boolean): boolean;
231
233
  set currentForm(instance: any);
232
234
  get currentForm(): any;
233
235
  _currentForm: any;
@@ -890,7 +892,15 @@ declare class Component extends Element {
890
892
  * @returns {boolean} - TRUE if a default value is set.
891
893
  */
892
894
  get hasDefaultValue(): boolean;
895
+ /**
896
+ * Determine if we should add a default value for this component.
897
+ * @returns {boolean} - TRUE if a default value should be set
898
+ */
893
899
  get shouldAddDefaultValue(): boolean;
900
+ /**
901
+ * Get the default value of this component.
902
+ * @returns {*} - The default value for this component.
903
+ */
894
904
  get defaultValue(): any;
895
905
  /**
896
906
  * Get the input value of this component.
@@ -1000,9 +1010,10 @@ declare class Component extends Element {
1000
1010
  * @param {boolean} dirty - If the component is dirty.
1001
1011
  * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
1002
1012
  * @param {*} row - Contextual row data for this component.
1013
+ * @param {*} options - Additional options for validation.
1003
1014
  * @returns {string} - The message to show when the component is invalid.
1004
1015
  */
1005
- invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any): string;
1016
+ invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any, options?: any): string;
1006
1017
  /**
1007
1018
  * Returns if the component is valid or not.
1008
1019
  * @param {*} data - The data to check if the component is valid.
@@ -414,7 +414,7 @@ class Component extends Element_1.default {
414
414
  if (this.allowData && this.key) {
415
415
  this.options.name += `[${this.key}]`;
416
416
  // If component is visible or not set to clear on hide, set the default value.
417
- if (!(this.conditionallyHidden() && this.component.clearOnHide)) {
417
+ if (!this.shouldConditionallyClear()) {
418
418
  if (!this.hasValue()) {
419
419
  if (this.shouldAddDefaultValue) {
420
420
  this.dataValue = this.defaultValue;
@@ -445,6 +445,16 @@ class Component extends Element_1.default {
445
445
  var _a;
446
446
  return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.childComponentsMap) || {};
447
447
  }
448
+ parentShouldConditionallyClear() {
449
+ let currentParent = this.parent;
450
+ while (currentParent) {
451
+ if (currentParent.shouldConditionallyClear(true)) {
452
+ return true;
453
+ }
454
+ currentParent = currentParent.parent;
455
+ }
456
+ return false;
457
+ }
448
458
  parentConditionallyHidden() {
449
459
  let currentParent = this.parent;
450
460
  while (currentParent) {
@@ -663,11 +673,48 @@ class Component extends Element_1.default {
663
673
  }
664
674
  return this._logicallyHidden;
665
675
  }
676
+ shouldConditionallyClear(skipParent = false) {
677
+ // Skip if this component has clearOnHide set to false.
678
+ if (this.component.clearOnHide === false) {
679
+ return false;
680
+ }
681
+ // If the component is logically hidden, then it is conditionally hidden and should clear.
682
+ if (this.logicallyHidden) {
683
+ return true;
684
+ }
685
+ // If we have a condition and it is not conditionally visible, the it should conditionally clear.
686
+ if (this.hasCondition() && !this.conditionallyVisible()) {
687
+ return true;
688
+ }
689
+ if (skipParent) {
690
+ // Stop recurrsion for the parent checks.
691
+ return false;
692
+ }
693
+ // If this component has a set value, then it should ONLY clear if a parent is hidden
694
+ // and has the clearOnHide set to true.
695
+ if (this.hasSetValue) {
696
+ return this.parentShouldConditionallyClear();
697
+ }
698
+ // Clear the value if the parent is conditionally hidden.
699
+ return this.parentConditionallyHidden();
700
+ }
666
701
  conditionallyHidden(skipParent = false) {
667
- if (!this.hasCondition()) {
668
- return this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
702
+ if (this.logicallyHidden) {
703
+ return true;
704
+ }
705
+ if (!this.hasCondition() && !skipParent) {
706
+ return this.parentConditionallyHidden();
707
+ }
708
+ // Return if we are not conditionally visible (conditionallyHidden)
709
+ if (!this.conditionallyVisible()) {
710
+ return true;
711
+ }
712
+ if (skipParent) {
713
+ // Stop recurrsion for the parent checks.
714
+ return false;
669
715
  }
670
- return !this.conditionallyVisible() || this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
716
+ // Check the parent.
717
+ return this.parentConditionallyHidden();
671
718
  }
672
719
  get currentForm() {
673
720
  return this._currentForm;
@@ -2066,7 +2113,7 @@ class Component extends Element_1.default {
2066
2113
  component: newComponent,
2067
2114
  result,
2068
2115
  });
2069
- if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2116
+ if (!lodash_1.default.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
2070
2117
  this.setValue(newValue);
2071
2118
  if (this.viewOnly) {
2072
2119
  this.dataValue = newValue;
@@ -2099,7 +2146,7 @@ class Component extends Element_1.default {
2099
2146
  component: newComponent,
2100
2147
  result,
2101
2148
  }, 'value');
2102
- if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2149
+ if (!lodash_1.default.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
2103
2150
  this.setValue(newValue);
2104
2151
  if (this.viewOnly) {
2105
2152
  this.dataValue = newValue;
@@ -2205,7 +2252,7 @@ class Component extends Element_1.default {
2205
2252
  clearComponentOnHide() {
2206
2253
  // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
2207
2254
  if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
2208
- if (this.conditionallyHidden()) {
2255
+ if (this.shouldConditionallyClear()) {
2209
2256
  this.deleteValue();
2210
2257
  }
2211
2258
  else if (!this.hasValue() && this.shouldAddDefaultValue) {
@@ -2526,15 +2573,17 @@ class Component extends Element_1.default {
2526
2573
  (this.component.defaultValue !== null) &&
2527
2574
  (this.component.defaultValue !== undefined));
2528
2575
  }
2576
+ /**
2577
+ * Determine if we should add a default value for this component.
2578
+ * @returns {boolean} - TRUE if a default value should be set
2579
+ */
2529
2580
  get shouldAddDefaultValue() {
2530
- // It should add a default value if...
2531
- // 1.) Ensure they have not set "noDefaults". If that is true, then will always return false. AND
2532
- // 2.) The component is pristine (user has not manually modified it). AND
2533
- // 3.) There is a default value setting present and it is not NULL or UNDEFINED.
2534
- return !this.options.noDefaults && this.pristine && (this.hasDefaultValue ||
2535
- // Empty strings and booleans are allowed primitives whose defaults are automatically added.
2536
- (this.emptyValue === '' || (typeof this.emptyValue === 'boolean')));
2581
+ return this.pristine && this.allowData && (this.hasDefaultValue || !this.options.noDefaults);
2537
2582
  }
2583
+ /**
2584
+ * Get the default value of this component.
2585
+ * @returns {*} - The default value for this component.
2586
+ */
2538
2587
  get defaultValue() {
2539
2588
  let defaultValue = this.emptyValue;
2540
2589
  if (this.component.defaultValue) {
@@ -2805,10 +2854,8 @@ class Component extends Element_1.default {
2805
2854
  }
2806
2855
  // If no calculated value or
2807
2856
  // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
2808
- const { clearOnHide } = this.component;
2809
- const shouldBeCleared = this.conditionallyHidden() && clearOnHide;
2810
2857
  const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);
2811
- if (shouldBeCleared) {
2858
+ if (this.shouldConditionallyClear()) {
2812
2859
  // remove calculated value so that the value is recalculated once component becomes visible
2813
2860
  if (this.hasOwnProperty('calculatedValue') && allowOverride) {
2814
2861
  lodash_1.default.unset(this, 'calculatedValue');
@@ -2929,10 +2976,12 @@ class Component extends Element_1.default {
2929
2976
  * @param {boolean} dirty - If the component is dirty.
2930
2977
  * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
2931
2978
  * @param {*} row - Contextual row data for this component.
2979
+ * @param {*} options - Additional options for validation.
2932
2980
  * @returns {string} - The message to show when the component is invalid.
2933
2981
  */
2934
- invalidMessage(data, dirty, ignoreCondition, row) {
2982
+ invalidMessage(data, dirty, ignoreCondition, row, options = {}) {
2935
2983
  var _a;
2984
+ const { local } = options;
2936
2985
  if (!row) {
2937
2986
  row = (0, utils_1.getContextualRowData)(this.component, data, this.paths);
2938
2987
  }
@@ -2952,6 +3001,7 @@ class Component extends Element_1.default {
2952
3001
  component: this.component,
2953
3002
  data,
2954
3003
  row,
3004
+ local,
2955
3005
  path: this.path || this.component.key,
2956
3006
  parent: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component,
2957
3007
  paths: this.paths,
@@ -3130,7 +3180,7 @@ class Component extends Element_1.default {
3130
3180
  row = row || this.data;
3131
3181
  // Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
3132
3182
  // as setValue. Historically, this was bypassed by a series of cached states around the data model
3133
- // which caused its own problems. We need to ensure that premium and custom components do not fall into
3183
+ // which caused its own problems. We need to ensure that premium and custom components do not fall into
3134
3184
  // an infinite loop by only checking this component once.
3135
3185
  if (this.checkingData) {
3136
3186
  return;
@@ -8,6 +8,7 @@ declare const _default: ({
8
8
  customConditional: ({ data }: {
9
9
  data: any;
10
10
  }) => boolean;
11
+ defaultValue?: undefined;
11
12
  placeholder?: undefined;
12
13
  validate?: undefined;
13
14
  } | {
@@ -15,6 +16,7 @@ declare const _default: ({
15
16
  type: string;
16
17
  input: boolean;
17
18
  key: string;
19
+ defaultValue: string;
18
20
  label: string;
19
21
  placeholder: string;
20
22
  tooltip: string;
@@ -32,6 +34,7 @@ declare const _default: ({
32
34
  label: string;
33
35
  tooltip: string;
34
36
  customConditional?: undefined;
37
+ defaultValue?: undefined;
35
38
  placeholder?: undefined;
36
39
  validate?: undefined;
37
40
  } | {
@@ -45,6 +48,7 @@ declare const _default: ({
45
48
  customConditional: ({ data }: {
46
49
  data: any;
47
50
  }) => any;
51
+ defaultValue?: undefined;
48
52
  validate?: undefined;
49
53
  })[];
50
54
  export default _default;
@@ -15,6 +15,7 @@ exports.default = [
15
15
  type: 'textfield',
16
16
  input: true,
17
17
  key: 'switchToManualModeLabel',
18
+ defaultValue: 'Can\'t find address? Switch to manual mode.',
18
19
  label: 'Switch To Manual Mode Label',
19
20
  placeholder: 'Switch To Manual Mode Label',
20
21
  tooltip: 'The label for the checkbox used to switch to manual mode.',
@@ -1089,7 +1089,9 @@ class EditGridComponent extends NestedArrayComponent_1.default {
1089
1089
  errors.push(...this._errors);
1090
1090
  return false;
1091
1091
  }
1092
- const message = this.invalid || this.invalidMessage(data, dirty, false, row);
1092
+ // TODO: this is the only place invalidMessage gets called, and it's not clear why it's needed - we already validate the editGrid
1093
+ // component above with super.checkComponentValidity
1094
+ const message = this.invalid || this.invalidMessage(data, dirty, false, row, options);
1093
1095
  if (allRowErrors.length && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted) && !message) {
1094
1096
  this._errors = this.setCustomValidity(message, dirty);
1095
1097
  errors.push(...this._errors);
@@ -523,7 +523,7 @@ class FormComponent extends Component_1.default {
523
523
  * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
524
524
  */
525
525
  get shouldSubmit() {
526
- return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden() || !this.component.clearOnHide);
526
+ return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.shouldConditionallyClear();
527
527
  }
528
528
  /**
529
529
  * Returns the data for the subform.
@@ -172,6 +172,7 @@ declare const _default: ({
172
172
  key: string;
173
173
  tooltip: string;
174
174
  weight: number;
175
+ defaultValue: boolean;
175
176
  conditional: {
176
177
  json: {
177
178
  and: ({
@@ -192,7 +193,6 @@ declare const _default: ({
192
193
  data?: undefined;
193
194
  as?: undefined;
194
195
  editor?: undefined;
195
- defaultValue?: undefined;
196
196
  description?: undefined;
197
197
  reorder?: undefined;
198
198
  components?: undefined;
@@ -119,6 +119,7 @@ exports.default = [
119
119
  key: 'lazyLoad',
120
120
  tooltip: 'When set, this will not fire off the request to the URL until this control is within focus. This can improve performance if you have many Select dropdowns on your form where the API\'s will only fire when the control is activated.',
121
121
  weight: 11,
122
+ defaultValue: true,
122
123
  conditional: {
123
124
  json: {
124
125
  and: [
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Unknown Component schema.
3
+ * @param {...any} extend
3
4
  * @returns {object} - The Unknown Component edit form.
4
5
  */
5
6
  export default function _default(): object;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const Unknown_edit_display_1 = __importDefault(require("./editForm/Unknown.edit.display"));
7
7
  /**
8
8
  * Unknown Component schema.
9
+ * @param {...any} extend
9
10
  * @returns {object} - The Unknown Component edit form.
10
11
  */
11
12
  function default_1() {
package/lib/mjs/Embed.js CHANGED
@@ -14,7 +14,7 @@ export class Formio {
14
14
  Formio._formioReady = ready;
15
15
  Formio._formioReadyReject = reject;
16
16
  });
17
- static version = '5.1.0-rc.27';
17
+ static version = '5.1.0-rc.29';
18
18
  static setLicense(license, norecurse = false) {
19
19
  Formio.license = license;
20
20
  if (!norecurse && Formio.FormioClass) {
package/lib/mjs/Formio.js CHANGED
@@ -4,7 +4,7 @@ import CDN from './CDN';
4
4
  import Providers from './providers';
5
5
  FormioCore.cdn = new CDN();
6
6
  FormioCore.Providers = Providers;
7
- FormioCore.version = '5.1.0-rc.27';
7
+ FormioCore.version = '5.1.0-rc.29';
8
8
  CDN.defaultCDN = FormioCore.version.includes('rc') ? 'https://cdn.test-form.io' : 'https://cdn.form.io';
9
9
  const isNil = (val) => val === null || val === undefined;
10
10
  FormioCore.prototype.uploadFile = function (storage, file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, uploadStartCallback, abortCallback, multipartOptions) {
@@ -163,6 +163,7 @@ declare class Component extends Element {
163
163
  */
164
164
  info: any;
165
165
  get componentsMap(): object;
166
+ parentShouldConditionallyClear(): boolean;
166
167
  parentConditionallyHidden(): boolean;
167
168
  set data(value: any);
168
169
  get data(): any;
@@ -227,7 +228,8 @@ declare class Component extends Element {
227
228
  get visible(): boolean;
228
229
  get logicallyHidden(): any;
229
230
  _logicallyHidden: any;
230
- conditionallyHidden(skipParent?: boolean): any;
231
+ shouldConditionallyClear(skipParent?: boolean): boolean;
232
+ conditionallyHidden(skipParent?: boolean): boolean;
231
233
  set currentForm(instance: any);
232
234
  get currentForm(): any;
233
235
  _currentForm: any;
@@ -890,7 +892,15 @@ declare class Component extends Element {
890
892
  * @returns {boolean} - TRUE if a default value is set.
891
893
  */
892
894
  get hasDefaultValue(): boolean;
895
+ /**
896
+ * Determine if we should add a default value for this component.
897
+ * @returns {boolean} - TRUE if a default value should be set
898
+ */
893
899
  get shouldAddDefaultValue(): boolean;
900
+ /**
901
+ * Get the default value of this component.
902
+ * @returns {*} - The default value for this component.
903
+ */
894
904
  get defaultValue(): any;
895
905
  /**
896
906
  * Get the input value of this component.
@@ -1000,9 +1010,10 @@ declare class Component extends Element {
1000
1010
  * @param {boolean} dirty - If the component is dirty.
1001
1011
  * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
1002
1012
  * @param {*} row - Contextual row data for this component.
1013
+ * @param {*} options - Additional options for validation.
1003
1014
  * @returns {string} - The message to show when the component is invalid.
1004
1015
  */
1005
- invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any): string;
1016
+ invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any, options?: any): string;
1006
1017
  /**
1007
1018
  * Returns if the component is valid or not.
1008
1019
  * @param {*} data - The data to check if the component is valid.
@@ -388,7 +388,7 @@ export default class Component extends Element {
388
388
  if (this.allowData && this.key) {
389
389
  this.options.name += `[${this.key}]`;
390
390
  // If component is visible or not set to clear on hide, set the default value.
391
- if (!(this.conditionallyHidden() && this.component.clearOnHide)) {
391
+ if (!this.shouldConditionallyClear()) {
392
392
  if (!this.hasValue()) {
393
393
  if (this.shouldAddDefaultValue) {
394
394
  this.dataValue = this.defaultValue;
@@ -418,6 +418,16 @@ export default class Component extends Element {
418
418
  get componentsMap() {
419
419
  return this.root?.childComponentsMap || {};
420
420
  }
421
+ parentShouldConditionallyClear() {
422
+ let currentParent = this.parent;
423
+ while (currentParent) {
424
+ if (currentParent.shouldConditionallyClear(true)) {
425
+ return true;
426
+ }
427
+ currentParent = currentParent.parent;
428
+ }
429
+ return false;
430
+ }
421
431
  parentConditionallyHidden() {
422
432
  let currentParent = this.parent;
423
433
  while (currentParent) {
@@ -636,11 +646,48 @@ export default class Component extends Element {
636
646
  }
637
647
  return this._logicallyHidden;
638
648
  }
649
+ shouldConditionallyClear(skipParent = false) {
650
+ // Skip if this component has clearOnHide set to false.
651
+ if (this.component.clearOnHide === false) {
652
+ return false;
653
+ }
654
+ // If the component is logically hidden, then it is conditionally hidden and should clear.
655
+ if (this.logicallyHidden) {
656
+ return true;
657
+ }
658
+ // If we have a condition and it is not conditionally visible, the it should conditionally clear.
659
+ if (this.hasCondition() && !this.conditionallyVisible()) {
660
+ return true;
661
+ }
662
+ if (skipParent) {
663
+ // Stop recurrsion for the parent checks.
664
+ return false;
665
+ }
666
+ // If this component has a set value, then it should ONLY clear if a parent is hidden
667
+ // and has the clearOnHide set to true.
668
+ if (this.hasSetValue) {
669
+ return this.parentShouldConditionallyClear();
670
+ }
671
+ // Clear the value if the parent is conditionally hidden.
672
+ return this.parentConditionallyHidden();
673
+ }
639
674
  conditionallyHidden(skipParent = false) {
640
- if (!this.hasCondition()) {
641
- return this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
675
+ if (this.logicallyHidden) {
676
+ return true;
677
+ }
678
+ if (!this.hasCondition() && !skipParent) {
679
+ return this.parentConditionallyHidden();
680
+ }
681
+ // Return if we are not conditionally visible (conditionallyHidden)
682
+ if (!this.conditionallyVisible()) {
683
+ return true;
684
+ }
685
+ if (skipParent) {
686
+ // Stop recurrsion for the parent checks.
687
+ return false;
642
688
  }
643
- return !this.conditionallyVisible() || this.logicallyHidden || (skipParent ? false : this.parentConditionallyHidden());
689
+ // Check the parent.
690
+ return this.parentConditionallyHidden();
644
691
  }
645
692
  get currentForm() {
646
693
  return this._currentForm;
@@ -2041,7 +2088,7 @@ export default class Component extends Element {
2041
2088
  component: newComponent,
2042
2089
  result,
2043
2090
  });
2044
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2091
+ if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
2045
2092
  this.setValue(newValue);
2046
2093
  if (this.viewOnly) {
2047
2094
  this.dataValue = newValue;
@@ -2074,7 +2121,7 @@ export default class Component extends Element {
2074
2121
  component: newComponent,
2075
2122
  result,
2076
2123
  }, 'value');
2077
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden())) {
2124
+ if (!_.isEqual(oldValue, newValue) && !this.shouldConditionallyClear()) {
2078
2125
  this.setValue(newValue);
2079
2126
  if (this.viewOnly) {
2080
2127
  this.dataValue = newValue;
@@ -2180,7 +2227,7 @@ export default class Component extends Element {
2180
2227
  clearComponentOnHide() {
2181
2228
  // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
2182
2229
  if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
2183
- if (this.conditionallyHidden()) {
2230
+ if (this.shouldConditionallyClear()) {
2184
2231
  this.deleteValue();
2185
2232
  }
2186
2233
  else if (!this.hasValue() && this.shouldAddDefaultValue) {
@@ -2506,15 +2553,17 @@ export default class Component extends Element {
2506
2553
  (this.component.defaultValue !== null) &&
2507
2554
  (this.component.defaultValue !== undefined));
2508
2555
  }
2556
+ /**
2557
+ * Determine if we should add a default value for this component.
2558
+ * @returns {boolean} - TRUE if a default value should be set
2559
+ */
2509
2560
  get shouldAddDefaultValue() {
2510
- // It should add a default value if...
2511
- // 1.) Ensure they have not set "noDefaults". If that is true, then will always return false. AND
2512
- // 2.) The component is pristine (user has not manually modified it). AND
2513
- // 3.) There is a default value setting present and it is not NULL or UNDEFINED.
2514
- return !this.options.noDefaults && this.pristine && (this.hasDefaultValue ||
2515
- // Empty strings and booleans are allowed primitives whose defaults are automatically added.
2516
- (this.emptyValue === '' || (typeof this.emptyValue === 'boolean')));
2561
+ return this.pristine && this.allowData && (this.hasDefaultValue || !this.options.noDefaults);
2517
2562
  }
2563
+ /**
2564
+ * Get the default value of this component.
2565
+ * @returns {*} - The default value for this component.
2566
+ */
2518
2567
  get defaultValue() {
2519
2568
  let defaultValue = this.emptyValue;
2520
2569
  if (this.component.defaultValue) {
@@ -2784,10 +2833,8 @@ export default class Component extends Element {
2784
2833
  }
2785
2834
  // If no calculated value or
2786
2835
  // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
2787
- const { clearOnHide } = this.component;
2788
- const shouldBeCleared = this.conditionallyHidden() && clearOnHide;
2789
2836
  const allowOverride = _.get(this.component, 'allowCalculateOverride', false);
2790
- if (shouldBeCleared) {
2837
+ if (this.shouldConditionallyClear()) {
2791
2838
  // remove calculated value so that the value is recalculated once component becomes visible
2792
2839
  if (this.hasOwnProperty('calculatedValue') && allowOverride) {
2793
2840
  _.unset(this, 'calculatedValue');
@@ -2908,9 +2955,11 @@ export default class Component extends Element {
2908
2955
  * @param {boolean} dirty - If the component is dirty.
2909
2956
  * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
2910
2957
  * @param {*} row - Contextual row data for this component.
2958
+ * @param {*} options - Additional options for validation.
2911
2959
  * @returns {string} - The message to show when the component is invalid.
2912
2960
  */
2913
- invalidMessage(data, dirty, ignoreCondition, row) {
2961
+ invalidMessage(data, dirty, ignoreCondition, row, options = {}) {
2962
+ const { local } = options;
2914
2963
  if (!row) {
2915
2964
  row = getContextualRowData(this.component, data, this.paths);
2916
2965
  }
@@ -2930,6 +2979,7 @@ export default class Component extends Element {
2930
2979
  component: this.component,
2931
2980
  data,
2932
2981
  row,
2982
+ local,
2933
2983
  path: this.path || this.component.key,
2934
2984
  parent: this.parent?.component,
2935
2985
  paths: this.paths,
@@ -3106,7 +3156,7 @@ export default class Component extends Element {
3106
3156
  row = row || this.data;
3107
3157
  // Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
3108
3158
  // as setValue. Historically, this was bypassed by a series of cached states around the data model
3109
- // which caused its own problems. We need to ensure that premium and custom components do not fall into
3159
+ // which caused its own problems. We need to ensure that premium and custom components do not fall into
3110
3160
  // an infinite loop by only checking this component once.
3111
3161
  if (this.checkingData) {
3112
3162
  return;
@@ -8,6 +8,7 @@ declare const _default: ({
8
8
  customConditional: ({ data }: {
9
9
  data: any;
10
10
  }) => boolean;
11
+ defaultValue?: undefined;
11
12
  placeholder?: undefined;
12
13
  validate?: undefined;
13
14
  } | {
@@ -15,6 +16,7 @@ declare const _default: ({
15
16
  type: string;
16
17
  input: boolean;
17
18
  key: string;
19
+ defaultValue: string;
18
20
  label: string;
19
21
  placeholder: string;
20
22
  tooltip: string;
@@ -32,6 +34,7 @@ declare const _default: ({
32
34
  label: string;
33
35
  tooltip: string;
34
36
  customConditional?: undefined;
37
+ defaultValue?: undefined;
35
38
  placeholder?: undefined;
36
39
  validate?: undefined;
37
40
  } | {
@@ -45,6 +48,7 @@ declare const _default: ({
45
48
  customConditional: ({ data }: {
46
49
  data: any;
47
50
  }) => any;
51
+ defaultValue?: undefined;
48
52
  validate?: undefined;
49
53
  })[];
50
54
  export default _default;
@@ -13,6 +13,7 @@ export default [
13
13
  type: 'textfield',
14
14
  input: true,
15
15
  key: 'switchToManualModeLabel',
16
+ defaultValue: 'Can\'t find address? Switch to manual mode.',
16
17
  label: 'Switch To Manual Mode Label',
17
18
  placeholder: 'Switch To Manual Mode Label',
18
19
  tooltip: 'The label for the checkbox used to switch to manual mode.',
@@ -1081,7 +1081,9 @@ export default class EditGridComponent extends NestedArrayComponent {
1081
1081
  errors.push(...this._errors);
1082
1082
  return false;
1083
1083
  }
1084
- const message = this.invalid || this.invalidMessage(data, dirty, false, row);
1084
+ // TODO: this is the only place invalidMessage gets called, and it's not clear why it's needed - we already validate the editGrid
1085
+ // component above with super.checkComponentValidity
1086
+ const message = this.invalid || this.invalidMessage(data, dirty, false, row, options);
1085
1087
  if (allRowErrors.length && this.root?.submitted && !message) {
1086
1088
  this._errors = this.setCustomValidity(message, dirty);
1087
1089
  errors.push(...this._errors);