@formio/js 5.1.0-rc.23 → 5.1.0-rc.25

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 (44) 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 +29 -51
  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 +31 -53
  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.js +1 -1
  14. package/dist/formio.utils.min.js +1 -1
  15. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  16. package/lib/cjs/Embed.js +1 -1
  17. package/lib/cjs/Formio.js +1 -1
  18. package/lib/cjs/WebformBuilder.js +4 -0
  19. package/lib/cjs/Wizard.js +6 -3
  20. package/lib/cjs/components/_classes/component/Component.d.ts +14 -0
  21. package/lib/cjs/components/_classes/component/Component.js +35 -11
  22. package/lib/cjs/components/_classes/nested/NestedComponent.d.ts +0 -1
  23. package/lib/cjs/components/_classes/nested/NestedComponent.js +0 -11
  24. package/lib/cjs/components/address/Address.d.ts +1 -0
  25. package/lib/cjs/components/datagrid/DataGrid.js +0 -3
  26. package/lib/cjs/components/editgrid/EditGrid.js +0 -8
  27. package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -1
  28. package/lib/cjs/utils/utils.d.ts +0 -8
  29. package/lib/cjs/utils/utils.js +1 -22
  30. package/lib/mjs/Embed.js +1 -1
  31. package/lib/mjs/Formio.js +1 -1
  32. package/lib/mjs/WebformBuilder.js +4 -0
  33. package/lib/mjs/Wizard.js +5 -2
  34. package/lib/mjs/components/_classes/component/Component.d.ts +14 -0
  35. package/lib/mjs/components/_classes/component/Component.js +36 -12
  36. package/lib/mjs/components/_classes/nested/NestedComponent.d.ts +0 -1
  37. package/lib/mjs/components/_classes/nested/NestedComponent.js +0 -11
  38. package/lib/mjs/components/address/Address.d.ts +1 -0
  39. package/lib/mjs/components/datagrid/DataGrid.js +0 -3
  40. package/lib/mjs/components/editgrid/EditGrid.js +0 -7
  41. package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -1
  42. package/lib/mjs/utils/utils.d.ts +0 -8
  43. package/lib/mjs/utils/utils.js +0 -20
  44. package/package.json +3 -3
@@ -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.23 | https://unpkg.com/formiojs@5.1.0-rc.23/LICENSE.txt */
23
+ /*! formiojs v5.1.0-rc.25 | https://unpkg.com/formiojs@5.1.0-rc.25/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.23';
421
+ Formio.version = '5.1.0-rc.25';
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.23';
14
+ sdk_1.Formio.version = '5.1.0-rc.25';
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) {
@@ -1634,6 +1634,10 @@ class WebformBuilder extends Component_1.default {
1634
1634
  info.type);
1635
1635
  }
1636
1636
  hasEditTabs(type) {
1637
+ // If the component type does not exist then it has no edit tabs
1638
+ if (!Components_1.default.components[type]) {
1639
+ return false;
1640
+ }
1637
1641
  const editTabs = (0, formUtils_1.getComponent)(Components_1.default.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
1638
1642
  const hiddenEditTabs = lodash_1.default.filter(lodash_1.default.get(this.options, `editForm.${type}`, []), 'ignore');
1639
1643
  return lodash_1.default.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
package/lib/cjs/Wizard.js CHANGED
@@ -602,7 +602,7 @@ class Wizard extends Webform_1.default {
602
602
  }
603
603
  this.redraw().then(() => {
604
604
  this.checkData(this.submission.data);
605
- this.triggerCaptcha(this.currentPanel.components);
605
+ this.triggerCaptcha(this.currentPage.components);
606
606
  const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
607
607
  if (this.alert) {
608
608
  this.showErrors(errors, true, true);
@@ -726,10 +726,13 @@ class Wizard extends Webform_1.default {
726
726
  }
727
727
  }
728
728
  validateCurrentPage(flags = {}) {
729
- var _a, _b;
729
+ var _a, _b, _c, _d;
730
730
  const components = (_a = this.currentPage) === null || _a === void 0 ? void 0 : _a.components.map((component) => component.component);
731
731
  // Accessing the parent ensures the right instance (whether it's the parent Wizard or a nested Wizard) performs its validation
732
- return (_b = this.currentPage) === null || _b === void 0 ? void 0 : _b.parent.validateComponents(components, this.root.data, flags);
732
+ if ((_b = this.currentPage) === null || _b === void 0 ? void 0 : _b.parent) {
733
+ return (_c = this.currentPage) === null || _c === void 0 ? void 0 : _c.parent.validateComponents(components, this.root.data, flags);
734
+ }
735
+ return (_d = this.currentPage) === null || _d === void 0 ? void 0 : _d.validateComponents(components, this.root ? this.root.data : this.data, flags);
733
736
  }
734
737
  emitPrevPage() {
735
738
  this.emit('prevPage', { page: this.page, submission: this.submission });
@@ -129,6 +129,16 @@ declare class Component extends Element {
129
129
  * The reference attribute name for this component
130
130
  */
