@formio/js 5.4.1 → 5.4.3

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 (227) hide show
  1. package/README.md +11 -5
  2. package/dist/formio.builder.css +1 -0
  3. package/dist/formio.builder.min.css +1 -1
  4. package/dist/formio.embed.js +1 -1
  5. package/dist/formio.embed.min.js +1 -1
  6. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  7. package/dist/formio.form.css +1 -0
  8. package/dist/formio.form.js +137 -115
  9. package/dist/formio.form.min.css +1 -1
  10. package/dist/formio.form.min.js +1 -1
  11. package/dist/formio.form.min.js.LICENSE.txt +2 -2
  12. package/dist/formio.full.css +1 -0
  13. package/dist/formio.full.js +161 -139
  14. package/dist/formio.full.min.css +1 -1
  15. package/dist/formio.full.min.js +1 -1
  16. package/dist/formio.full.min.js.LICENSE.txt +2 -2
  17. package/dist/formio.js +27 -27
  18. package/dist/formio.min.js +1 -1
  19. package/dist/formio.min.js.LICENSE.txt +2 -2
  20. package/dist/formio.utils.js +19 -19
  21. package/dist/formio.utils.min.js +1 -1
  22. package/dist/formio.utils.min.js.LICENSE.txt +2 -2
  23. package/lib/cjs/Element.js +1 -1
  24. package/lib/cjs/Embed.js +8 -16
  25. package/lib/cjs/Form.js +4 -4
  26. package/lib/cjs/Formio.js +2 -9
  27. package/lib/cjs/InlineEmbed.js +1 -4
  28. package/lib/cjs/PDF.js +28 -8
  29. package/lib/cjs/PDFBuilder.js +6 -10
  30. package/lib/cjs/Webform.d.ts +1 -0
  31. package/lib/cjs/Webform.js +19 -34
  32. package/lib/cjs/WebformBuilder.js +27 -68
  33. package/lib/cjs/Wizard.d.ts +2 -0
  34. package/lib/cjs/Wizard.js +59 -31
  35. package/lib/cjs/WizardBuilder.js +5 -15
  36. package/lib/cjs/addons/PasswordStrength/PasswordStrengthAddon.form.js +2 -6
  37. package/lib/cjs/addons/PasswordStrength/PasswordStrengthAddon.js +3 -9
  38. package/lib/cjs/addons/index.js +1 -3
  39. package/lib/cjs/components/_classes/component/Component.d.ts +5 -5
  40. package/lib/cjs/components/_classes/component/Component.js +60 -132
  41. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +2 -4
  42. package/lib/cjs/components/_classes/component/editForm/Component.edit.display.js +4 -16
  43. package/lib/cjs/components/_classes/component/editForm/Component.edit.validation.js +1 -4
  44. package/lib/cjs/components/_classes/field/Field.js +1 -4
  45. package/lib/cjs/components/_classes/input/Input.js +2 -2
  46. package/lib/cjs/components/_classes/list/ListComponent.js +4 -4
  47. package/lib/cjs/components/_classes/list/editForm/ListComponent.edit.data.js +6 -28
  48. package/lib/cjs/components/_classes/multivalue/Multivalue.js +8 -26
  49. package/lib/cjs/components/_classes/nested/NestedComponent.js +1 -4
  50. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +5 -9
  51. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +1 -3
  52. package/lib/cjs/components/address/Address.js +10 -30
  53. package/lib/cjs/components/address/editForm/Address.edit.provider.js +8 -32
  54. package/lib/cjs/components/alert/Alert.js +3 -6
  55. package/lib/cjs/components/button/Button.js +10 -17
  56. package/lib/cjs/components/button/editForm/Button.edit.display.js +8 -32
  57. package/lib/cjs/components/checkbox/Checkbox.js +4 -10
  58. package/lib/cjs/components/checkbox/editForm/Checkbox.edit.display.js +2 -8
  59. package/lib/cjs/components/columns/Columns.js +5 -17
  60. package/lib/cjs/components/container/Container.js +1 -3
  61. package/lib/cjs/components/currency/Currency.js +2 -7
  62. package/lib/cjs/components/datagrid/DataGrid.js +31 -63
  63. package/lib/cjs/components/datamap/DataMap.js +4 -16
  64. package/lib/cjs/components/datetime/DateTime.js +2 -6
  65. package/lib/cjs/components/datetime/editForm/DateTime.edit.display.js +1 -4
  66. package/lib/cjs/components/day/Day.js +12 -70
  67. package/lib/cjs/components/day/editForm/Day.edit.day.js +1 -3
  68. package/lib/cjs/components/day/editForm/Day.edit.month.js +1 -3
  69. package/lib/cjs/components/editgrid/EditGrid.d.ts +1 -0
  70. package/lib/cjs/components/editgrid/EditGrid.js +18 -44
  71. package/lib/cjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -4
  72. package/lib/cjs/components/file/File.js +52 -75
  73. package/lib/cjs/components/file/editForm/File.edit.display.js +1 -5
  74. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +9 -3
  75. package/lib/cjs/components/file/editForm/File.edit.file.js +27 -52
  76. package/lib/cjs/components/form/Form.js +5 -7
  77. package/lib/cjs/components/html/HTML.d.ts +1 -1
  78. package/lib/cjs/components/html/HTML.js +8 -10
  79. package/lib/cjs/components/number/Number.js +7 -5
  80. package/lib/cjs/components/panel/editForm/Panel.edit.display.js +3 -12
  81. package/lib/cjs/components/password/Password.js +1 -4
  82. package/lib/cjs/components/radio/Radio.js +17 -17
  83. package/lib/cjs/components/radio/editForm/Radio.edit.data.js +4 -14
  84. package/lib/cjs/components/recaptcha/ReCaptcha.js +3 -6
  85. package/lib/cjs/components/select/Select.js +48 -92
  86. package/lib/cjs/components/select/editForm/Select.edit.data.js +37 -182
  87. package/lib/cjs/components/select/editForm/Select.edit.validation.js +1 -9
  88. package/lib/cjs/components/selectboxes/SelectBoxes.js +3 -6
  89. package/lib/cjs/components/signature/Signature.d.ts +1 -1
  90. package/lib/cjs/components/signature/Signature.js +21 -24
  91. package/lib/cjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  92. package/lib/cjs/components/signature/editForm/Signature.edit.display.js +8 -12
  93. package/lib/cjs/components/survey/Survey.js +6 -17
  94. package/lib/cjs/components/survey/editForm/Survey.edit.data.js +4 -12
  95. package/lib/cjs/components/table/editForm/Table.edit.display.js +3 -3
  96. package/lib/cjs/components/tabs/Tabs.js +4 -19
  97. package/lib/cjs/components/tabs/editForm/Tabs.edit.display.js +1 -3
  98. package/lib/cjs/components/tags/Tags.js +4 -14
  99. package/lib/cjs/components/textarea/TextArea.js +8 -15
  100. package/lib/cjs/components/textarea/editForm/TextArea.edit.display.js +14 -56
  101. package/lib/cjs/components/textfield/TextField.js +4 -4
  102. package/lib/cjs/components/textfield/editForm/TextField.edit.display.js +2 -8
  103. package/lib/cjs/components/time/Time.js +1 -4
  104. package/lib/cjs/components/time/editForm/Time.edit.display.js +1 -4
  105. package/lib/cjs/formio.form.js +5 -5
  106. package/lib/cjs/package.json +1 -1
  107. package/lib/cjs/providers/address/AddressProvider.js +1 -1
  108. package/lib/cjs/providers/address/GoogleAddressProvider.js +1 -3
  109. package/lib/cjs/providers/processor/fileProcessor.js +1 -3
  110. package/lib/cjs/providers/storage/azure.js +5 -6
  111. package/lib/cjs/providers/storage/indexeddb.js +17 -18
  112. package/lib/cjs/providers/storage/s3.js +3 -14
  113. package/lib/cjs/providers/storage/url.js +13 -2
  114. package/lib/cjs/providers/storage/xhr.js +19 -28
  115. package/lib/cjs/templates/Templates.js +1 -0
  116. package/lib/cjs/templates/index.d.ts +1 -0
  117. package/lib/cjs/translations/en.d.ts +237 -82
  118. package/lib/cjs/translations/en.js +9 -82
  119. package/lib/cjs/utils/ChoicesWrapper.js +1 -1
  120. package/lib/cjs/utils/builder.js +5 -26
  121. package/lib/cjs/utils/i18n.d.ts +5 -2
  122. package/lib/cjs/utils/i18n.js +33 -12
  123. package/lib/cjs/utils/utils.js +37 -47
  124. package/lib/cjs/widgets/CalendarWidget.js +2 -6
  125. package/lib/mjs/Element.js +1 -1
  126. package/lib/mjs/Embed.js +8 -16
  127. package/lib/mjs/Form.js +4 -4
  128. package/lib/mjs/Formio.js +2 -9
  129. package/lib/mjs/InlineEmbed.js +1 -4
  130. package/lib/mjs/PDF.js +27 -8
  131. package/lib/mjs/PDFBuilder.js +6 -10
  132. package/lib/mjs/Webform.d.ts +1 -0
  133. package/lib/mjs/Webform.js +19 -31
  134. package/lib/mjs/WebformBuilder.js +27 -68
  135. package/lib/mjs/Wizard.d.ts +2 -0
  136. package/lib/mjs/Wizard.js +54 -27
  137. package/lib/mjs/WizardBuilder.js +5 -15
  138. package/lib/mjs/addons/PasswordStrength/PasswordStrengthAddon.form.js +2 -6
  139. package/lib/mjs/addons/PasswordStrength/PasswordStrengthAddon.js +3 -9
  140. package/lib/mjs/addons/index.js +1 -3
  141. package/lib/mjs/components/_classes/component/Component.d.ts +5 -5
  142. package/lib/mjs/components/_classes/component/Component.js +59 -132
  143. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +2 -4
  144. package/lib/mjs/components/_classes/component/editForm/Component.edit.display.js +4 -16
  145. package/lib/mjs/components/_classes/component/editForm/Component.edit.validation.js +1 -4
  146. package/lib/mjs/components/_classes/field/Field.js +1 -4
  147. package/lib/mjs/components/_classes/input/Input.js +2 -2
  148. package/lib/mjs/components/_classes/list/ListComponent.js +4 -4
  149. package/lib/mjs/components/_classes/list/editForm/ListComponent.edit.data.js +6 -28
  150. package/lib/mjs/components/_classes/multivalue/Multivalue.js +8 -26
  151. package/lib/mjs/components/_classes/nested/NestedComponent.js +1 -4
  152. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +5 -9
  153. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +1 -3
  154. package/lib/mjs/components/address/Address.js +10 -30
  155. package/lib/mjs/components/address/editForm/Address.edit.provider.js +8 -32
  156. package/lib/mjs/components/alert/Alert.js +3 -6
  157. package/lib/mjs/components/button/Button.js +9 -16
  158. package/lib/mjs/components/button/editForm/Button.edit.display.js +8 -32
  159. package/lib/mjs/components/checkbox/Checkbox.js +4 -10
  160. package/lib/mjs/components/checkbox/editForm/Checkbox.edit.display.js +2 -8
  161. package/lib/mjs/components/columns/Columns.js +5 -17
  162. package/lib/mjs/components/container/Container.js +1 -3
  163. package/lib/mjs/components/currency/Currency.js +2 -7
  164. package/lib/mjs/components/datagrid/DataGrid.js +30 -63
  165. package/lib/mjs/components/datamap/DataMap.js +12 -18
  166. package/lib/mjs/components/datetime/DateTime.js +2 -6
  167. package/lib/mjs/components/datetime/editForm/DateTime.edit.display.js +1 -4
  168. package/lib/mjs/components/day/Day.js +12 -70
  169. package/lib/mjs/components/day/editForm/Day.edit.day.js +1 -3
  170. package/lib/mjs/components/day/editForm/Day.edit.month.js +1 -3
  171. package/lib/mjs/components/editgrid/EditGrid.d.ts +1 -0
  172. package/lib/mjs/components/editgrid/EditGrid.js +18 -44
  173. package/lib/mjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -4
  174. package/lib/mjs/components/file/File.js +52 -75
  175. package/lib/mjs/components/file/editForm/File.edit.display.js +1 -5
  176. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +9 -3
  177. package/lib/mjs/components/file/editForm/File.edit.file.js +27 -52
  178. package/lib/mjs/components/form/Form.js +5 -7
  179. package/lib/mjs/components/html/HTML.d.ts +1 -1
  180. package/lib/mjs/components/html/HTML.js +8 -10
  181. package/lib/mjs/components/number/Number.js +7 -5
  182. package/lib/mjs/components/panel/editForm/Panel.edit.display.js +3 -12
  183. package/lib/mjs/components/password/Password.js +1 -4
  184. package/lib/mjs/components/radio/Radio.js +17 -17
  185. package/lib/mjs/components/radio/editForm/Radio.edit.data.js +4 -14
  186. package/lib/mjs/components/recaptcha/ReCaptcha.js +3 -6
  187. package/lib/mjs/components/select/Select.js +51 -95
  188. package/lib/mjs/components/select/editForm/Select.edit.data.js +37 -182
  189. package/lib/mjs/components/select/editForm/Select.edit.validation.js +1 -9
  190. package/lib/mjs/components/selectboxes/SelectBoxes.js +3 -6
  191. package/lib/mjs/components/signature/Signature.d.ts +1 -1
  192. package/lib/mjs/components/signature/Signature.js +20 -23
  193. package/lib/mjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  194. package/lib/mjs/components/signature/editForm/Signature.edit.display.js +6 -12
  195. package/lib/mjs/components/survey/Survey.js +6 -17
  196. package/lib/mjs/components/survey/editForm/Survey.edit.data.js +4 -12
  197. package/lib/mjs/components/table/editForm/Table.edit.display.js +3 -3
  198. package/lib/mjs/components/tabs/Tabs.js +4 -19
  199. package/lib/mjs/components/tabs/editForm/Tabs.edit.display.js +1 -3
  200. package/lib/mjs/components/tags/Tags.js +4 -14
  201. package/lib/mjs/components/textarea/TextArea.js +8 -15
  202. package/lib/mjs/components/textarea/editForm/TextArea.edit.display.js +14 -56
  203. package/lib/mjs/components/textfield/TextField.js +4 -4
  204. package/lib/mjs/components/textfield/editForm/TextField.edit.display.js +2 -8
  205. package/lib/mjs/components/time/Time.js +1 -4
  206. package/lib/mjs/components/time/editForm/Time.edit.display.js +1 -4
  207. package/lib/mjs/formio.form.js +6 -6
  208. package/lib/mjs/package.json +1 -1
  209. package/lib/mjs/providers/address/AddressProvider.js +1 -1
  210. package/lib/mjs/providers/address/GoogleAddressProvider.js +1 -3
  211. package/lib/mjs/providers/processor/fileProcessor.js +1 -3
  212. package/lib/mjs/providers/storage/azure.js +5 -6
  213. package/lib/mjs/providers/storage/indexeddb.js +17 -18
  214. package/lib/mjs/providers/storage/s3.js +3 -14
  215. package/lib/mjs/providers/storage/url.js +13 -2
  216. package/lib/mjs/providers/storage/xhr.js +19 -32
  217. package/lib/mjs/templates/Templates.js +1 -0
  218. package/lib/mjs/templates/index.d.ts +1 -0
  219. package/lib/mjs/translations/en.d.ts +237 -82
  220. package/lib/mjs/translations/en.js +88 -0
  221. package/lib/mjs/utils/ChoicesWrapper.js +1 -1
  222. package/lib/mjs/utils/builder.js +5 -26
  223. package/lib/mjs/utils/i18n.d.ts +5 -2
  224. package/lib/mjs/utils/i18n.js +33 -12
  225. package/lib/mjs/utils/utils.js +37 -47
  226. package/lib/mjs/widgets/CalendarWidget.js +2 -6
  227. package/package.json +6 -4
