@formio/js 5.1.0-dev.5983.aa8260f → 5.1.0-dev.5988.8d481cd

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 (47) hide show
  1. package/dist/formio.form.js +13 -13
  2. package/dist/formio.form.min.js +1 -1
  3. package/dist/formio.full.js +16 -16
  4. package/dist/formio.full.min.js +1 -1
  5. package/dist/formio.js +1 -1
  6. package/dist/formio.min.js +1 -1
  7. package/lib/cjs/Form.js +3 -1
  8. package/lib/cjs/Webform.d.ts +4 -1
  9. package/lib/cjs/Webform.js +26 -13
  10. package/lib/cjs/Wizard.js +1 -1
  11. package/lib/cjs/components/Components.d.ts +3 -0
  12. package/lib/cjs/components/_classes/component/Component.js +11 -2
  13. package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  14. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +1 -1
  15. package/lib/cjs/components/_classes/component/editForm/utils.d.ts +1 -0
  16. package/lib/cjs/components/_classes/component/editForm/utils.js +3 -0
  17. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -0
  18. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +3 -0
  19. package/lib/cjs/components/day/Day.js +7 -5
  20. package/lib/cjs/components/file/File.js +2 -1
  21. package/lib/cjs/components/form/Form.js +15 -5
  22. package/lib/cjs/components/form/editForm/Form.edit.data.js +1 -1
  23. package/lib/cjs/components/form/editForm/Form.edit.form.js +2 -2
  24. package/lib/cjs/components/select/editForm/Select.edit.data.js +2 -2
  25. package/lib/cjs/providers/storage/googleDrive.js +3 -2
  26. package/lib/cjs/widgets/CalendarWidget.js +0 -14
  27. package/lib/mjs/Form.js +3 -1
  28. package/lib/mjs/Webform.d.ts +4 -1
  29. package/lib/mjs/Webform.js +26 -13
  30. package/lib/mjs/Wizard.js +1 -1
  31. package/lib/mjs/components/Components.d.ts +3 -0
  32. package/lib/mjs/components/_classes/component/Component.js +11 -2
  33. package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  34. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +1 -1
  35. package/lib/mjs/components/_classes/component/editForm/utils.d.ts +1 -0
  36. package/lib/mjs/components/_classes/component/editForm/utils.js +3 -0
  37. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -0
  38. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +3 -0
  39. package/lib/mjs/components/day/Day.js +7 -5
  40. package/lib/mjs/components/file/File.js +2 -1
  41. package/lib/mjs/components/form/Form.js +15 -5
  42. package/lib/mjs/components/form/editForm/Form.edit.data.js +1 -1
  43. package/lib/mjs/components/form/editForm/Form.edit.form.js +2 -2
  44. package/lib/mjs/components/select/editForm/Select.edit.data.js +2 -2
  45. package/lib/mjs/providers/storage/googleDrive.js +3 -2
  46. package/lib/mjs/widgets/CalendarWidget.js +0 -14
  47. package/package.json +1 -1
package/lib/cjs/Form.js CHANGED
@@ -281,7 +281,9 @@ class Form extends Element_1.default {
281
281
  this.form.display = display;
282
282
  this.instance.destroy();
283
283
  this.instance = this.create(display);
284
- return this.setForm(this.form);
284
+ return this.setForm(this.form).then(() => {
285
+ this.instance.emit('setDisplay', this.form.display);
286
+ });
285
287
  }
