@formio/js 5.1.0-dev.6048.569bfc1 → 5.1.0-dev.6049.6110ca0

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 (230) hide show
  1. package/Changelog.md +99 -310
  2. package/README.md +7 -0
  3. package/dist/formio.builder.css +1 -0
  4. package/dist/formio.builder.min.css +1 -1
  5. package/dist/formio.form.css +1 -0
  6. package/dist/formio.form.js +658 -669
  7. package/dist/formio.form.min.css +1 -1
  8. package/dist/formio.form.min.js +1 -1
  9. package/dist/formio.form.min.js.LICENSE.txt +3 -1
  10. package/dist/formio.full.css +1 -0
  11. package/dist/formio.full.js +685 -696
  12. package/dist/formio.full.min.css +1 -1
  13. package/dist/formio.full.min.js +1 -1
  14. package/dist/formio.full.min.js.LICENSE.txt +3 -1
  15. package/dist/formio.js +90 -68
  16. package/dist/formio.min.js +1 -1
  17. package/dist/formio.utils.js +103 -81
  18. package/dist/formio.utils.min.js +1 -1
  19. package/dist/formio.utils.min.js.LICENSE.txt +3 -1
  20. package/lib/cjs/Element.d.ts +2 -1
  21. package/lib/cjs/Element.js +18 -39
  22. package/lib/cjs/EventEmitter.js +2 -25
  23. package/lib/cjs/Form.js +2 -25
  24. package/lib/cjs/PDF.js +1 -1
  25. package/lib/cjs/PDFBuilder.d.ts +1 -0
  26. package/lib/cjs/PDFBuilder.js +10 -11
  27. package/lib/cjs/Webform.d.ts +2 -2
  28. package/lib/cjs/Webform.js +14 -15
  29. package/lib/cjs/WebformBuilder.d.ts +2 -1
  30. package/lib/cjs/WebformBuilder.js +62 -20
  31. package/lib/cjs/Wizard.d.ts +2 -2
  32. package/lib/cjs/Wizard.js +40 -26
  33. package/lib/cjs/WizardBuilder.js +1 -1
  34. package/lib/cjs/components/_classes/component/Component.d.ts +44 -13
  35. package/lib/cjs/components/_classes/component/Component.js +156 -95
  36. package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  37. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +19 -0
  38. package/lib/cjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  39. package/lib/cjs/components/_classes/component/editForm/utils.js +1 -1
  40. package/lib/cjs/components/_classes/componentModal/ComponentModal.js +1 -1
  41. package/lib/cjs/components/_classes/input/Input.js +1 -1
  42. package/lib/cjs/components/_classes/list/ListComponent.js +3 -3
  43. package/lib/cjs/components/_classes/nested/NestedComponent.form.js +13 -0
  44. package/lib/cjs/components/_classes/nested/NestedComponent.js +15 -8
  45. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  46. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.d.ts +0 -2
  47. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +1 -12
  48. package/lib/cjs/components/address/Address.d.ts +8 -0
  49. package/lib/cjs/components/address/Address.js +32 -9
  50. package/lib/cjs/components/address/editForm/Address.edit.display.d.ts +4 -0
  51. package/lib/cjs/components/address/editForm/Address.edit.display.js +1 -0
  52. package/lib/cjs/components/address/editForm/Address.edit.provider.js +8 -8
  53. package/lib/cjs/components/alert/Alert.js +1 -1
  54. package/lib/cjs/components/button/Button.d.ts +1 -1
  55. package/lib/cjs/components/button/Button.js +7 -11
  56. package/lib/cjs/components/checkbox/Checkbox.js +1 -1
  57. package/lib/cjs/components/container/Container.js +1 -1
  58. package/lib/cjs/components/content/editForm/Content.edit.display.js +8 -0
  59. package/lib/cjs/components/currency/Currency.js +1 -1
  60. package/lib/cjs/components/currency/editForm/Currency.edit.display.js +12 -0
  61. package/lib/cjs/components/datagrid/DataGrid.js +5 -1
  62. package/lib/cjs/components/datetime/DateTime.d.ts +1 -1
  63. package/lib/cjs/components/datetime/DateTime.js +15 -13
  64. package/lib/cjs/components/datetime/editForm/DateTime.edit.validation.d.ts +66 -15
  65. package/lib/cjs/components/datetime/editForm/DateTime.edit.validation.js +68 -47
  66. package/lib/cjs/components/day/Day.js +2 -2
  67. package/lib/cjs/components/day/editForm/Day.edit.display.js +8 -0
  68. package/lib/cjs/components/editgrid/EditGrid.js +4 -2
  69. package/lib/cjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  70. package/lib/cjs/components/email/editForm/Email.edit.display.js +12 -0
  71. package/lib/cjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
  72. package/lib/cjs/components/file/File.js +6 -2
  73. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +13 -0
  74. package/lib/cjs/components/file/editForm/File.edit.file.js +1 -0
  75. package/lib/cjs/components/form/Form.d.ts +0 -1
  76. package/lib/cjs/components/form/Form.js +31 -23
  77. package/lib/cjs/components/form/editForm/Form.edit.form.js +4 -3
  78. package/lib/cjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
  79. package/lib/cjs/components/html/editForm/HTML.edit.display.js +8 -0
  80. package/lib/cjs/components/number/Number.js +1 -1
  81. package/lib/cjs/components/number/editForm/Number.edit.display.js +12 -0
  82. package/lib/cjs/components/panel/Panel.js +1 -1
  83. package/lib/cjs/components/password/editForm/Password.edit.display.js +13 -1
  84. package/lib/cjs/components/phonenumber/PhoneNumber.form.js +9 -1
  85. package/lib/cjs/components/radio/Radio.d.ts +8 -0
  86. package/lib/cjs/components/radio/Radio.js +16 -6
  87. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  88. package/lib/cjs/components/select/Select.d.ts +1 -0
  89. package/lib/cjs/components/select/Select.js +21 -5
  90. package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +68 -110
  91. package/lib/cjs/components/select/editForm/Select.edit.data.js +2 -37
  92. package/lib/cjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  93. package/lib/cjs/components/selectboxes/SelectBoxes.js +7 -1
  94. package/lib/cjs/components/signature/Signature.js +1 -1
  95. package/lib/cjs/components/survey/Survey.js +2 -2
  96. package/lib/cjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
  97. package/lib/cjs/components/tags/Tags.js +1 -1
  98. package/lib/cjs/components/textarea/TextArea.js +10 -2
  99. package/lib/cjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
  100. package/lib/cjs/components/textfield/TextField.js +9 -32
  101. package/lib/cjs/components/time/Time.js +1 -1
  102. package/lib/cjs/components/unknown/Unknown.form.d.ts +2 -1
  103. package/lib/cjs/components/unknown/Unknown.form.js +13 -9
  104. package/lib/cjs/components/url/editForm/Url.edit.display.js +12 -0
  105. package/lib/cjs/components/well/editForm/Well.edit.display.js +8 -0
  106. package/lib/cjs/formio.form.js +5 -5
  107. package/lib/cjs/providers/storage/uploadAdapter.js +8 -6
  108. package/lib/cjs/translations/en.d.ts +1 -234
  109. package/lib/cjs/translations/en.js +4 -2
  110. package/lib/cjs/utils/Evaluator.d.ts +20 -6
  111. package/lib/cjs/utils/Evaluator.js +38 -15
  112. package/lib/cjs/utils/builder.js +5 -5
  113. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +3 -3
  114. package/lib/cjs/utils/formUtils.d.ts +2 -2
  115. package/lib/cjs/utils/index.d.ts +169 -2
  116. package/lib/cjs/utils/index.js +22 -2
  117. package/lib/cjs/utils/utils.d.ts +31 -37
  118. package/lib/cjs/utils/utils.js +80 -135
  119. package/lib/cjs/widgets/CalendarWidget.d.ts +1 -8
  120. package/lib/cjs/widgets/CalendarWidget.js +19 -40
  121. package/lib/mjs/Element.d.ts +2 -1
  122. package/lib/mjs/Element.js +11 -9
  123. package/lib/mjs/EventEmitter.js +2 -2
  124. package/lib/mjs/Form.js +1 -1
  125. package/lib/mjs/PDF.js +1 -1
  126. package/lib/mjs/PDFBuilder.d.ts +1 -0
  127. package/lib/mjs/PDFBuilder.js +9 -10
  128. package/lib/mjs/Webform.d.ts +2 -2
  129. package/lib/mjs/Webform.js +12 -13
  130. package/lib/mjs/WebformBuilder.d.ts +2 -1
  131. package/lib/mjs/WebformBuilder.js +53 -13
  132. package/lib/mjs/Wizard.d.ts +2 -2
  133. package/lib/mjs/Wizard.js +38 -24
  134. package/lib/mjs/WizardBuilder.js +1 -1
  135. package/lib/mjs/components/_classes/component/Component.d.ts +44 -13
  136. package/lib/mjs/components/_classes/component/Component.js +129 -45
  137. package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  138. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +19 -0
  139. package/lib/mjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  140. package/lib/mjs/components/_classes/component/editForm/utils.js +1 -1
  141. package/lib/mjs/components/_classes/componentModal/ComponentModal.js +1 -1
  142. package/lib/mjs/components/_classes/input/Input.js +1 -1
  143. package/lib/mjs/components/_classes/list/ListComponent.js +3 -3
  144. package/lib/mjs/components/_classes/nested/NestedComponent.form.js +13 -0
  145. package/lib/mjs/components/_classes/nested/NestedComponent.js +15 -8
  146. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  147. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.d.ts +0 -2
  148. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +1 -12
  149. package/lib/mjs/components/address/Address.d.ts +8 -0
  150. package/lib/mjs/components/address/Address.js +32 -9
  151. package/lib/mjs/components/address/editForm/Address.edit.display.d.ts +4 -0
  152. package/lib/mjs/components/address/editForm/Address.edit.display.js +1 -0
  153. package/lib/mjs/components/address/editForm/Address.edit.provider.js +8 -8
  154. package/lib/mjs/components/alert/Alert.js +1 -1
  155. package/lib/mjs/components/button/Button.d.ts +1 -1
  156. package/lib/mjs/components/button/Button.js +7 -10
  157. package/lib/mjs/components/checkbox/Checkbox.js +1 -1
  158. package/lib/mjs/components/container/Container.js +1 -1
  159. package/lib/mjs/components/content/editForm/Content.edit.display.js +8 -0
  160. package/lib/mjs/components/currency/Currency.js +1 -1
  161. package/lib/mjs/components/currency/editForm/Currency.edit.display.js +12 -0
  162. package/lib/mjs/components/datagrid/DataGrid.js +5 -1
  163. package/lib/mjs/components/datetime/DateTime.d.ts +1 -1
  164. package/lib/mjs/components/datetime/DateTime.js +15 -13
  165. package/lib/mjs/components/datetime/editForm/DateTime.edit.validation.d.ts +66 -15
  166. package/lib/mjs/components/datetime/editForm/DateTime.edit.validation.js +68 -47
  167. package/lib/mjs/components/day/Day.js +2 -2
  168. package/lib/mjs/components/day/editForm/Day.edit.display.js +8 -0
  169. package/lib/mjs/components/editgrid/EditGrid.js +4 -2
  170. package/lib/mjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  171. package/lib/mjs/components/email/editForm/Email.edit.display.js +12 -0
  172. package/lib/mjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
  173. package/lib/mjs/components/file/File.js +6 -2
  174. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +13 -0
  175. package/lib/mjs/components/file/editForm/File.edit.file.js +1 -0
  176. package/lib/mjs/components/form/Form.d.ts +0 -1
  177. package/lib/mjs/components/form/Form.js +30 -23
  178. package/lib/mjs/components/form/editForm/Form.edit.form.js +3 -2
  179. package/lib/mjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
  180. package/lib/mjs/components/html/editForm/HTML.edit.display.js +8 -0
  181. package/lib/mjs/components/number/Number.js +1 -1
  182. package/lib/mjs/components/number/editForm/Number.edit.display.js +12 -0
  183. package/lib/mjs/components/panel/Panel.js +1 -1
  184. package/lib/mjs/components/password/editForm/Password.edit.display.js +13 -1
  185. package/lib/mjs/components/phonenumber/PhoneNumber.form.js +9 -1
  186. package/lib/mjs/components/radio/Radio.d.ts +8 -0
  187. package/lib/mjs/components/radio/Radio.js +16 -6
  188. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  189. package/lib/mjs/components/select/Select.d.ts +1 -0
  190. package/lib/mjs/components/select/Select.js +21 -5
  191. package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +68 -110
  192. package/lib/mjs/components/select/editForm/Select.edit.data.js +2 -37
  193. package/lib/mjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  194. package/lib/mjs/components/selectboxes/SelectBoxes.js +7 -1
  195. package/lib/mjs/components/signature/Signature.js +1 -1
  196. package/lib/mjs/components/survey/Survey.js +2 -2
  197. package/lib/mjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
  198. package/lib/mjs/components/tags/Tags.js +1 -1
  199. package/lib/mjs/components/textarea/TextArea.js +10 -2
  200. package/lib/mjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
  201. package/lib/mjs/components/textfield/TextField.js +3 -3
  202. package/lib/mjs/components/time/Time.js +1 -1
  203. package/lib/mjs/components/unknown/Unknown.form.d.ts +2 -1
  204. package/lib/mjs/components/unknown/Unknown.form.js +13 -9
  205. package/lib/mjs/components/url/editForm/Url.edit.display.js +12 -0
  206. package/lib/mjs/components/well/editForm/Well.edit.display.js +8 -0
  207. package/lib/mjs/formio.form.js +3 -3
  208. package/lib/mjs/providers/storage/uploadAdapter.js +8 -6
  209. package/lib/mjs/translations/en.d.ts +1 -234
  210. package/lib/mjs/translations/en.js +6 -47
  211. package/lib/mjs/utils/Evaluator.d.ts +20 -6
  212. package/lib/mjs/utils/Evaluator.js +31 -13
  213. package/lib/mjs/utils/builder.js +1 -1
  214. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +1 -1
  215. package/lib/mjs/utils/formUtils.d.ts +2 -2
  216. package/lib/mjs/utils/index.d.ts +169 -2
  217. package/lib/mjs/utils/index.js +18 -1
  218. package/lib/mjs/utils/utils.d.ts +31 -37
  219. package/lib/mjs/utils/utils.js +72 -109
  220. package/lib/mjs/widgets/CalendarWidget.d.ts +1 -8
  221. package/lib/mjs/widgets/CalendarWidget.js +19 -40
  222. package/package.json +8 -6
  223. package/lib/cjs/i18n.d.ts +0 -13
  224. package/lib/cjs/i18n.js +0 -19
  225. package/lib/cjs/utils/i18n.d.ts +0 -19
  226. package/lib/cjs/utils/i18n.js +0 -120
  227. package/lib/mjs/i18n.d.ts +0 -13
  228. package/lib/mjs/i18n.js +0 -14
  229. package/lib/mjs/utils/i18n.d.ts +0 -19
  230. package/lib/mjs/utils/i18n.js +0 -112