@@ -265,11 +265,7 @@ export default class Webform extends NestedDataComponent {
265
265
  return false;
266
266
  }
267
267
  if (element.nodeName === 'INPUT') {
268
- return ([
269
- 'text',
270
- 'email',
271
- 'password',
272
- ].indexOf(element.type) === -1);
268
+ return ['text', 'email', 'password'].indexOf(element.type) === -1;
273
269
  }
274
270
  return true;
275
271
  }
@@ -542,7 +538,7 @@ export default class Webform extends NestedDataComponent {
542
538
  }
543
539
  if ('schema' in form && compareVersions(form.schema, '1.x') > 0) {
544
540
  this.ready.then(() => {
545
- this.setAlert('alert alert-danger', 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.');
541
+ this.setAlert('alert alert-danger', this.t('newFormSchema'));
546
542
  });
547
543
  }
548
544
  // See if they pass a module, and evaluate it if so.
@@ -739,9 +735,7 @@ export default class Webform extends NestedDataComponent {
739
735
  });
740
736
  }
741
737
  get schema() {
742
- const schema = fastCloneDeep(_.omit(this._form, [
743
- 'components',
744
- ]));
738
+ const schema = fastCloneDeep(_.omit(this._form, ['components']));
745
739
  schema.components = [];
746
740
  this.eachComponent((component) => schema.components.push(component.schema));
747
741
  return schema;
@@ -768,10 +762,12 @@ export default class Webform extends NestedDataComponent {
768
762
  if (!this.options.submissionTimezone && submission.metadata && submission.metadata.timezone) {
769
763
  this.options.submissionTimezone = submission.metadata.timezone;
770
764
  }
765
+ this.subFromServer = _.cloneDeep(submission.data);
771
766
  const changed = super.setValue(submission.data, flags);
772
767
  if (!flags.sanitize) {
773
768
  this.mergeData(this.data, submission.data);
774
769
  }
770
+ // GOTCHA(G-FJS01)
775
771
  submission.data = this.data;
776
772
  this._submission = submission;
777
773
  return changed;
@@ -1008,6 +1004,7 @@ export default class Webform extends NestedDataComponent {
1008
1004
  const component = this.getComponent(key);
1009
1005
  if (component) {
1010
1006
  component.focus();
1007
+ component.scrollIntoView();
1011
1008
  }
1012
1009
  }
1013
1010
  }
@@ -1031,9 +1028,7 @@ export default class Webform extends NestedDataComponent {
1031
1028
  showErrors(errors, triggerEvent) {
1032
1029
  this.loading = false;
1033
1030
  if (!Array.isArray(errors)) {
1034
- errors = [
1035
- errors,
1036
- ];
1031
+ errors = [errors];
1037
1032
  }
1038
1033
  if (Array.isArray(this.errors) &&
1039
1034
  // do not show components validation errors in alert for draft submission
@@ -1065,11 +1060,7 @@ export default class Webform extends NestedDataComponent {
1065
1060
  }
1066
1061
  const displayedErrors = [];
1067
1062
  if (errors.length) {
1068
- errors = _.uniqBy(errors, (error) => [
1069
- error.message,
1070
- error.component?.id,
1071
- error.context?.path,
1072
- ].join());
1063
+ errors = _.uniqBy(errors, (error) => [error.message, error.component?.id, error.context?.path].join());
1073
1064
  const createListItem = (message, index) => {
1074
1065
  const err = errors[index];
1075
1066
  const messageFromIndex = !_.isUndefined(index) && errors && errors[index];
@@ -1096,6 +1087,7 @@ export default class Webform extends NestedDataComponent {
1096
1087
  });
1097
1088
  }
1098
1089
  const errorsList = this.renderTemplate('errorsList', { errors: displayedErrors });
1090
+ // GOTCHA(G-FJS02)
1099
1091
  // Only paint the alert from a subform when the root won't double paint it to avoid a painful flicker
1100
1092
  if (this === this.root || !this.root?.submitted) {
1101
1093
  this.root?.setAlert('danger', errorsList);
@@ -1136,7 +1128,8 @@ export default class Webform extends NestedDataComponent {
1136
1128
  liveRegion.setAttribute('role', 'status');
1137
1129
  liveRegion.setAttribute('aria-live', 'polite');
1138
1130
  liveRegion.setAttribute('aria-atomic', 'true');
1139
- liveRegion.style.cssText = 'position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0);';
1131
+ liveRegion.style.cssText =
1132
+ 'position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0);';
1140
1133
  document.body.appendChild(liveRegion);
1141
1134
  }
1142
1135
  // Announce the submission completion using VPAT clear-and-reset technique
@@ -1352,11 +1345,7 @@ export default class Webform extends NestedDataComponent {
1352
1345
  };
1353
1346
  }
1354
1347
  // Ensure err is an array.
1355
- err = Array.isArray(err)
1356
- ? err
1357
- : [
1358
- err,
1359
- ];
1348
+ err = Array.isArray(err) ? err : [err];
1360
1349
  return reject(err);
1361
1350
  }
1362
1351
  this.loading = true;
@@ -1407,9 +1396,7 @@ export default class Webform extends NestedDataComponent {
1407
1396
  });
1408
1397
  }
1409
1398
  else if (typeof error === 'string') {
1410
- this.serverErrors = [
1411
- { fromServer: true, level: 'error', message: error },
1412
- ];
1399
+ this.serverErrors = [{ fromServer: true, level: 'error', message: error }];
1413
1400
  }
1414
1401
  }