131
131
  _referenceAttributeName: string;
132
+ /**
133
+ * Sometimes the customDefaultValue does not set the "value" within the script, but is just a script to execute. This
134
+ * flag is used to determine if the customDefaultValue should be used to set the value of the component or not based on
135
+ * if there is a "value=" within the script.
136
+ */
137
+ shouldSetCustomDefault: any;
138
+ /**
139
+ * Same as customDefaultValue, but for calculateValue.
140
+ */
141
+ shouldSetCalculatedValue: any;
132
142
  triggerChange: (...args: any[]) => any;
133
143
  /**
134
144
  * Used to trigger a redraw event within this component.
@@ -778,6 +788,10 @@ declare class Component extends Element {
778
788
  * @returns {void}
779
789
  */
780
790
  setElementInvalid(element: HTMLElement, invalid: boolean): void;
791
+ /**
792
+ * Clear any conditionally hidden components for this component only.
793
+ */
794
+ clearComponentOnHide(): void;
781
795
  /**
782
796
  * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
783
797
  */
@@ -351,6 +351,22 @@ class Component extends Element_1.default {
351
351
  * The reference attribute name for this component
352
352
  */
353
353
  this._referenceAttributeName = 'ref';
354
+ /**
355
+ * Sometimes the customDefaultValue does not set the "value" within the script, but is just a script to execute. This
356
+ * flag is used to determine if the customDefaultValue should be used to set the value of the component or not based on
357
+ * if there is a "value=" within the script.
358
+ */
359
+ this.shouldSetCustomDefault = true;
360
+ if (this.component.customDefaultValue && (typeof this.component.customDefaultValue === 'string')) {
361
+ this.shouldSetCustomDefault = this.component.customDefaultValue.match(/value\s*=/);
362
+ }
363
+ /**
364
+ * Same as customDefaultValue, but for calculateValue.
365
+ */
366
+ this.shouldSetCalculatedValue = true;
367
+ if (this.component.calculateValue && (typeof this.component.calculateValue === 'string')) {
368
+ this.shouldSetCalculatedValue = this.component.calculateValue.match(/value\s*=/);
369
+ }
354
370
  /**
355
371
  * Used to trigger a new change in this component.
356
372
  * @type {Function} - Call to trigger a change in this component.
@@ -1940,7 +1956,7 @@ class Component extends Element_1.default {
1940
1956
  if (this.visible !== visible) {
1941
1957
  this.visible = visible;
1942
1958
  }
1943
- this.clearOnHide();
1959
+ this.clearComponentOnHide();
1944
1960
  return visible;
1945
1961
  }
1946
1962
  /**
@@ -2200,16 +2216,11 @@ class Component extends Element_1.default {
2200
2216
  element.setAttribute('aria-invalid', invalid ? 'true' : 'false');
2201
2217
  }
2202
2218
  /**
2203
- * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
2219
+ * Clear any conditionally hidden components for this component only.
2204
2220
  */
2205
- clearOnHide() {
2221
+ clearComponentOnHide() {
2206
2222
  // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
2207
- if (
2208
- // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true
2209
- (!this.rootPristine || this.options.server || (0, utils_1.isInsideScopingComponent)(this)) &&
2210
- this.component.clearOnHide !== false &&
2211
- !this.options.readOnly &&
2212
- !this.options.showHiddenFields) {
2223
+ if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
2213
2224
  if (this.conditionallyHidden()) {
2214
2225
  this.deleteValue();
2215
2226
  }
@@ -2221,6 +2232,12 @@ class Component extends Element_1.default {
2221
2232
  }
2222
2233
  }
2223
2234
  }
2235
+ /**
2236
+ * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
2237
+ */
2238
+ clearOnHide() {
2239
+ this.clearComponentOnHide();
2240
+ }
2224
2241
  /**
2225
2242
  * Triggers a debounced onChange event for the root component (usually Webform).
2226
2243
  * @param {...any} args - The arguments to pass to the onChange event.
@@ -2512,7 +2529,10 @@ class Component extends Element_1.default {
2512
2529
  }
2513
2530
  getCustomDefaultValue(defaultValue) {
2514
2531
  if (this.component.customDefaultValue && !this.options.preview) {
2515
- defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');
2532
+ const customDefaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');
2533
+ if (this.shouldSetCustomDefault) {
2534
+ defaultValue = customDefaultValue;
2535
+ }
2516
2536
  }
2517
2537
  return defaultValue;
2518
2538
  }
@@ -2772,7 +2792,7 @@ class Component extends Element_1.default {
2772
2792
  }
2773
2793
  doValueCalculation(dataValue, data, row) {
2774
2794
  var _a;
2775
- return this.evaluate(this.component.calculateValue, {
2795
+ const calculatedValue = this.evaluate(this.component.calculateValue, {
2776
2796
  value: dataValue,
2777
2797
  data,
2778
2798
  row: row || this.data,
@@ -2780,6 +2800,10 @@ class Component extends Element_1.default {
2780
2800
  data: this.rootValue
2781
2801
  }
2782
2802
  }, 'value');
2803
+ if (this.shouldSetCalculatedValue) {
2804
+ return calculatedValue;
2805
+ }
2806
+ return dataValue;
2783
2807
  }
2784
2808
  /* eslint-disable max-statements */
2785
2809
  calculateComponentValue(data, flags, row) {
@@ -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.
@@ -631,19 +631,8 @@ class NestedComponent extends Field_1.default {
631
631
  }
632
632
  clearOnHide(show) {
633
633
  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
634
  this.getComponents().forEach(component => component.clearOnHide(show));
643
635
  }
644
- restoreComponentsContext() {
645
- this.getComponents().forEach((component) => component.data = this.dataValue);
646
- }
647
636
  /**
648
637
  * Allow components to hook into the next page trigger to perform their own logic.
649
638
  * @param {Function} next - The callback to continue to the next page.
@@ -36,6 +36,7 @@ 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;
@@ -598,9 +598,6 @@ class DataGridComponent extends NestedArrayComponent_1.default {
598
598
  this.updateOnChange(flags, changed);
599
599
  return changed;
600
600
  }
601
- restoreComponentsContext() {
602
- this.rows.forEach((row, index) => lodash_1.default.forIn(row, (component) => component.data = this.dataValue[index]));
603
- }
604
601
  toggleGroup(element, index) {
605
602
  element.classList.toggle('collapsed');
606
603
  lodash_1.default.each(this.refs.chunks[index], row => {
@@ -550,14 +550,6 @@ class EditGridComponent extends NestedArrayComponent_1.default {
550
550
  }
551
551
  });
552
552
  }
553
- restoreComponentsContext() {
554
- this.getComponents().forEach((component) => {
555
- var _a;
556
- const rowData = this.dataValue[component.rowIndex];
557
- const editRowData = (_a = this.editRows[component.rowIndex]) === null || _a === void 0 ? void 0 : _a.data;
558
- component.data = rowData || editRowData;
559
- });
560
- }
561
553
  flattenComponents(rowIndex) {
562
554
  const result = {};
563
555
  this.everyComponent((component) => {
@@ -208,7 +208,7 @@ exports.default = [
208
208
  label: 'Value Property',
209
209
  key: 'valueProperty',
210
210
  skipMerge: true,
211
- clearOnHide: true,
211
+ clearOnHide: false,
212
212
  tooltip: 'The field to use as the value.',
213
213
  weight: 11,
214
214
  refreshOn: 'data.resource',
@@ -478,14 +478,6 @@ export function getDataParentComponent(componentInstance: Component): Component
478
478
  * @returns {boolean} - TRUE if the value is a promise; FALSE otherwise
479
479
  */
480
480
  export function isPromise(value: any): boolean;
481
- /**
482
- * Determines if the component has a scoping parent in tree (a component which scopes its children and manages its
483
- * changes by itself, e.g. EditGrid)
484
- * @param {Component} componentInstance - The component to check for the scoping parent.
485
- * @param {boolean} firstPass - Whether it is the first pass of the function
486
- * @returns {boolean|*} - TRUE if the component has a scoping parent; FALSE otherwise
487
- */
488
- export function isInsideScopingComponent(componentInstance: Component, firstPass?: boolean): boolean | any;
489
481
  /**
490
482
  * Returns all the focusable elements within the provided dom element.
491
483
  * @param {HTMLElement} element - The element to get the focusable elements from.
@@ -19,7 +19,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToMoment = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.momentDate = exports.loadZones = exports.shouldLoadZones = exports.zonesLoaded = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.removeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = exports.moment = exports.ConditionOperators = exports.jsonLogic = void 0;
22
- exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = void 0;
22
+ exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = void 0;
23
23
  const lodash_1 = __importDefault(require("lodash"));
24
24
  exports._ = lodash_1.default;
25
25
  const json_logic_js_1 = __importDefault(require("json-logic-js"));
@@ -1593,27 +1593,6 @@ function isPromise(value) {
1593
1593
  && Object.prototype.toString.call(value) === '[object Promise]';
1594
1594
  }
1595
1595
  exports.isPromise = isPromise;
1596
- /**
1597
- * Determines if the component has a scoping parent in tree (a component which scopes its children and manages its
1598
- * changes by itself, e.g. EditGrid)
1599
- * @param {Component} componentInstance - The component to check for the scoping parent.
1600
- * @param {boolean} firstPass - Whether it is the first pass of the function
1601
- * @returns {boolean|*} - TRUE if the component has a scoping parent; FALSE otherwise
1602
- */
1603
- function isInsideScopingComponent(componentInstance, firstPass = true) {
1604
- if (!firstPass && (componentInstance === null || componentInstance === void 0 ? void 0 : componentInstance.hasScopedChildren)) {
1605
- return true;
1606
- }
1607
- const dataParent = getDataParentComponent(componentInstance);
1608
- if (dataParent === null || dataParent === void 0 ? void 0 : dataParent.hasScopedChildren) {
1609
- return true;
1610
- }
1611
- else if (dataParent === null || dataParent === void 0 ? void 0 : dataParent.parent) {
1612
- return isInsideScopingComponent(dataParent.parent, false);
1613
- }
1614
- return false;
1615
- }
1616
- exports.isInsideScopingComponent = isInsideScopingComponent;
1617
1596
  /**
1618
1597
  * Returns all the focusable elements within the provided dom element.
1619
1598
  * @param {HTMLElement} element - The element to get the focusable elements from.
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.23';
17
+ static version = '5.1.0-rc.25';
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.23';
7
+ FormioCore.version = '5.1.0-rc.25';
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) {
@@ -1637,6 +1637,10 @@ export default class WebformBuilder extends Component {
1637
1637
  info.type);
1638
1638
  }
1639
1639
  hasEditTabs(type) {
1640
+ // If the component type does not exist then it has no edit tabs
1641
+ if (!Components.components[type]) {
1642
+ return false;
1643
+ }
1640
1644
  const editTabs = getComponent(Components.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
1641
1645
  const hiddenEditTabs = _.filter(_.get(this.options, `editForm.${type}`, []), 'ignore');
1642
1646
  return _.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
package/lib/mjs/Wizard.js CHANGED
@@ -594,7 +594,7 @@ export default class Wizard extends Webform {
594
594
  }
595
595
  this.redraw().then(() => {
596
596
  this.checkData(this.submission.data);
597
- this.triggerCaptcha(this.currentPanel.components);
597
+ this.triggerCaptcha(this.currentPage.components);
598
598
  const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
599
599
  if (this.alert) {
600
600
  this.showErrors(errors, true, true);
@@ -718,7 +718,10 @@ export default class Wizard extends Webform {
718
718
  validateCurrentPage(flags = {}) {
719
719
  const components = this.currentPage?.components.map((component) => component.component);
720
720
  // Accessing the parent ensures the right instance (whether it's the parent Wizard or a nested Wizard) performs its validation
721
- return this.currentPage?.parent.validateComponents(components, this.root.data, flags);
721
+ if (this.currentPage?.parent) {
722
+ return this.currentPage?.parent.validateComponents(components, this.root.data, flags);
723
+ }
724
+ return this.currentPage?.validateComponents(components, this.root ? this.root.data : this.data, flags);
722
725
  }
723
726
  emitPrevPage() {
724
727
  this.emit('prevPage', { page: this.page, submission: this.submission });
@@ -129,6 +129,16 @@ declare class Component extends Element {
129
129
  * The reference attribute name for this component
130
130
  */
131
131
  _referenceAttributeName: string;
132
+ /**
133
+ * Sometimes the customDefaultValue does not set the "value" within the script, but is just a script to execute. This
134
+ * flag is used to determine if the customDefaultValue should be used to set the value of the component or not based on
135
+ * if there is a "value=" within the script.
136
+ */
137
+ shouldSetCustomDefault: any;
138
+ /**
139
+ * Same as customDefaultValue, but for calculateValue.
140
+ */
141
+ shouldSetCalculatedValue: any;
132
142
  triggerChange: (...args: any[]) => any;
133
143
  /**
134
144
  * Used to trigger a redraw event within this component.
@@ -778,6 +788,10 @@ declare class Component extends Element {
778
788
  * @returns {void}
779
789
  */
780
790
  setElementInvalid(element: HTMLElement, invalid: boolean): void;
791
+ /**
792
+ * Clear any conditionally hidden components for this component only.
793
+ */
794
+ clearComponentOnHide(): void;
781
795
  /**
782
796
  * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
783
797
  */
@@ -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, isInsideScopingComponent, currentTimezone, getScriptPlugin, getContextualRowData } from '../../../utils/utils';
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';
@@ -325,6 +325,22 @@ export default class Component extends Element {
325
325
  * The reference attribute name for this component
326
326
  */
327
327
  this._referenceAttributeName = 'ref';
328
+ /**
329
+ * Sometimes the customDefaultValue does not set the "value" within the script, but is just a script to execute. This
330
+ * flag is used to determine if the customDefaultValue should be used to set the value of the component or not based on
331
+ * if there is a "value=" within the script.
332
+ */
333
+ this.shouldSetCustomDefault = true;
334
+ if (this.component.customDefaultValue && (typeof this.component.customDefaultValue === 'string')) {
335
+ this.shouldSetCustomDefault = this.component.customDefaultValue.match(/value\s*=/);
336
+ }
337
+ /**
338
+ * Same as customDefaultValue, but for calculateValue.
339
+ */
340
+ this.shouldSetCalculatedValue = true;
341
+ if (this.component.calculateValue && (typeof this.component.calculateValue === 'string')) {
342
+ this.shouldSetCalculatedValue = this.component.calculateValue.match(/value\s*=/);
343
+ }
328
344
  /**
329
345
  * Used to trigger a new change in this component.
330
346
  * @type {Function} - Call to trigger a change in this component.
@@ -1915,7 +1931,7 @@ export default class Component extends Element {
1915
1931
  if (this.visible !== visible) {
1916
1932
  this.visible = visible;
1917
1933
  }
1918
- this.clearOnHide();
1934
+ this.clearComponentOnHide();
1919
1935
  return visible;
1920
1936
  }
1921
1937
  /**
@@ -2175,16 +2191,11 @@ export default class Component extends Element {
2175
2191
  element.setAttribute('aria-invalid', invalid ? 'true' : 'false');
2176
2192
  }
2177
2193
  /**
2178
- * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
2194
+ * Clear any conditionally hidden components for this component only.
2179
2195
  */
2180
- clearOnHide() {
2196
+ clearComponentOnHide() {
2181
2197
  // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
2182
- if (
2183
- // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true
2184
- (!this.rootPristine || this.options.server || isInsideScopingComponent(this)) &&
2185
- this.component.clearOnHide !== false &&
2186
- !this.options.readOnly &&
2187
- !this.options.showHiddenFields) {
2198
+ if (this.component.clearOnHide !== false && !this.options.readOnly && !this.options.showHiddenFields) {
2188
2199
  if (this.conditionallyHidden()) {
2189
2200
  this.deleteValue();
2190
2201
  }
@@ -2196,6 +2207,12 @@ export default class Component extends Element {
2196
2207
  }
2197
2208
  }
2198
2209
  }
2210
+ /**
2211
+ * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.
2212
+ */
2213
+ clearOnHide() {
2214
+ this.clearComponentOnHide();
2215
+ }
2199
2216
  /**
2200
2217
  * Triggers a debounced onChange event for the root component (usually Webform).
2201
2218
  * @param {...any} args - The arguments to pass to the onChange event.
@@ -2492,7 +2509,10 @@ export default class Component extends Element {
2492
2509
  }
2493
2510
  getCustomDefaultValue(defaultValue) {
2494
2511
  if (this.component.customDefaultValue && !this.options.preview) {
2495
- defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');
2512
+ const customDefaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');
2513
+ if (this.shouldSetCustomDefault) {
2514
+ defaultValue = customDefaultValue;
2515
+ }
2496
2516
  }
2497
2517
  return defaultValue;
2498
2518
  }
@@ -2751,7 +2771,7 @@ export default class Component extends Element {
2751
2771
  return value;
2752
2772
  }
2753
2773
  doValueCalculation(dataValue, data, row) {
2754
- return this.evaluate(this.component.calculateValue, {
2774
+ const calculatedValue = this.evaluate(this.component.calculateValue, {
2755
2775
  value: dataValue,
2756
2776
  data,
2757
2777
  row: row || this.data,
@@ -2759,6 +2779,10 @@ export default class Component extends Element {
2759
2779
  data: this.rootValue
2760
2780
  }
2761
2781
  }, 'value');
2782
+ if (this.shouldSetCalculatedValue) {
2783
+ return calculatedValue;
2784
+ }
2785
+ return dataValue;
2762
2786
  }
2763
2787
  /* eslint-disable max-statements */
2764
2788
  calculateComponentValue(data, flags, row) {
@@ -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.
@@ -627,19 +627,8 @@ export default class NestedComponent extends Field {
627
627
  }
628
628
  clearOnHide(show) {
629
629
  super.clearOnHide(show);
630
- if (this.component.clearOnHide) {
631
- if (this.allowData && !this.hasValue() && !this.conditionallyHidden()) {
632
- this.dataValue = this.defaultValue;
633
- }
634
- if (this.hasValue()) {
635
- this.restoreComponentsContext();
636
- }
637
- }
638
630
  this.getComponents().forEach(component => component.clearOnHide(show));
639
631
  }
640
- restoreComponentsContext() {
641
- this.getComponents().forEach((component) => component.data = this.dataValue);
642
- }
643
632
  /**
644
633
  * Allow components to hook into the next page trigger to perform their own logic.
645
634
  * @param {Function} next - The callback to continue to the next page.
@@ -36,6 +36,7 @@ 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;
@@ -594,9 +594,6 @@ export default class DataGridComponent extends NestedArrayComponent {
594
594
  this.updateOnChange(flags, changed);
595
595
  return changed;
596
596
  }
597
- restoreComponentsContext() {
598
- this.rows.forEach((row, index) => _.forIn(row, (component) => component.data = this.dataValue[index]));
599
- }
600
597
  toggleGroup(element, index) {
601
598
  element.classList.toggle('collapsed');
602
599
  _.each(this.refs.chunks[index], row => {
@@ -543,13 +543,6 @@ export default class EditGridComponent extends NestedArrayComponent {
543
543
  }
544
544
  });
545
545
  }
546
- restoreComponentsContext() {
547
- this.getComponents().forEach((component) => {
548
- const rowData = this.dataValue[component.rowIndex];
549
- const editRowData = this.editRows[component.rowIndex]?.data;
550
- component.data = rowData || editRowData;
551
- });
552
- }
553
546
  flattenComponents(rowIndex) {
554
547
  const result = {};
555
548
  this.everyComponent((component) => {
@@ -202,7 +202,7 @@ export default [
202
202
  label: 'Value Property',
203
203
  key: 'valueProperty',
204
204
  skipMerge: true,
205
- clearOnHide: true,
205
+ clearOnHide: false,
206
206
  tooltip: 'The field to use as the value.',
207
207
  weight: 11,
208
208
  refreshOn: 'data.resource',
@@ -478,14 +478,6 @@ export function getDataParentComponent(componentInstance: Component): Component
478
478
  * @returns {boolean} - TRUE if the value is a promise; FALSE otherwise
479
479
  */
480
480
  export function isPromise(value: any): boolean;
481
- /**
482
- * Determines if the component has a scoping parent in tree (a component which scopes its children and manages its
483
- * changes by itself, e.g. EditGrid)
484
- * @param {Component} componentInstance - The component to check for the scoping parent.
485
- * @param {boolean} firstPass - Whether it is the first pass of the function
486
- * @returns {boolean|*} - TRUE if the component has a scoping parent; FALSE otherwise
487
- */
488
- export function isInsideScopingComponent(componentInstance: Component, firstPass?: boolean): boolean | any;
489
481
  /**
490
482
  * Returns all the focusable elements within the provided dom element.
491
483
  * @param {HTMLElement} element - The element to get the focusable elements from.
@@ -1502,26 +1502,6 @@ export function isPromise(value) {
1502
1502
  && typeof value.then === 'function'
1503
1503
  && Object.prototype.toString.call(value) === '[object Promise]';
1504
1504
  }
1505
- /**
1506
- * Determines if the component has a scoping parent in tree (a component which scopes its children and manages its
1507
- * changes by itself, e.g. EditGrid)
1508
- * @param {Component} componentInstance - The component to check for the scoping parent.
1509
- * @param {boolean} firstPass - Whether it is the first pass of the function
1510
- * @returns {boolean|*} - TRUE if the component has a scoping parent; FALSE otherwise
1511
- */
1512
- export function isInsideScopingComponent(componentInstance, firstPass = true) {
1513
- if (!firstPass && componentInstance?.hasScopedChildren) {
1514
- return true;
1515
- }
1516
- const dataParent = getDataParentComponent(componentInstance);
1517
- if (dataParent?.hasScopedChildren) {
1518
- return true;
1519
- }
1520
- else if (dataParent?.parent) {
1521
- return isInsideScopingComponent(dataParent.parent, false);
1522
- }
1523
- return false;
1524
- }
1525
1505
  /**
1526
1506
  * Returns all the focusable elements within the provided dom element.
1527
1507
  * @param {HTMLElement} element - The element to get the focusable elements from.