@@ -1,8 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import { Formio } from './Formio';
3
3
  import WebformBuilder from './WebformBuilder';
4
- import { fastCloneDeep, getElementRect, getBrowserInfo } from './utils/utils';
5
- import { eachComponent } from './utils/formUtils';
4
+ import { fastCloneDeep, getElementRect, getBrowserInfo, eachComponent } from './utils';
6
5
  import BuilderUtils from './utils/builder';
7
6
  import PDF from './PDF';
8
7
  export default class PDFBuilder extends WebformBuilder {
@@ -445,21 +444,21 @@ export default class PDFBuilder extends WebformBuilder {
445
444
  e.target.style.cursor = 'default';
446
445
  }
447
446
  highlightInvalidComponents() {
448
- const repeatablePaths = this.findRepeatablePaths();
447
+ const repeatablePathsComps = this.findComponentsWithRepeatablePaths();
449
448
  // update elements which path was duplicated if any pathes have been changed
450
- if (!_.isEqual(this.repeatablePaths, repeatablePaths)) {
451
- eachComponent(this.webform.getComponents(), (comp, path) => {
452
- if (this.repeatablePaths.includes(path)) {
449
+ if (!_.isEqual(this.repeatablePathsComps, repeatablePathsComps)) {
450
+ eachComponent(this.webform.getComponents(), (comp) => {
451
+ if (this.repeatablePathsComps.includes(comp.component)) {
453
452
  this.webform.postMessage({ name: 'updateElement', data: comp.component });
454
453
  }
455
454
  });
456
- this.repeatablePaths = repeatablePaths;
455
+ this.repeatablePathsComps = repeatablePathsComps;
457
456
  }
458
- if (!repeatablePaths.length) {
457
+ if (!repeatablePathsComps.length) {
459
458
  return;
460
459
  }
461
- eachComponent(this.webform.getComponents(), (comp, path) => {
462
- if (this.repeatablePaths.includes(path)) {
460
+ eachComponent(this.webform.getComponents(), (comp) => {
461
+ if (this.repeatablePathsComps.includes(comp)) {
463
462
  this.webform.postMessage({
464
463
  name: 'showBuilderErrors',
465
464
  data: {
@@ -45,7 +45,7 @@
45
45
  * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
46
46
  * @property {boolean} [readOnly] - Set this form to readOnly.
47
47
  * @property {boolean} [noAlerts] - Disable the alerts dialog.
48
- * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
48
+ * @property {{[key: string]: string}} [enTranslation] - The translation file for this rendering.
49
49
  * @property {string} [template] - Custom logic for creation of elements.
50
50
  * @property {boolean} [noDefaults] - Exclude default values from the settings.
51
51
  * @property {any} [fileService] - The file service for this form.
@@ -586,7 +586,7 @@ export type FormOptions = {
586
586
  /**
587
587
  * - The translation file for this rendering.
588
588
  */
589
- i18n?: {
589
+ enTranslation?: {
590
590
  [key: string]: string;
591
591
  } | undefined;
592
592
  /**
@@ -1,13 +1,12 @@
1
1
  import _ from 'lodash';
2
- import moment from 'moment';
3
2
  import { compareVersions } from 'compare-versions';
4
3
  import EventEmitter from './EventEmitter';
5
- import i18nDefaults from './i18n';
4
+ import enTranslation from './translations/en';
6
5
  import { Formio } from './Formio';
7
6
  import Components from './components/Components';
8
7
  import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent';
9
- import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, } from './utils/utils';
10
- import { eachComponent } from './utils/formUtils';
8
+ import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, eachComponent } from './utils';
9
+ import dayjs from "dayjs";
11
10
  // We need this here because dragula pulls in CustomEvent class that requires global to exist.
12
11
  if (typeof window !== 'undefined' && typeof window.global === 'undefined') {
13
12
  window.global = window;
@@ -95,7 +94,7 @@ function getOptions(options) {
95
94
  * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
96
95
  * @property {boolean} [readOnly] - Set this form to readOnly.
97
96
  * @property {boolean} [noAlerts] - Disable the alerts dialog.
98
- * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
97
+ * @property {{[key: string]: string}} [enTranslation] - The translation file for this rendering.
99
98
  * @property {string} [template] - Custom logic for creation of elements.
100
99
  * @property {boolean} [noDefaults] - Exclude default values from the settings.
101
100
  * @property {any} [fileService] - The file service for this form.
@@ -342,7 +341,7 @@ export default class Webform extends NestedDataComponent {
342
341
  */
343
342
  addLanguage(code, lang, active = false) {
344
343
  if (this.i18next) {
345
- var translations = _.assign(fastCloneDeep(i18nDefaults.resources.en.translation), lang);
344
+ var translations = _.assign(fastCloneDeep(enTranslation), lang);
346
345
  this.i18next.addResourceBundle(code, 'translation', translations, true, true);
347
346
  if (active) {
348
347
  this.language = code;
@@ -659,7 +658,9 @@ export default class Webform extends NestedDataComponent {
659
658
  const rebuild = this.rebuild() || Promise.resolve();
660
659
  return rebuild.then(() => {
661
660
  this.emit('formLoad', form);
662
- this.triggerCaptcha();
661
+ if (!this.options.server) {
662
+ this.triggerCaptcha();
663
+ }
663
664
  // Make sure to trigger onChange after a render event occurs to speed up form rendering.
664
665
  setTimeout(() => {
665
666
  this.onChange(flags);
@@ -1158,11 +1159,8 @@ export default class Webform extends NestedDataComponent {
1158
1159
  };
1159
1160
  errors.forEach(({ message, context, fromServer, component }, index) => {
1160
1161
  const text = !component?.label || context?.hasLabel || fromServer
1161
- ? this.t('alertMessage', { message: this.t(message) })
1162
- : this.t('alertMessageWithLabel', {
1163
- label: this.t(component?.label),
1164
- message: this.t(message),
1165
- });
1162
+ ? this.t(message)
1163
+ : `${this.t(component?.label)}: ${this.t(message)}`;
1166
1164
  displayedErrors.push(createListItem(text, index));
1167
1165
  });
1168
1166
  }
@@ -1318,13 +1316,14 @@ export default class Webform extends NestedDataComponent {
1318
1316
  submission.metadata = submission.metadata || {};
1319
1317
  _.defaults(submission.metadata, {
1320
1318
  timezone: _.get(this, '_submission.metadata.timezone', currentTimezone()),
1321
- offset: parseInt(_.get(this, '_submission.metadata.offset', moment().utcOffset()), 10),
1319
+ offset: parseInt(_.get(this, '_submission.metadata.offset', dayjs().utcOffset()), 10),
1322
1320
  origin: document.location.origin,
1323
1321
  referrer: document.referrer,
1324
1322
  browserName: navigator.appName,
1325
1323
  userAgent: navigator.userAgent,
1326
1324
  pathName: window.location.pathname,
1327
1325
  onLine: navigator.onLine,
1326
+ language: this.language,
1328
1327
  });
1329
1328
  }
1330
1329
  submitForm(options = {}, local = false) {
@@ -77,7 +77,8 @@ export default class WebformBuilder extends Component {
77
77
  removeComponent(component: any, parent: any, original: any, componentInstance: any): boolean | undefined;
78
78
  replaceDoubleQuotes(data: any, fieldsToRemoveDoubleQuotes?: any[]): any;
79
79
  updateComponent(component: any, changed: any): void;
80
- findRepeatablePaths(): any[];
80
+ originalDefaultValue: any;
81
+ findComponentsWithRepeatablePaths(): any[];
81
82
  highlightInvalidComponents(): void;
82
83
  /**
83
84
  * Called when a new component is saved.
@@ -3,8 +3,7 @@ import Component from './components/_classes/component/Component';
3
3
  import tippy from 'tippy.js';
4
4
  import Components from './components/Components';
5
5
  import { Formio } from './Formio';
6
- import { fastCloneDeep, bootstrapVersion, getArrayFromComponentPath, getStringFromComponentPath } from './utils/utils';
7
- import { eachComponent, getComponent } from './utils/formUtils';
6
+ import { fastCloneDeep, bootstrapVersion, getArrayFromComponentPath, getStringFromComponentPath, eachComponent, getComponent, componentInfo } from './utils';
8
7
  import BuilderUtils from './utils/builder';
9
8
  import _ from 'lodash';
10
9
  import autoScroll from 'dom-autoscroller';
@@ -1054,6 +1053,16 @@ export default class WebformBuilder extends Component {
1054
1053
  'fields.month.required',
1055
1054
  'fields.year.required',
1056
1055
  ]));
1056
+ if (defaultValueComponent.component.components) {
1057
+ if (!this.originalDefaultValue) {
1058
+ this.originalDefaultValue = fastCloneDeep(defaultValueComponent.component);
1059
+ }
1060
+ eachComponent(defaultValueComponent.component.components, (comp => {
1061
+ if (comp.validate?.required) {
1062
+ comp.validate.required = false;
1063
+ }
1064
+ }));
1065
+ }
1057
1066
  const parentComponent = defaultValueComponent.parent;
1058
1067
  let tabIndex = -1;
1059
1068
  let index = -1;
@@ -1099,28 +1108,52 @@ export default class WebformBuilder extends Component {
1099
1108
  // Called when we update a component.
1100
1109
  this.emit('updateComponent', component);
1101
1110
  }
1102
- findRepeatablePaths() {
1103
- const repeatablePaths = [];
1111
+ findComponentsWithRepeatablePaths() {
1112
+ const repeatablePaths = {};
1104
1113
  const keys = new Map();
1105
1114
  eachComponent(this.form.components, (comp, path, components, parent, paths) => {
1106
- if (keys.has(paths.dataPath)) {
1107
- repeatablePaths.push(paths.dataPath);
1108
- }
1109
- else {
1110
- keys.set(paths.dataPath, true);
1115
+ const isRadioCheckbox = comp.type === 'checkbox' && comp.inputType === 'radio';
1116
+ const isLayout = componentInfo(comp).layout;
1117
+ if (!isLayout) {
1118
+ if (keys.has(paths.dataPath)) {
1119
+ const onlyRadioCheckboxes = repeatablePaths[paths.dataPath]?.onlyRadioCheckboxes === false ? false : isRadioCheckbox;
1120
+ repeatablePaths[paths.dataPath] = {
1121
+ comps: [...(repeatablePaths[paths.dataPath]?.comps || []), keys.get(paths.dataPath), comp],
1122
+ onlyRadioCheckboxes,
1123
+ };
1124
+ }
1125
+ else {
1126
+ keys.set(paths.dataPath, comp);
1127
+ }
1111
1128
  }
1112
1129
  }, true);
1113
- return repeatablePaths;
1130
+ const componentsWithRepeatablePaths = [];
1131
+ Object.keys(repeatablePaths).forEach((path) => {
1132
+ const { comps, onlyRadioCheckboxes } = repeatablePaths[path];
1133
+ if (!onlyRadioCheckboxes) {
1134
+ componentsWithRepeatablePaths.push(...comps);
1135
+ }
1136
+ });
1137
+ return componentsWithRepeatablePaths;
1114
1138
  }
1115
1139
  highlightInvalidComponents() {
1116
- const repeatablePaths = this.findRepeatablePaths();
1140
+ const repeatablePathsComps = this.findComponentsWithRepeatablePaths();
1117
1141
  let hasInvalidComponents = false;
1142
+ // Matches anything expect letters and '_' at the beginning of the key and anything except of letters, numbers,
1143
+ // '-', '.' and '_' in the rest of the key
1144
+ const badCharacters = /^[^A-Za-z_]+|[^A-Za-z0-9\-._]+/g;
1118
1145
  this.webform.everyComponent((comp) => {
1119
- const path = comp.path;
1120
- if (repeatablePaths.includes(path)) {
1146
+ if (repeatablePathsComps.includes(comp.component)) {
1121
1147
  comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
1122
1148
  hasInvalidComponents = true;
1123
1149
  }
1150
+ else if (comp.key.replace(badCharacters, '') === '') {
1151
+ comp.setCustomValidity(this.t('apiKeyNotValid', { key: comp.key }));
1152
+ hasInvalidComponents = true;
1153
+ }
1154
+ else {
1155
+ comp.setCustomValidity();
1156
+ }
1124
1157
  });
1125
1158
  this.emit('builderFormValidityChange', hasInvalidComponents);
1126
1159
  }
@@ -1145,6 +1178,9 @@ export default class WebformBuilder extends Component {
1145
1178
  if (index !== -1) {
1146
1179
  let submissionData = this.editForm.submission.data;
1147
1180
  submissionData = submissionData.componentJson || submissionData;
1181
+ if (submissionData.components && this.originalDefaultValue) {
1182
+ submissionData.components = this.originalDefaultValue.components;
1183
+ }
1148
1184
  const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1149
1185
  this.replaceDoubleQuotes(submissionData, fieldsToRemoveDoubleQuotes);
1150
1186
  this.hook('beforeSaveComponentSettings', submissionData);
@@ -1626,6 +1662,10 @@ export default class WebformBuilder extends Component {
1626
1662
  info.type);
1627
1663
  }
1628
1664
  hasEditTabs(type) {
1665
+ // If the component type does not exist then it has no edit tabs
1666
+ if (!Components.components[type === 'custom' ? 'unknown' : type]) {
1667
+ return false;
1668
+ }
1629
1669
  const editTabs = getComponent(Components.components[type === 'custom' ? 'unknown' : type].editForm().components, 'tabs', true).components;
1630
1670
  const hiddenEditTabs = _.filter(_.get(this.options, `editForm.${type}`, []), 'ignore');
1631
1671
  return _.intersectionBy(editTabs, hiddenEditTabs, 'key').length !== editTabs.length;
@@ -6,7 +6,6 @@ declare class Wizard extends Webform {
6
6
  originalComponents: any[];
7
7
  page: number;
8
8
  currentPanel: any;
9
- currentPanels: any[] | null;
10
9
  currentNextPage: number;
11
10
  _seenPages: number[];
12
11
  subWizards: any[];
@@ -17,7 +16,7 @@ declare class Wizard extends Webform {
17
16
  originalOptions: any;
18
17
  isLastPage(): any;
19
18
  getPages(args?: {}): any[];
20
- get hasExtraPages(): boolean;
19
+ get hasSubWizards(): boolean;
21
20
  get localData(): any;
22
21
  get wizardKey(): string;
23
22
  set wizard(form: object);
@@ -106,6 +105,7 @@ declare class Wizard extends Webform {
106
105
  onChange(flags: any, changed: any, modified: any, changes: any): void;
107
106
  checkValidity(data: any, dirty: any, row: any, currentPageOnly: any, childErrors?: any[]): any;
108
107
  focusOnComponent(key: any): void | Promise<void>;
108
+ triggerButtonCaptcha(page: any): void;
109
109
  }
110
110
  declare namespace Wizard {
111
111
  let setBaseUrl: any;
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, } from './utils/utils';
4
+ import { fastCloneDeep, checkCondition, firstNonNil, uniqueKey, eachComponent, } from './utils';
5
5
  export default class Wizard extends Webform {
6
6
  /**
7
7
  * Constructor for wizard-based forms.
@@ -29,7 +29,6 @@ export default class Wizard extends Webform {
29
29
  this.originalComponents = [];
30
30
  this.page = 0;
31
31
  this.currentPanel = null;
32
- this.currentPanels = null;
33
32
  this.currentNextPage = 0;
34
33
  this._seenPages = [0];
35
34
  this.subWizards = [];
@@ -48,12 +47,12 @@ export default class Wizard extends Webform {
48
47
  }
49
48
  getPages(args = {}) {
50
49
  const { all = false } = args;
51
- const pages = this.hasExtraPages ? this.components : this.pages;
50
+ const pages = this.hasSubWizards ? this.components : this.pages;
52
51
  const filteredPages = pages
53
52
  .filter(all ? _.identity : (p, index) => this._seenPages.includes(index));
54
53
  return filteredPages;
55
54
  }
56
- get hasExtraPages() {
55
+ get hasSubWizards() {
57
56
  return !_.isEmpty(this.subWizards);
58
57
  }
59
58
  get data() {
@@ -177,9 +176,9 @@ export default class Wizard extends Webform {
177
176
  }
178
177
  render() {
179
178
  const ctx = this.renderContext;
180
- if (this.component.key) {
181
- ctx.panels.map(panel => {
182
- if (panel.key === this.component.key) {
179
+ if (this.component.id) {
180
+ ctx.panels.forEach(panel => {
181
+ if (panel.id === this.component.id) {
183
182
  this.currentPanel = panel;
184
183
  ctx.wizardPageTooltip = this.getFormattedTooltip(panel.tooltip);
185
184
  }
@@ -580,7 +579,7 @@ export default class Wizard extends Webform {
580
579
  this.pageFieldLogic(num);
581
580
  this.getNextPage();
582
581
  let parentNum = num;
583
- if (this.hasExtraPages) {
582
+ if (this.hasSubWizards) {
584
583
  const pageFromPages = this.pages[num];
585
584
  const pageFromComponents = this.components[num];
586
585
  if (!pageFromComponents || pageFromPages?.id !== pageFromComponents.id) {
@@ -660,6 +659,7 @@ export default class Wizard extends Webform {
660
659
  beforeSubmit() {
661
660
  const pages = this.getPages({ all: true });
662
661
  return Promise.all(pages.map((page) => {
662
+ this.triggerButtonCaptcha(page);
663
663
  page.options.beforeSubmit = true;
664
664
  return page.beforeSubmit();
665
665
  }));
@@ -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 });
@@ -865,23 +868,18 @@ export default class Wizard extends Webform {
865
868
  this.showErrors(errors, true, true);
866
869
  }
867
870
  // If the pages change, need to redraw the header.
868
- let currentPanels;
869
- let panels;
871
+ const currentPanels = this.pages;
872
+ // calling this.establishPages() updates/mutates this.pages to be the current pages
873
+ this.establishPages();
874
+ const newPanels = this.pages;
870
875
  const currentNextPage = this.currentNextPage;
871
- if (this.hasExtraPages) {
872
- currentPanels = this.pages.map(page => page.component.key);
873
- this.establishPages();
874
- panels = this.pages.map(page => page.component.key);
875
- }
876
- else {
877
- currentPanels = this.currentPanels || this.pages.map(page => page.component.key);
878
- panels = this.establishPages().map(panel => panel.key);
879
- this.currentPanels = panels;
880
- if (this.currentPanel?.key && this.currentPanels?.length) {
881
- this.setPage(this.currentPanels.findIndex(panel => panel === this.currentPanel.key));
882
- }
876
+ const panelsUpdated = !_.isEqual(newPanels, currentPanels);
877
+ if (this.currentPanel?.id && this.pages.length && (!this.hasSubWizards || (this.hasSubWizards && panelsUpdated))) {
878
+ const newIndex = this.pages.findIndex(page => page.id === this.currentPanel.id);
879
+ if (newIndex !== -1)
880
+ this.setPage(newIndex);
883
881
  }
884
- if (!_.isEqual(panels, currentPanels) || (flags && flags.fromSubmission)) {
882
+ if (panelsUpdated || (flags && flags.fromSubmission)) {
885
883
  this.redrawHeader();
886
884
  }
887
885
  // If the next page changes, then make sure to redraw navigation.
@@ -930,6 +928,22 @@ export default class Wizard extends Webform {
930
928
  }
931
929
  return super.focusOnComponent(key);
932
930
  }
931
+ triggerButtonCaptcha(page) {
932
+ if (!page.components) {
933
+ return;
934
+ }
935
+ let captchaComponent;
936
+ page.eachComponent((component) => {
937
+ if (/^(re)?captcha$/.test(component.component.type) &&
938
+ component.component.eventType === 'buttonClick' &&
939
+ component.component.buttonKey === 'submit') {
940
+ captchaComponent = component;
941
+ }
942
+ });
943
+ if (captchaComponent) {
944
+ captchaComponent.verify(`submitClick`);
945
+ }
946
+ }
933
947
  }
934
948
  Wizard.setBaseUrl = Formio.setBaseUrl;
935
949
  Wizard.setApiUrl = Formio.setApiUrl;
@@ -2,7 +2,7 @@ import WebformBuilder from './WebformBuilder';
2
2
  import Webform from './Webform';
3
3
  import BuilderUtils from './utils/builder';
4
4
  import _ from 'lodash';
5
- import { fastCloneDeep } from './utils/utils';
5
+ import { fastCloneDeep } from './utils';
6
6
  export default class WizardBuilder extends WebformBuilder {
7
7
  constructor() {
8
8
  let element, options;
@@ -129,16 +129,6 @@ 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;
142
132
  triggerChange: (...args: any[]) => any;
143
133
  /**
144
134
  * Used to trigger a redraw event within this component.
@@ -173,7 +163,17 @@ declare class Component extends Element {
173
163
  */
174
164
  info: any;
175
165
  get componentsMap(): object;
166
+ /**
167
+ * Returns if the parent should conditionally clear.
168
+ * @returns {boolean} - If the parent should conditionally clear.
169
+ */
170
+ parentShouldConditionallyClear(): boolean;
176
171
  parentConditionallyHidden(): boolean;
172
+ /**
173
+ * Returns true if any of the parents default their component "hidden" property to true.
174
+ * @returns {boolean} - If any parent defaults the hidden property to true.
175
+ */
176
+ anyParentDefaultsHidden(): boolean;
177
177
  set data(value: any);
178
178
  get data(): any;
179
179
  mergeSchema(component?: {}): any;
@@ -237,7 +237,23 @@ declare class Component extends Element {
237
237
  get visible(): boolean;
238
238
  get logicallyHidden(): any;
239
239
  _logicallyHidden: any;
240
- conditionallyHidden(skipParent?: boolean): any;
240
+ /**
241
+ * Determines if the component should clear its value when the root form is pristine.
242
+ * @returns {boolean} - If the component should clear its value when the root form is pristine.
243
+ */
244
+ shouldConditionallyClearOnPristine(): boolean;
245
+ /**
246
+ * Returns if the component should clear its value when conditionally hidden.
247
+ * @returns {boolean} - If the component should clear its value when conditionally hidden.
248
+ */
249
+ shouldConditionallyClear(): boolean;
250
+ _conditionallyClear: boolean | undefined;
251
+ /**
252
+ * Returns if the component is conditionally hidden.
253
+ * @returns {boolean} - If the component is conditionally hidden.
254
+ */
255
+ conditionallyHidden(): boolean;
256
+ _conditionallyHidden: boolean | undefined;
241
257
  set currentForm(instance: any);
242
258
  get currentForm(): any;
243
259
  _currentForm: any;
@@ -896,7 +912,20 @@ declare class Component extends Element {
896
912
  */
897
913
  deleteValue(): void;
898
914
  getCustomDefaultValue(defaultValue: any): any;
899
- get shouldAddDefaultValue(): any;
915
+ /**
916
+ * Returns if a component has a default value set.
917
+ * @returns {boolean} - TRUE if a default value is set.
918
+ */
919
+ get hasDefaultValue(): boolean;
920
+ /**
921
+ * Determine if we should add a default value for this component.
922
+ * @returns {boolean} - TRUE if a default value should be set
923
+ */
924
+ get shouldAddDefaultValue(): boolean;
925
+ /**
926
+ * Get the default value of this component.
927
+ * @returns {*} - The default value for this component.
928
+ */
900
929
  get defaultValue(): any;
901
930
  /**
902
931
  * Get the input value of this component.
@@ -1006,9 +1035,10 @@ declare class Component extends Element {
1006
1035
  * @param {boolean} dirty - If the component is dirty.
1007
1036
  * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.
1008
1037
  * @param {*} row - Contextual row data for this component.
1038
+ * @param {*} options - Additional options for validation.
1009
1039
  * @returns {string} - The message to show when the component is invalid.
1010
1040
  */
1011
- invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any): string;
1041
+ invalidMessage(data: any, dirty: boolean, ignoreCondition: boolean, row: any, options?: any): string;
1012
1042
  /**
1013
1043
  * Returns if the component is valid or not.
1014
1044
  * @param {*} data - The data to check if the component is valid.
@@ -1070,6 +1100,7 @@ declare class Component extends Element {
1070
1100
  * @returns {void|boolean} - TRUE if no check should be performed on the component.
1071
1101
  */
1072
1102
  checkData(data?: any, flags?: any, row?: any): void | boolean;
1103
+ checkingData: boolean | undefined;
1073
1104
  checkModal(errors?: any[], dirty?: boolean): void;
1074
1105
  get validationValue(): any;
1075
1106
  isEmpty(value?: any): any;