1415
1402
  executeSubmit(options) {
@@ -1467,7 +1454,7 @@ export default class Webform extends NestedDataComponent {
1467
1454
  }
1468
1455
  submitUrl(URL, headers) {
1469
1456
  if (!URL) {
1470
- return console.warn('Missing URL argument');
1457
+ return console.warn(this.t('missingUrl'));
1471
1458
  }
1472
1459
  const submission = this.submission || {};
1473
1460
  const API_URL = URL;
@@ -1488,7 +1475,7 @@ export default class Webform extends NestedDataComponent {
1488
1475
  })
1489
1476
  .then(() => {
1490
1477
  this.emit('requestDone');
1491
- this.setAlert('success', '<p> Success </p>');
1478
+ this.setAlert('success', `<p> ${this.t('success')} </p>`);
1492
1479
  })
1493
1480
  .catch((e) => {
1494
1481
  const message = `${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`;
@@ -1499,9 +1486,10 @@ export default class Webform extends NestedDataComponent {
1499
1486
  });
1500
1487
  }
1501
1488
  else {
1502
- this.emit('error', 'You should add a URL to this button.');
1503
- this.setAlert('warning', 'You should add a URL to this button.');
1504
- return console.warn('You should add a URL to this button.');
1489
+ const message = this.t('urlNotAttachedToBtn');
1490
+ this.emit('error', message);
1491
+ this.setAlert('warning', message);
1492
+ return console.warn(message);
1505
1493
  }
1506
1494
  }