286
288
  empty() {
287
289
  if (this.element) {
@@ -190,7 +190,10 @@ declare class Webform extends NestedDataComponent {
190
190
  get language(): string;
191
191
  root: this;
192
192
  localRoot: this;
193
+ beforeInit(): void;
194
+ executeFormController: any;
193
195
  get emptyValue(): null;
196
+ get shouldCallFormController(): any;
194
197
  get shadowRoot(): any;
195
198
  /**
196
199
  * Add a language for translations
@@ -360,7 +363,7 @@ declare class Webform extends NestedDataComponent {
360
363
  * @returns {Promise} - The promise that is triggered when the form is built.
361
364
  */
362
365
  init(): Promise<any>;
363
- executeFormController(): false | undefined;
366
+ _executeFormController(): void;
364
367
  build(element: any): Promise<any>;
365
368
  getClassName(): string;
366
369
  render(): string;
@@ -315,12 +315,24 @@ class Webform extends NestedDataComponent_1.default {
315
315
  this.localRoot = this;
316
316
  }
317
317
  /* eslint-enable max-statements */
318
+ beforeInit() {
319
+ this.executeFormController = lodash_1.default.once(this._executeFormController);
320
+ }
318
321
  get language() {
319
322
  return this.options.language;
320
323
  }
321
324
  get emptyValue() {
322
325
  return null;
323
326
  }
327
+ get shouldCallFormController() {
328
+ // If no controller value or
329
+ // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
330
+ return (this.form &&
331
+ this.form.controller &&
332
+ !((!this.visible || this.component.hidden) &&
333
+ this.component.clearOnHide &&
334
+ !this.rootPristine));
335
+ }
324
336
  componentContext() {
325
337
  return this._data;
326
338
  }
@@ -899,19 +911,12 @@ class Webform extends NestedDataComponent_1.default {
899
911
  this.on('resetForm', () => this.resetValue(), true);
900
912
  this.on('deleteSubmission', () => this.deleteSubmission(), true);
901
913
  this.on('refreshData', () => this.updateValue(), true);
902
- this.executeFormController();
914
+ if (this.shouldCallFormController) {
915
+ this.executeFormController();
916
+ }
903
917
  return this.formReady;
904
918
  }
905
- executeFormController() {
906
- // If no controller value or
907
- // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
908
- if (!this.form ||
909
- !this.form.controller ||
910
- ((!this.visible || this.component.hidden) &&
911
- this.component.clearOnHide &&
912
- !this.rootPristine)) {
913
- return false;
914
- }
919
+ _executeFormController() {
915
920
  this.formReady.then(() => {
916
921
  this.evaluate(this.form.controller, {
917
922
  components: this.components,
@@ -1530,7 +1535,7 @@ class Webform extends NestedDataComponent_1.default {
1530
1535
  }
1531
1536
  }
1532
1537
  triggerCaptcha() {
1533
- if (!this || !this.components) {
1538
+ if (!this || !this.components || this.options.preview) {
1534
1539
  return;
1535
1540
  }
1536
1541
  const captchaComponent = [];
@@ -1540,7 +1545,15 @@ class Webform extends NestedDataComponent_1.default {
1540
1545
  }
1541
1546
  });
1542
1547
  if (captchaComponent.length > 0) {
1543
- captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1548
+ if (this.parent) {
1549
+ this.parent.subFormReady.then(() => {
1550
+ captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1551
+ });
1552
+ }
1553
+ else {
1554
+ captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1555
+ }
1556
+ ;
1544
1557
  }
1545
1558
  }
1546
1559
  set nosubmit(value) {
package/lib/cjs/Wizard.js CHANGED
@@ -667,7 +667,7 @@ class Wizard extends Webform_1.default {
667
667
  return this.page - 1;
668
668
  }
669
669
  beforeSubmit() {
670
- const pages = this.getPages();
670
+ const pages = this.getPages({ all: true });
671
671
  return Promise.all(pages.map((page) => {
672
672
  page.options.beforeSubmit = true;
673
673
  return page.beforeSubmit();
@@ -2,6 +2,7 @@ export default class Components {
2
2
  static _editFormUtils: {
3
3
  sortAndFilterComponents(components: any): any;
4
4
  unifyComponents(objValue: any, srcValue: any): any;
5
+ tokenVariableDescription(): string;
5
6
  logicVariablesTable(additional: any): {
6
7
  type: string;
7
8
  tag: string;
@@ -86,6 +87,7 @@ export default class Components {
86
87
  static set EditFormUtils(value: {
87
88
  sortAndFilterComponents(components: any): any;
88
89
  unifyComponents(objValue: any, srcValue: any): any;
90
+ tokenVariableDescription(): string;
89
91
  logicVariablesTable(additional: any): {
90
92
  type: string;
91
93
  tag: string;
@@ -169,6 +171,7 @@ export default class Components {
169
171
  static get EditFormUtils(): {
170
172
  sortAndFilterComponents(components: any): any;
171
173
  unifyComponents(objValue: any, srcValue: any): any;
174
+ tokenVariableDescription(): string;
172
175
  logicVariablesTable(additional: any): {
173
176
  type: string;
174
177
  tag: string;
@@ -453,6 +453,9 @@ class Component extends Element_1.default {
453
453
  // Allow anyone to hook into the component creation.
454
454
  this.hook('component');
455
455
  if (!this.options.skipInit) {
456
+ if (typeof this.beforeInit === 'function') {
457
+ this.beforeInit();
458
+ }
456
459
  this.init();
457
460
  }
458
461
  }
@@ -1296,7 +1299,7 @@ class Component extends Element_1.default {
1296
1299
  detach() {
1297
1300
  // First iterate through each ref and delete the component so there are no dangling component references.
1298
1301
  lodash_1.default.each(this.refs, (ref) => {
1299
- if (typeof ref === NodeList) {
1302
+ if (ref instanceof NodeList) {
1300
1303
  ref.forEach((elem) => {
1301
1304
  delete elem.component;
1302
1305
  });
@@ -1948,15 +1951,21 @@ class Component extends Element_1.default {
1948
1951
  }
1949
1952
  // Check advanced conditions (and cache the result)
1950
1953
  const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;
1954
+ let shouldClear = false;
1951
1955
  if (isConditionallyHidden !== this._conditionallyHidden) {
1952
1956
  this._conditionallyHidden = isConditionallyHidden;
1953
- this.clearOnHide();
1957
+ shouldClear = true;
1954
1958
  }
1955
1959
  // Check visibility
1956
1960
  const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
1957
1961
  if (this.visible !== visible) {
1958
1962
  this.visible = visible;
1959
1963
  }
1964
+ // Wait for visibility to update for nested components, so the component state is up-to-date when
1965
+ // calling clearOnHide
1966
+ if (shouldClear) {
1967
+ this.clearOnHide();
1968
+ }
1960
1969
  return visible;
1961
1970
  }
1962
1971
  /**
@@ -50,6 +50,6 @@ exports.default = [
50
50
  },
51
51
  utils_1.default.javaScriptValue('Advanced Conditions', 'customConditional', 'conditional.json', 110, '<p>You must assign the <strong>show</strong> variable a boolean result.</p>' +
52
52
  '<p><strong>Note: Advanced Conditional logic will override the results of the Simple Conditional logic.</strong></p>' +
53
- '<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>')
53
+ '<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', utils_1.default.tokenVariableDescription())
54
54
  ];
55
55
  /* eslint-enable quotes, max-len */
@@ -140,7 +140,7 @@ exports.default = [
140
140
  input: true
141
141
  },
142
142
  utils_1.default.javaScriptValue('Custom Default Value', 'customDefaultValue', 'customDefaultValue', 1000, '<p><h4>Example:</h4><pre>value = data.firstName + " " + data.lastName;</pre></p>', '<p><h4>Example:</h4><pre>{"cat": [{"var": "data.firstName"}, " ", {"var": "data.lastName"}]}</pre>'),
143
- utils_1.default.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 1100, '<p><h4>Example:</h4><pre>value = data.a + data.b + data.c;</pre></p>', '<p><h4>Example:</h4><pre>{"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]}</pre><p><a href="https://help.form.io/userguide/form-building/logic-and-conditions#calculated-values" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', '<tr><th>token</th><td>The decoded JWT token for the authenticated user.</td></tr>'),
143
+ utils_1.default.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 1100, '<p><h4>Example:</h4><pre>value = data.a + data.b + data.c;</pre></p>', '<p><h4>Example:</h4><pre>{"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]}</pre><p><a href="https://help.form.io/userguide/form-building/logic-and-conditions#calculated-values" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', utils_1.default.tokenVariableDescription()),
144
144
  {
145
145
  type: 'checkbox',
146
146
  input: true,
@@ -2,6 +2,7 @@ export default EditFormUtils;
2
2
  declare namespace EditFormUtils {
3
3
  function sortAndFilterComponents(components: any): any;
4
4
  function unifyComponents(objValue: any, srcValue: any): any;
5
+ function tokenVariableDescription(): string;
5
6
  function logicVariablesTable(additional: any): {
6
7
  type: string;
7
8
  tag: string;
@@ -37,6 +37,9 @@ const EditFormUtils = {
37
37
  }
38
38
  return lodash_1.default.isEqual(objValue, srcValue);
39
39
  },
40
+ tokenVariableDescription() {
41
+ return '<tr><th>token</th><td>The decoded JWT token for the authenticated user.</td></tr>';
42
+ },
40
43
  logicVariablesTable(additional) {
41
44
  additional = additional || '';
42
45
  return {
@@ -3,6 +3,7 @@ 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;
6
7
  componentContext(): any;
7
8
  getValueAsString(value: any, options: any): string;
8
9
  getDataValueAsTable(value: any, options: any): string;
@@ -26,6 +26,9 @@ class NestedDataComponent extends NestedComponent_1.default {
26
26
  get emptyValue() {
27
27
  return {};
28
28
  }
29
+ get shouldAddDefaultValue() {
30
+ return !this.options.noDefaults || !this.options.server;
31
+ }
29
32
  componentContext() {
30
33
  return this.dataValue;
31
34
  }
@@ -53,11 +53,13 @@ class DayComponent extends Field_1.default {
53
53
  return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.string];
54
54
  }
55
55
  constructor(component, options, data) {
56
- if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
57
- component.maxDate = (0, moment_1.default)(component.maxDate, 'YYYY-MM-DD').toISOString();
58
- }
59
- if (component.minDate && component.minDate.indexOf('moment(') === -1) {
60
- component.minDate = (0, moment_1.default)(component.minDate, 'YYYY-MM-DD').toISOString();
56
+ if (!options.inFormBuilder && !options.building) {
57
+ if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
58
+ component.maxDate = (0, moment_1.default)(component.maxDate, 'YYYY-MM-DD').toISOString();
59
+ }
60
+ if (component.minDate && component.minDate.indexOf('moment(') === -1) {
61
+ component.minDate = (0, moment_1.default)(component.minDate, 'YYYY-MM-DD').toISOString();
62
+ }
61
63
  }
62
64
  super(component, options, data);
63
65
  }
@@ -109,7 +109,8 @@ class FileComponent extends Field_1.default {
109
109
  if (this.component.privateDownload) {
110
110
  fileInfo.private = true;
111
111
  }
112
- return this.fileService.downloadFile(fileInfo).then((result) => result.url);
112
+ // pass the component to the downloadFile method
113
+ return this.fileService.downloadFile(fileInfo, this.component).then((result) => result.url);
113
114
  }
114
115
  get emptyValue() {
115
116
  return [];
@@ -587,11 +587,21 @@ class FormComponent extends Component_1.default {
587
587
  this.dataValue = submission;
588
588
  return Promise.resolve(this.dataValue);
589
589
  }
590
- return this.submitSubForm(false)
591
- .then(() => {
592
- return this.dataValue;
593
- })
594
- .then(() => super.beforeSubmit());
590
+ if (this.isSubFormLazyLoad() && !this.subFormLoading) {
591
+ return this.createSubForm(true)
592
+ .then(this.submitSubForm(false))
593
+ .then(() => {
594
+ return this.dataValue;
595
+ })
596
+ .then(() => super.beforeSubmit());
597
+ }
598
+ else {
599
+ return this.submitSubForm(false)
600
+ .then(() => {
601
+ return this.dataValue;
602
+ })
603
+ .then(() => super.beforeSubmit());
604
+ }
595
605
  }
596
606
  isSubFormLazyLoad() {
597
607
  var _a, _b;
@@ -11,7 +11,7 @@ exports.default = [
11
11
  {
12
12
  weight: 140,
13
13
  type: 'checkbox',
14
- label: 'Clear Value When Hidden',
14
+ label: 'Omit Value From Submission Data When Conditionally Hidden',
15
15
  key: 'clearOnHide',
16
16
  defaultValue: true,
17
17
  tooltip: 'When a field is hidden, clear the value.',
@@ -69,7 +69,7 @@ exports.default = [
69
69
  input: true,
70
70
  weight: 20,
71
71
  key: 'reference',
72
- label: 'Save as reference',
73
- tooltip: 'Using this option will save this field as a reference and link its value to the value of the origin record.'
72
+ label: 'Submit as reference',
73
+ tooltip: 'When "Submit as reference" is enabled, the form submission will be recorded against the Parent Form as well as the Child Form. When a submission recorded with "Submit as reference" is edited, the update is applied to each submission made against the Parent Form and Child Form.'
74
74
  }
75
75
  ];
@@ -641,8 +641,8 @@ exports.default = [
641
641
  input: true,
642
642
  weight: 25,
643
643
  key: 'reference',
644
- label: 'Save as reference',
645
- tooltip: 'Using this option will save this field as a reference and link its value to the value of the origin record.',
644
+ label: 'Submit as reference',
645
+ tooltip: 'Using this option will submit this field as a reference id and link its value to the value of the origin record.',
646
646
  conditional: {
647
647
  json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
648
648
  },
@@ -52,10 +52,11 @@ function googledrive(formio) {
52
52
  xhr.send(fd);
53
53
  }));
54
54
  },
55
- downloadFile(file) {
55
+ downloadFile(file, component) {
56
56
  const token = formio.getToken();
57
+ // Constructed the url with the fileId, fileName, displayImage, imageSize if applicable
57
58
  file.url =
58
- `${formio.formUrl}/storage/gdrive?fileId=${file.id}&fileName=${file.originalName}${token ? `&x-jwt-token=${token}` : ''}`;
59
+ `${formio.formUrl}/storage/gdrive?fileId=${file.id}&fileName=${file.originalName}${token ? `&x-jwt-token=${token}` : ''}${component.image ? '&displayImage=true' : ''}${component.imageSize ? `&imageSize=${component.imageSize}` : ''}`;
59
60
  return Promise.resolve(file);
60
61
  },
61
62
  deleteFile: function deleteFile(fileInfo) {
@@ -93,8 +93,6 @@ class CalendarWidget extends InputWidget_1.default {
93
93
  this.settings.disableWeekends ? this.settings.disable.push(this.disableWeekends) : '';
94
94
  this.settings.disableWeekdays ? this.settings.disable.push(this.disableWeekdays) : '';
95
95
  this.settings.disableFunction ? this.settings.disable.push(this.disableFunction) : '';
96
- this.settings.wasDefaultValueChanged = false;
97
- this.settings.defaultValue = '';
98
96
  this.settings.manualInputValue = '';
99
97
  this.settings.isManuallyOverriddenValue = false;
100
98
  this.settings.currentValue = '';
@@ -115,10 +113,6 @@ class CalendarWidget extends InputWidget_1.default {
115
113
  this.calendar._input.value = this.settings.isManuallyOverriddenValue ? this.settings.manualInputValue : this.calendar.altInput.value;
116
114
  this.emit('update');
117
115
  }
118
- if (this.settings.wasDefaultValueChanged) {
119
- this.calendar._input.value = this.settings.defaultValue;
120
- this.settings.wasDefaultValueChanged = false;
121
- }
122
116
  if (this.calendar) {
123
117
  this.emit('blur');
124
118
  }
@@ -360,14 +354,6 @@ class CalendarWidget extends InputWidget_1.default {
360
354
  this.settings.currentValue = event.target.value;
361
355
  this.emit('update');
362
356
  }
363
- if (event.target.value === '' && this.calendar.selectedDates.length > 0) {
364
- this.settings.wasDefaultValueChanged = true;
365
- this.settings.defaultValue = event.target.value;
366
- this.calendar.clear();
367
- }
368
- else {
369
- this.settings.wasDefaultValueChanged = false;
370
- }
371
357
  });
372
358
  if (this.calendar.daysContainer) {
373
359
  this.calendar.daysContainer.addEventListener('click', () => {
package/lib/mjs/Form.js CHANGED
@@ -350,7 +350,9 @@ export default class Form extends Element {
350
350
  this.form.display = display;
351
351
  this.instance.destroy();
352
352
  this.instance = this.create(display);
353
- return this.setForm(this.form);
353
+ return this.setForm(this.form).then(() => {
354
+ this.instance.emit('setDisplay', this.form.display);
355
+ });
354
356
  }
355
357
  empty() {
356
358
  if (this.element) {
@@ -190,7 +190,10 @@ declare class Webform extends NestedDataComponent {
190
190
  get language(): string;
191
191
  root: this;
192
192
  localRoot: this;
193
+ beforeInit(): void;
194
+ executeFormController: any;
193
195
  get emptyValue(): null;
196
+ get shouldCallFormController(): any;
194
197
  get shadowRoot(): any;
195
198
  /**
196
199
  * Add a language for translations
@@ -360,7 +363,7 @@ declare class Webform extends NestedDataComponent {
360
363
  * @returns {Promise} - The promise that is triggered when the form is built.
361
364
  */
362
365
  init(): Promise<any>;
363
- executeFormController(): false | undefined;
366
+ _executeFormController(): void;
364
367
  build(element: any): Promise<any>;
365
368
  getClassName(): string;
366
369
  render(): string;
@@ -287,12 +287,24 @@ export default class Webform extends NestedDataComponent {
287
287
  this.localRoot = this;
288
288
  }
289
289
  /* eslint-enable max-statements */
290
+ beforeInit() {
291
+ this.executeFormController = _.once(this._executeFormController);
292
+ }
290
293
  get language() {
291
294
  return this.options.language;
292
295
  }
293
296
  get emptyValue() {
294
297
  return null;
295
298
  }
299
+ get shouldCallFormController() {
300
+ // If no controller value or
301
+ // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
302
+ return (this.form &&
303
+ this.form.controller &&
304
+ !((!this.visible || this.component.hidden) &&
305
+ this.component.clearOnHide &&
306
+ !this.rootPristine));
307
+ }
296
308
  componentContext() {
297
309
  return this._data;
298
310
  }
@@ -902,19 +914,12 @@ export default class Webform extends NestedDataComponent {
902
914
  this.on('resetForm', () => this.resetValue(), true);
903
915
  this.on('deleteSubmission', () => this.deleteSubmission(), true);
904
916
  this.on('refreshData', () => this.updateValue(), true);
905
- this.executeFormController();
917
+ if (this.shouldCallFormController) {
918
+ this.executeFormController();
919
+ }
906
920
  return this.formReady;
907
921
  }
908
- executeFormController() {
909
- // If no controller value or
910
- // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
911
- if (!this.form ||
912
- !this.form.controller ||
913
- ((!this.visible || this.component.hidden) &&
914
- this.component.clearOnHide &&
915
- !this.rootPristine)) {
916
- return false;
917
- }
922
+ _executeFormController() {
918
923
  this.formReady.then(() => {
919
924
  this.evaluate(this.form.controller, {
920
925
  components: this.components,
@@ -1530,7 +1535,7 @@ export default class Webform extends NestedDataComponent {
1530
1535
  }
1531
1536
  }
1532
1537
  triggerCaptcha() {
1533
- if (!this || !this.components) {
1538
+ if (!this || !this.components || this.options.preview) {
1534
1539
  return;
1535
1540
  }
1536
1541
  const captchaComponent = [];
@@ -1540,7 +1545,15 @@ export default class Webform extends NestedDataComponent {
1540
1545
  }
1541
1546
  });
1542
1547
  if (captchaComponent.length > 0) {
1543
- captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1548
+ if (this.parent) {
1549
+ this.parent.subFormReady.then(() => {
1550
+ captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1551
+ });
1552
+ }
1553
+ else {
1554
+ captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1555
+ }
1556
+ ;
1544
1557
  }
1545
1558
  }
1546
1559
  set nosubmit(value) {
package/lib/mjs/Wizard.js CHANGED
@@ -657,7 +657,7 @@ export default class Wizard extends Webform {
657
657
  return this.page - 1;
658
658
  }
659
659
  beforeSubmit() {
660
- const pages = this.getPages();
660
+ const pages = this.getPages({ all: true });
661
661
  return Promise.all(pages.map((page) => {
662
662
  page.options.beforeSubmit = true;
663
663
  return page.beforeSubmit();
@@ -2,6 +2,7 @@ export default class Components {
2
2
  static _editFormUtils: {
3
3
  sortAndFilterComponents(components: any): any;
4
4
  unifyComponents(objValue: any, srcValue: any): any;
5
+ tokenVariableDescription(): string;
5
6
  logicVariablesTable(additional: any): {
6
7
  type: string;
7
8
  tag: string;
@@ -86,6 +87,7 @@ export default class Components {
86
87
  static set EditFormUtils(value: {
87
88
  sortAndFilterComponents(components: any): any;
88
89
  unifyComponents(objValue: any, srcValue: any): any;
90
+ tokenVariableDescription(): string;
89
91
  logicVariablesTable(additional: any): {
90
92
  type: string;
91
93
  tag: string;
@@ -169,6 +171,7 @@ export default class Components {
169
171
  static get EditFormUtils(): {
170
172
  sortAndFilterComponents(components: any): any;
171
173
  unifyComponents(objValue: any, srcValue: any): any;
174
+ tokenVariableDescription(): string;
172
175
  logicVariablesTable(additional: any): {
173
176
  type: string;
174
177
  tag: string;
@@ -418,6 +418,9 @@ export default class Component extends Element {
418
418
  // Allow anyone to hook into the component creation.
419
419
  this.hook('component');
420
420
  if (!this.options.skipInit) {
421
+ if (typeof this.beforeInit === 'function') {
422
+ this.beforeInit();
423
+ }
421
424
  this.init();
422
425
  }
423
426
  }
@@ -1264,7 +1267,7 @@ export default class Component extends Element {
1264
1267
  detach() {
1265
1268
  // First iterate through each ref and delete the component so there are no dangling component references.
1266
1269
  _.each(this.refs, (ref) => {
1267
- if (typeof ref === NodeList) {
1270
+ if (ref instanceof NodeList) {
1268
1271
  ref.forEach((elem) => {
1269
1272
  delete elem.component;
1270
1273
  });
@@ -1914,15 +1917,21 @@ export default class Component extends Element {
1914
1917
  }
1915
1918
  // Check advanced conditions (and cache the result)
1916
1919
  const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;
1920
+ let shouldClear = false;
1917
1921
  if (isConditionallyHidden !== this._conditionallyHidden) {
1918
1922
  this._conditionallyHidden = isConditionallyHidden;
1919
- this.clearOnHide();
1923
+ shouldClear = true;
1920
1924
  }
1921
1925
  // Check visibility
1922
1926
  const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);
1923
1927
  if (this.visible !== visible) {
1924
1928
  this.visible = visible;
1925
1929
  }
1930
+ // Wait for visibility to update for nested components, so the component state is up-to-date when
1931
+ // calling clearOnHide
1932
+ if (shouldClear) {
1933
+ this.clearOnHide();
1934
+ }
1926
1935
  return visible;
1927
1936
  }
1928
1937
  /**
@@ -45,6 +45,6 @@ export default [
45
45
  },
46
46
  EditFormUtils.javaScriptValue('Advanced Conditions', 'customConditional', 'conditional.json', 110, '<p>You must assign the <strong>show</strong> variable a boolean result.</p>' +
47
47
  '<p><strong>Note: Advanced Conditional logic will override the results of the Simple Conditional logic.</strong></p>' +
48
- '<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>')
48
+ '<h5>Example</h5><pre>show = !!data.showMe;</pre>', '<p><a href="https://help.form.io/userguide/form-building/logic-and-conditions" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', EditFormUtils.tokenVariableDescription())
49
49
  ];
50
50
  /* eslint-enable quotes, max-len */
@@ -135,7 +135,7 @@ export default [
135
135
  input: true
136
136
  },
137
137
  EditFormUtils.javaScriptValue('Custom Default Value', 'customDefaultValue', 'customDefaultValue', 1000, '<p><h4>Example:</h4><pre>value = data.firstName + " " + data.lastName;</pre></p>', '<p><h4>Example:</h4><pre>{"cat": [{"var": "data.firstName"}, " ", {"var": "data.lastName"}]}</pre>'),
138
- EditFormUtils.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 1100, '<p><h4>Example:</h4><pre>value = data.a + data.b + data.c;</pre></p>', '<p><h4>Example:</h4><pre>{"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]}</pre><p><a href="https://help.form.io/userguide/form-building/logic-and-conditions#calculated-values" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', '<tr><th>token</th><td>The decoded JWT token for the authenticated user.</td></tr>'),
138
+ EditFormUtils.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 1100, '<p><h4>Example:</h4><pre>value = data.a + data.b + data.c;</pre></p>', '<p><h4>Example:</h4><pre>{"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]}</pre><p><a href="https://help.form.io/userguide/form-building/logic-and-conditions#calculated-values" target="_blank" rel="noopener noreferrer">Click here for an example</a></p>', EditFormUtils.tokenVariableDescription()),
139
139
  {
140
140
  type: 'checkbox',
141
141
  input: true,
@@ -2,6 +2,7 @@ export default EditFormUtils;
2
2
  declare namespace EditFormUtils {
3
3
  function sortAndFilterComponents(components: any): any;
4
4
  function unifyComponents(objValue: any, srcValue: any): any;
5
+ function tokenVariableDescription(): string;
5
6
  function logicVariablesTable(additional: any): {
6
7
  type: string;
7
8
  tag: string;
@@ -32,6 +32,9 @@ const EditFormUtils = {
32
32
  }
33
33
  return _.isEqual(objValue, srcValue);
34
34
  },
35
+ tokenVariableDescription() {
36
+ return '<tr><th>token</th><td>The decoded JWT token for the authenticated user.</td></tr>';
37
+ },
35
38
  logicVariablesTable(additional) {
36
39
  additional = additional || '';
37
40
  return {
@@ -3,6 +3,7 @@ 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;
6
7
  componentContext(): any;
7
8
  getValueAsString(value: any, options: any): string;
8
9
  getDataValueAsTable(value: any, options: any): string;
@@ -22,6 +22,9 @@ export default class NestedDataComponent extends NestedComponent {
22
22
  get emptyValue() {
23
23
  return {};
24
24
  }
25
+ get shouldAddDefaultValue() {
26
+ return !this.options.noDefaults || !this.options.server;
27
+ }
25
28
  componentContext() {
26
29
  return this.dataValue;
27
30
  }