1507
1495
  triggerCaptcha(components = null) {
@@ -202,14 +202,10 @@ export default class WebformBuilder extends Component {
202
202
  },
203
203
  };
204
204
  if (this.options && this.options.resourceTag) {
205
- query.params.tags = [
206
- this.options.resourceTag,
207
- ];
205
+ query.params.tags = [this.options.resourceTag];
208
206
  }
209
207
  else if (!this.options || !this.options.hasOwnProperty('resourceTag')) {
210
- query.params.tags = [
211
- 'builder',
212
- ];
208
+ query.params.tags = ['builder'];
213
209
  }
214
210
  const formio = new Formio(Formio.projectUrl);
215
211
  const isResourcesDisabled = this.options.builder && this.options.builder.resource === false;
@@ -229,7 +225,7 @@ export default class WebformBuilder extends Component {
229
225
  }
230
226
  })
231
227
  .catch((err) => {
232
- console.warn(`Could not load project settings: ${err.message || err}`);
228
+ console.warn(`${this.t('loadingProjectSettingsError')}: ${err.message || err}`);
233
229
  });
234
230
  if (!formio.noProject && !isResourcesDisabled && formio.formsUrl) {
235
231
  const resourceOptions = this.options.builder && this.options.builder.resource;
@@ -318,10 +314,7 @@ export default class WebformBuilder extends Component {
318
314
  allowHTML: true,
319
315
  trigger: 'mouseenter focus',
320
316
  placement: 'top',
321
- delay: [
322
- 200,
323
- 0,
324
- ],
317
+ delay: [200, 0],
325
318
  zIndex: 10000,
326
319
  content: title,
327
320
  });
@@ -341,18 +334,18 @@ export default class WebformBuilder extends Component {
341
334
  editJson: 'single',
342
335
  });
343
336
  if (component.refs.copyComponent) {
344
- this.attachTooltip(component.refs.copyComponent, this.t('Copy'));
337
+ this.attachTooltip(component.refs.copyComponent, this.t('copy'));
345
338
  component.addEventListener(component.refs.copyComponent, 'click', () => this.copyComponent(component));
346
339
  }
347
340
  if (component.refs.pasteComponent) {
348
- const pasteToolTip = this.attachTooltip(component.refs.pasteComponent, this.t('Paste below'));
341
+ const pasteToolTip = this.attachTooltip(component.refs.pasteComponent, this.t('pasteBelow'));
349
342
  component.addEventListener(component.refs.pasteComponent, 'click', () => {
350
343
  pasteToolTip.hide();
351
344
  this.pasteComponent(component);
352
345
  });
353
346
  }
354
347
  if (component.refs.moveComponent) {
355
- this.attachTooltip(component.refs.moveComponent, this.t('Move'));
348
+ this.attachTooltip(component.refs.moveComponent, this.t('move'));
356
349
  if (this.keyboardActionsEnabled) {
357
350
  component.addEventListener(component.refs.moveComponent, 'click', () => {
358
351
  this.moveComponent(component);
@@ -361,20 +354,20 @@ export default class WebformBuilder extends Component {
361
354
  }
362
355
  const parent = this.getParentElement(element);
363
356
  if (component.refs.editComponent) {
364
- this.attachTooltip(component.refs.editComponent, this.t('Edit'));
357
+ this.attachTooltip(component.refs.editComponent, this.t('edit'));
365
358
  component.addEventListener(component.refs.editComponent, 'click', () => this.editComponent(component.schema, parent, false, false, component.component, {
366
359
  inDataGrid: component.isInDataGrid,
367
360
  editComponentPath: component.path,
368
361
  }));
369
362
  }
370
363
  if (component.refs.editJson) {
371
- this.attachTooltip(component.refs.editJson, this.t('Edit JSON'));
364
+ this.attachTooltip(component.refs.editJson, this.t('editJson'));
372
365
  component.addEventListener(component.refs.editJson, 'click', () => this.editComponent(component.schema, parent, false, true, component.component, {
373
366
  editComponentPath: component.path,
374
367
  }));
375
368
  }
376
369
  if (component.refs.removeComponent) {
377
- this.attachTooltip(component.refs.removeComponent, this.t('Remove'));
370
+ this.attachTooltip(component.refs.removeComponent, this.t('remove'));
378
371
  component.addEventListener(component.refs.removeComponent, 'click', () => this.removeComponent(component.schema, parent, component.component, component));
379
372
  }
380
373
  return element;
@@ -457,10 +450,7 @@ export default class WebformBuilder extends Component {
457
450
  const componentSchema = component.component;
458
451
  // If the current component is the namespace, we don't need to find it again.
459
452
  if (namespaceKey === component.key) {
460
- return [
461
- ...componentSchema.components,
462
- componentSchema,
463
- ];
453
+ return [...componentSchema.components, componentSchema];
464
454
  }
465
455
  // Get the namespace component so we have the original object.
466
456
  const namespaceComponent = getComponent(this.form.components, namespaceKey, true);
@@ -472,14 +462,7 @@ export default class WebformBuilder extends Component {
472
462
  return null;
473
463
  }
474
464
  // Some components are their own namespace.
475
- if ([
476
- 'address',
477
- 'container',
478
- 'datagrid',
479
- 'editgrid',
480
- 'dynamicWizard',
481
- 'tree',
482
- ].includes(component.type) ||
465
+ if (['address', 'container', 'datagrid', 'editgrid', 'dynamicWizard', 'tree'].includes(component.type) ||
483
466
  component.tree ||
484
467
  component.arrayTree) {
485
468
  return component.key;
@@ -546,15 +529,11 @@ export default class WebformBuilder extends Component {
546
529
  };
547
530
  const hideShow = (group, forceShow, toggle = false) => {
548
531
  if (forceShow || (toggle && !Array.from(group.classList).includes('show'))) {
549
- group.classList.add([
550
- 'show',
551
- ]);
532
+ group.classList.add(['show']);
552
533
  group.style.display = 'inherit';
553
534
  }
554
535
  else {
555
- group.classList.remove([
556
- 'show',
557
- ]);
536
+ group.classList.remove(['show']);
558
537
  group.style.display = 'none';
559
538
  }
560
539
  };
@@ -598,9 +577,7 @@ export default class WebformBuilder extends Component {
598
577
  }
599
578
  const drake = this.dragula;
600
579
  if (this.refs.form) {
601
- autoScroll([
602
- window,
603
- ], {
580
+ autoScroll([window], {
604
581
  margin: 20,
605
582
  maxSpeed: 6,
606
583
  scrollWhenOutside: true,
@@ -852,7 +829,7 @@ export default class WebformBuilder extends Component {
852
829
  }, true);
853
830
  if (isCompAlreadyExists) {
854
831
  this.webform.redraw();
855
- this.webform.setAlert('danger', `You cannot add more than one ${draggableComponent.key} component to one page.`);
832
+ this.webform.setAlert('danger', this.t('builderUniqueError', { componentKeyOrTitle: draggableComponent.key }));
856
833
  return;
857
834
  }
858
835
  }
@@ -866,7 +843,7 @@ export default class WebformBuilder extends Component {
866
843
  }, true);
867
844
  if (isCompAlreadyExists) {
868
845
  this.webform.redraw();
869
- this.webform.setAlert('danger', `You cannot add more than one ${draggableComponent.title} component to one page.`);
846
+ this.webform.setAlert('danger', this.t('builderUniqueError', { componentKeyOrTitle: draggableComponent.title }));
870
847
  return;
871
848
  }
872
849
  }
@@ -946,7 +923,7 @@ export default class WebformBuilder extends Component {
946
923
  path,
947
924
  fromIndex: index,
948
925
  toIndex,
949
- timestamp: new Date()
926
+ timestamp: new Date(),
950
927
  };
951
928
  // New event that allows explicit tracking of reordering
952
929
  this.emit('moveComponent', payload);
@@ -1036,8 +1013,8 @@ export default class WebformBuilder extends Component {
1036
1013
  (Array.isArray(component.columns) && component.columns.length));
1037
1014
  if (this.options.alwaysConfirmComponentRemoval || removingComponentsGroup) {
1038
1015
  const message = removingComponentsGroup
1039
- ? 'Removing this component will also remove all of its children. Are you sure you want to do this?'
1040
- : 'Are you sure you want to remove this component?';
1016
+ ? 'confirmComponentRemoveWithChildren'
1017
+ : 'confirmComponentRemove';
1041
1018
  remove = window.confirm(this.t(message));
1042
1019
  }
1043
1020
  if (!original) {
@@ -1106,10 +1083,7 @@ export default class WebformBuilder extends Component {
1106
1083
  config: this.options.formConfig || {},
1107
1084
  sanitizeConfig,
1108
1085
  };
1109
- const fieldsToRemoveDoubleQuotes = [
1110
- 'label',
1111
- 'tooltip',
1112
- ];
1086
+ const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1113
1087
  this.preview.form.components.forEach((component) => this.replaceDoubleQuotes(component, fieldsToRemoveDoubleQuotes));
1114
1088
  const previewElement = this.componentEdit.querySelector(`[${this._referenceAttributeName}="preview"]`);
1115
1089
  if (previewElement) {
@@ -1279,10 +1253,7 @@ export default class WebformBuilder extends Component {
1279
1253
  submissionData.components = this.originalDefaultValue.components;
1280
1254
  this.originalDefaultValue = null;
1281
1255
  }
1282
- const fieldsToRemoveDoubleQuotes = [
1283
- 'label',
1284
- 'tooltip',
1285
- ];
1256
+ const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1286
1257
  this.replaceDoubleQuotes(submissionData, fieldsToRemoveDoubleQuotes);
1287
1258
  this.hook('beforeSaveComponentSettings', submissionData);
1288
1259
  let comp = null;
@@ -1411,13 +1382,7 @@ export default class WebformBuilder extends Component {
1411
1382
  editFormOptions.flags = flags;
1412
1383
  this.hook('editComponentParentInstance', editFormOptions, parent);
1413
1384
  this.editForm = new Webform({
1414
- ..._.omit(this.options, [
1415
- 'hooks',
1416
- 'builder',
1417
- 'events',
1418
- 'attachMode',
1419
- 'skipInit',
1420
- ]),
1385
+ ..._.omit(this.options, ['hooks', 'builder', 'events', 'attachMode', 'skipInit']),
1421
1386
  language: this.options.language,
1422
1387
  ...editFormOptions,
1423
1388
  evalContext: {
@@ -1510,16 +1475,10 @@ export default class WebformBuilder extends Component {
1510
1475
  }
1511
1476
  let isComponentLabelChanged = false;
1512
1477
  if (event.changed.instance) {
1513
- isComponentLabelChanged = [
1514
- 'label',
1515
- 'title',
1516
- ].includes(event.changed.instance.path);
1478
+ isComponentLabelChanged = ['label', 'title'].includes(event.changed.instance.path);
1517
1479
  }
1518
1480
  else if (event.changed.component) {
1519
- isComponentLabelChanged = [
1520
- 'label',
1521
- 'title',
1522
- ].includes(event.changed.component.key);
1481
+ isComponentLabelChanged = ['label', 'title'].includes(event.changed.component.key);
1523
1482
  }
1524
1483
  if (isComponentLabelChanged) {
1525
1484
  // Ensure this component has a key.
@@ -1680,7 +1639,7 @@ export default class WebformBuilder extends Component {
1680
1639
  */
1681
1640
  copyComponent(component) {
1682
1641
  if (!window.sessionStorage) {
1683
- return console.warn('Session storage is not supported in this browser.');
1642
+ return console.warn(this.t('sessionStorageSupportError'));
1684
1643
  }
1685
1644
  this.addClass(this.refs.form, 'builder-paste-mode');
1686
1645
  window.sessionStorage.setItem('formio.clipboard', JSON.stringify(component.schema));
@@ -1692,7 +1651,7 @@ export default class WebformBuilder extends Component {
1692
1651
  */
1693
1652
  pasteComponent(component) {
1694
1653
  if (!window.sessionStorage) {
1695
- return console.warn('Session storage is not supported in this browser.');
1654
+ return console.warn(this.t('sessionStorageSupportError'));
1696
1655
  }
1697
1656
  this.removeClass(this.refs.form, 'builder-paste-mode');
1698
1657
  if (window.sessionStorage) {
@@ -84,6 +84,8 @@ declare class Wizard extends Webform {
84
84
  get currentPage(): any;
85
85
  getNextPage(): number | null;
86
86
  getPreviousPage(): number;
87
+ renderTemplate(...args: any[]): any;
88
+ mergeDefaultsFromSchema(data: any): void;
87
89
  beforeSubmit(): Promise<any[]>;
88
90
  beforePage(next: any): Promise<any>;
89
91
  emitNextPage(): void;
package/lib/mjs/Wizard.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import Webform from './Webform';
3
3
  import { Formio } from './Formio';
4
- import { fastCloneDeep, checkCondition, firstNonNil, uniqueKey, eachComponent, screenReaderSpeech } from './utils';
4
+ import { fastCloneDeep, checkCondition, firstNonNil, uniqueKey, eachComponent, getModelType, screenReaderSpeech, } from './utils';
5
5
  export default class Wizard extends Webform {
6
6
  /**
7
7
  * Constructor for wizard-based forms.
@@ -30,9 +30,7 @@ export default class Wizard extends Webform {
30
30
  this.page = 0;
31
31
  this.currentPanel = null;
32
32
  this.currentNextPage = 0;
33
- this._seenPages = [
34
- 0,
35
- ];
33
+ this._seenPages = [0];
36
34
  this.subWizards = [];
37
35
  this.allPages = [];
38
36
  this.lastPromise = Promise.resolve();
@@ -101,6 +99,7 @@ export default class Wizard extends Webform {
101
99
  this.on('subWizardsUpdated', (subForm) => {
102
100
  const subWizard = this.subWizards.find((subWizard) => subForm?.id && subWizard.subForm?.id === subForm?.id);
103
101
  if (this.subWizards.length && subWizard) {
102
+ // GOTCHA(G-FJS01)
104
103
  subWizard.subForm.setValue(subForm._submission, {}, true);
105
104
  this.establishPages();
106
105
  this.redraw();
@@ -132,12 +131,7 @@ export default class Wizard extends Webform {
132
131
  return buttons;
133
132
  }
134
133
  get buttonOrder() {
135
- const defaultButtonOrder = [
136
- 'cancel',
137
- 'previous',
138
- 'next',
139
- 'submit',
140
- ];
134
+ const defaultButtonOrder = ['cancel', 'previous', 'next', 'submit'];
141
135
  return (this.options.properties?.wizardButtonOrder?.toLowerCase().split(', ') ?? defaultButtonOrder);
142
136
  }
143
137
  get renderContext() {
@@ -200,7 +194,7 @@ export default class Wizard extends Webform {
200
194
  wizardNav,
201
195
  components: this.renderComponents([
202
196
  ...this.prefixComps,
203
- ...this.currentPage?.components || [],
197
+ ...(this.currentPage?.components || []),
204
198
  ...this.suffixComps,
205
199
  ]),
206
200
  }, this.builderMode ? 'builder' : 'form');
@@ -262,7 +256,7 @@ export default class Wizard extends Webform {
262
256
  this.hook('attachWebform', element, this);
263
257
  const promises = this.attachComponents(this.refs[this.wizardKey], [
264
258
  ...this.prefixComps,
265
- ...this.currentPage?.components || [],
259
+ ...(this.currentPage?.components || []),
266
260
  ...this.suffixComps,
267
261
  ]);
268
262
  this.attachNav();
@@ -414,11 +408,7 @@ export default class Wizard extends Webform {
414
408
  // Get all components including all nested components and line up in the correct order
415
409
  const getAllComponents = (nestedComp, compsArr, pushAllowed = true) => {
416
410
  const nestedPages = [];
417
- const dataArrayComponents = [
418
- 'datagrid',
419
- 'editgrid',
420
- 'dynamicWizard',
421
- ];
411
+ const dataArrayComponents = ['datagrid', 'editgrid', 'dynamicWizard'];
422
412
  const currentComponents = nestedComp?.subForm
423
413
  ? this.getSortedComponents(nestedComp.subForm)
424
414
  : nestedComp?.components || [];
@@ -537,7 +527,7 @@ export default class Wizard extends Webform {
537
527
  const forceShow = this.shouldForceShow(item);
538
528
  const forceHide = this.shouldForceHide(item);
539
529
  let isVisible = !page
540
- ? (checkCondition(item, data, data, this.component, this) && !item.hidden)
530
+ ? checkCondition(item, data, data, this.component, this) && !item.hidden
541
531
  : page.visible;
542
532
  if (forceShow) {
543
533
  isVisible = true;
@@ -621,7 +611,7 @@ export default class Wizard extends Webform {
621
611
  this.redraw();
622
612
  return Promise.resolve();
623
613
  }
624
- return Promise.reject('Page not found');
614
+ return Promise.reject(this.t('pageNotFound'));
625
615
  }
626
616
  pageFieldLogic(page) {
627
617
  if (this.pages?.[page]) {
@@ -674,7 +664,48 @@ export default class Wizard extends Webform {
674
664
  getPreviousPage() {
675
665
  return this.page - 1;
676
666
  }
667
+ renderTemplate(...args) {
668
+ if (args[0] === 'errorsList' && _.isPlainObject(args[1])) {
669
+ const pages = this.getPages({ all: true });
670
+ const errors = args[1].errors;
671
+ if (_.isArray(errors)) {
672
+ _.forEach(errors, (compWithError) => {
673
+ const pageNum = _.findIndex(pages, (page) => page.getComponent(compWithError.keyOrPath));
674
+ if (pageNum >= 0) {
675
+ compWithError.errorPageTitle = _.get(pages[pageNum], 'component.title');
676
+ }
677
+ });
678
+ }
679
+ }
680
+ return super.renderTemplate(...args);
681
+ }
682
+ mergeDefaultsFromSchema(data) {
683
+ const components = this.form?.components;
684
+ if (!components || !data || this.options?.readOnly) {
685
+ return;
686
+ }
687
+ eachComponent(components, (component, _path, _c, _parent, compPaths) => {
688
+ if (!component?.key ||
689
+ component.type === 'button' ||
690
+ component.persistent === 'client-only' ||
691
+ !component.hasOwnProperty('clearOnHide') ||
692
+ component.clearOnHide !== false ||
693
+ !component.hasOwnProperty('defaultValue')) {
694
+ return;
695
+ }
696
+ const modelType = getModelType(component);
697
+ if (modelType === 'none' || modelType === 'content' || component.input === false) {
698
+ return;
699
+ }
700
+ const dataPath = compPaths?.dataPath || component.key;
701
+ if (!dataPath || _.get(data, dataPath) != null) {
702
+ return;
703
+ }
704
+ _.set(data, dataPath, component.defaultValue);
705
+ }, true);
706
+ }
677
707
  beforeSubmit() {
708
+ this.mergeDefaultsFromSchema(this.data);
678
709
  const pages = this.getPages({ all: true });
679
710
  return Promise.all(pages.map((page) => {
680
711
  this.triggerButtonCaptcha(page);
@@ -820,9 +851,7 @@ export default class Wizard extends Webform {
820
851
  key: 'page1',
821
852
  components: this.component.components,
822
853
  };
823
- this.component.components = [
824
- newPage,
825
- ];
854
+ this.component.components = [newPage];
826
855
  this.originalComponents.push(_.clone(newPage));
827
856
  }
828
857
  }
@@ -833,7 +862,8 @@ export default class Wizard extends Webform {
833
862
  return super.setForm(form, flags);
834
863
  }
835
864
  onSetForm(clonedForm, initialForm) {
836
- this.component.components = (this.parent ? initialForm.components : clonedForm.components) || [];
865
+ this.component.components =
866
+ (this.parent ? initialForm.components : clonedForm.components) || [];
837
867
  this.setComponentSchema();
838
868
  }
839
869
  setEditMode(submission) {
@@ -865,10 +895,7 @@ export default class Wizard extends Webform {
865
895
  }
866
896
  isClickable(page, index) {
867
897
  return (this.page !== index &&
868
- firstNonNil([
869
- _.get(page, 'breadcrumbClickable'),
870
- this.options.breadcrumbSettings.clickable,
871
- ]));
898
+ firstNonNil([_.get(page, 'breadcrumbClickable'), this.options.breadcrumbSettings.clickable]));
872
899
  }
873
900
  hasButton(name, nextPage = this.getNextPage()) {
874
901
  // get page options with global options as default values
@@ -18,9 +18,7 @@ export default class WizardBuilder extends WebformBuilder {
18
18
  options.display = 'wizard';
19
19
  super(element, options);
20
20
  this._form = {
21
- components: [
22
- this.getPageConfig(1),
23
- ],
21
+ components: [this.getPageConfig(1)],
24
22
  };
25
23
  this.page = 0;
26
24
  // Need to create a component order for each group.
@@ -101,9 +99,7 @@ export default class WizardBuilder extends WebformBuilder {
101
99
  }
102
100
  if (this.pages.length === 0) {
103
101
  const components = this._form.components.filter((component) => component.type !== 'button');
104
- this._form.components = [
105
- this.getPageConfig(1, components),
106
- ];
102
+ this._form.components = [this.getPageConfig(1, components)];
107
103
  }
108
104
  else {
109
105
  const components = this._form.components.filter((component) => component.type !== 'button' || component.action !== 'submit');
@@ -154,9 +150,7 @@ export default class WizardBuilder extends WebformBuilder {
154
150
  page.parentNode.dragInfo = { index };
155
151
  });
156
152
  if (this.dragulaLib) {
157
- this.navigationDragula = this.dragulaLib([
158
- this.element.querySelector('.wizard-pages'),
159
- ], {
153
+ this.navigationDragula = this.dragulaLib([this.element.querySelector('.wizard-pages')], {
160
154
  moves: (el) => !el.classList.contains('wizard-add-page'),
161
155
  accepts: (el, target, source, sibling) => (sibling ? true : false),
162
156
  }).on('drop', this.onReorder.bind(this));
@@ -187,11 +181,7 @@ export default class WizardBuilder extends WebformBuilder {
187
181
  this.webform.setForm({
188
182
  display: 'form',
189
183
  type: 'form',
190
- components: page
191
- ? [
192
- page,
193
- ]
194
- : [],
184
+ components: page ? [page] : [],
195
185
  controller: this._form?.controller || '',
196
186
  }, { keepAsReference: true });
197
187
  return this.redraw();
@@ -225,7 +215,7 @@ export default class WizardBuilder extends WebformBuilder {
225
215
  const isSiblingAnAddPageButton = sibling?.classList.contains('wizard-add-page');
226
216
  // We still can paste before Add Page button
227
217
  if (!element.dragInfo || (sibling && !sibling.dragInfo && !isSiblingAnAddPageButton)) {
228
- console.warn('There is no Drag Info available for either dragged or sibling element');
218
+ console.warn(this.t('noDragInfoError'));
229
219
  return;
230
220
  }
231
221
  const oldPosition = element.dragInfo.index;
@@ -8,9 +8,7 @@ export default [
8
8
  enableRowGroups: false,
9
9
  initEmpty: false,
10
10
  tableView: false,
11
- defaultValue: [
12
- {},
13
- ],
11
+ defaultValue: [{}],
14
12
  key: 'levels',
15
13
  type: 'editgrid',
16
14
  input: true,
@@ -121,9 +119,7 @@ export default [
121
119
  enableRowGroups: false,
122
120
  initEmpty: false,
123
121
  tableView: false,
124
- defaultValue: [
125
- {},
126
- ],
122
+ defaultValue: [{}],
127
123
  key: 'rulesSettings',
128
124
  type: 'datagrid',
129
125
  input: true,