@formio/js 5.1.0-dev.6109.79f22ad → 5.1.0-dev.6112.86987a5

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 (168) hide show
  1. package/README.md +7 -0
  2. package/dist/formio.builder.css +1 -0
  3. package/dist/formio.builder.min.css +1 -1
  4. package/dist/formio.form.css +1 -0
  5. package/dist/formio.form.js +116 -149
  6. package/dist/formio.form.min.css +1 -1
  7. package/dist/formio.form.min.js +1 -1
  8. package/dist/formio.full.css +1 -0
  9. package/dist/formio.full.js +123 -156
  10. package/dist/formio.full.min.css +1 -1
  11. package/dist/formio.full.min.js +1 -1
  12. package/dist/formio.js +65 -54
  13. package/dist/formio.min.js +1 -1
  14. package/dist/formio.utils.js +76 -76
  15. package/dist/formio.utils.min.js +1 -1
  16. package/lib/cjs/Element.d.ts +2 -1
  17. package/lib/cjs/Element.js +18 -39
  18. package/lib/cjs/EventEmitter.js +2 -25
  19. package/lib/cjs/Form.js +2 -25
  20. package/lib/cjs/PDF.js +1 -1
  21. package/lib/cjs/PDFBuilder.d.ts +1 -0
  22. package/lib/cjs/PDFBuilder.js +10 -11
  23. package/lib/cjs/Webform.d.ts +2 -2
  24. package/lib/cjs/Webform.js +9 -9
  25. package/lib/cjs/WebformBuilder.d.ts +1 -1
  26. package/lib/cjs/WebformBuilder.js +45 -21
  27. package/lib/cjs/Wizard.d.ts +1 -2
  28. package/lib/cjs/Wizard.js +18 -24
  29. package/lib/cjs/WizardBuilder.js +1 -1
  30. package/lib/cjs/components/_classes/component/Component.d.ts +0 -1
  31. package/lib/cjs/components/_classes/component/Component.js +57 -62
  32. package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  33. package/lib/cjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  34. package/lib/cjs/components/_classes/componentModal/ComponentModal.js +1 -1
  35. package/lib/cjs/components/_classes/input/Input.d.ts +1 -1
  36. package/lib/cjs/components/_classes/input/Input.js +3 -3
  37. package/lib/cjs/components/_classes/list/ListComponent.js +1 -1
  38. package/lib/cjs/components/_classes/nested/NestedComponent.js +7 -7
  39. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  40. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
  41. package/lib/cjs/components/address/Address.js +1 -1
  42. package/lib/cjs/components/alert/Alert.js +1 -1
  43. package/lib/cjs/components/button/Button.js +1 -1
  44. package/lib/cjs/components/checkbox/Checkbox.js +1 -1
  45. package/lib/cjs/components/container/Container.js +1 -1
  46. package/lib/cjs/components/currency/Currency.js +1 -1
  47. package/lib/cjs/components/datagrid/DataGrid.js +1 -1
  48. package/lib/cjs/components/datamap/DataMap.js +7 -2
  49. package/lib/cjs/components/datetime/DateTime.d.ts +1 -1
  50. package/lib/cjs/components/datetime/DateTime.js +15 -13
  51. package/lib/cjs/components/day/Day.js +2 -2
  52. package/lib/cjs/components/editgrid/EditGrid.js +1 -1
  53. package/lib/cjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  54. package/lib/cjs/components/fieldset/Fieldset.js +1 -0
  55. package/lib/cjs/components/file/File.js +1 -1
  56. package/lib/cjs/components/form/Form.js +14 -2
  57. package/lib/cjs/components/form/editForm/Form.edit.form.js +4 -3
  58. package/lib/cjs/components/number/Number.js +1 -1
  59. package/lib/cjs/components/panel/Panel.js +1 -1
  60. package/lib/cjs/components/radio/Radio.d.ts +8 -0
  61. package/lib/cjs/components/radio/Radio.js +16 -6
  62. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  63. package/lib/cjs/components/select/Select.js +7 -3
  64. package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -1
  65. package/lib/cjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  66. package/lib/cjs/components/selectboxes/SelectBoxes.js +1 -1
  67. package/lib/cjs/components/signature/Signature.js +1 -1
  68. package/lib/cjs/components/survey/Survey.js +1 -1
  69. package/lib/cjs/components/tags/Tags.js +1 -1
  70. package/lib/cjs/components/textarea/TextArea.js +9 -4
  71. package/lib/cjs/components/textfield/TextField.js +13 -31
  72. package/lib/cjs/components/time/Time.js +1 -1
  73. package/lib/cjs/formio.form.js +5 -5
  74. package/lib/cjs/providers/storage/uploadAdapter.js +1 -1
  75. package/lib/cjs/translations/en.d.ts +1 -232
  76. package/lib/cjs/translations/en.js +4 -2
  77. package/lib/cjs/utils/Evaluator.d.ts +20 -6
  78. package/lib/cjs/utils/Evaluator.js +38 -15
  79. package/lib/cjs/utils/builder.js +5 -5
  80. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +3 -3
  81. package/lib/cjs/utils/formUtils.d.ts +2 -2
  82. package/lib/cjs/utils/index.d.ts +169 -2
  83. package/lib/cjs/utils/index.js +22 -2
  84. package/lib/cjs/utils/utils.d.ts +22 -37
  85. package/lib/cjs/utils/utils.js +64 -135
  86. package/lib/cjs/widgets/CalendarWidget.d.ts +1 -8
  87. package/lib/cjs/widgets/CalendarWidget.js +17 -43
  88. package/lib/mjs/Element.d.ts +2 -1
  89. package/lib/mjs/Element.js +11 -9
  90. package/lib/mjs/EventEmitter.js +2 -2
  91. package/lib/mjs/Form.js +1 -1
  92. package/lib/mjs/PDF.js +1 -1
  93. package/lib/mjs/PDFBuilder.d.ts +1 -0
  94. package/lib/mjs/PDFBuilder.js +9 -10
  95. package/lib/mjs/Webform.d.ts +2 -2
  96. package/lib/mjs/Webform.js +7 -7
  97. package/lib/mjs/WebformBuilder.d.ts +1 -1
  98. package/lib/mjs/WebformBuilder.js +36 -13
  99. package/lib/mjs/Wizard.d.ts +1 -2
  100. package/lib/mjs/Wizard.js +17 -23
  101. package/lib/mjs/WizardBuilder.js +1 -1
  102. package/lib/mjs/components/_classes/component/Component.d.ts +0 -1
  103. package/lib/mjs/components/_classes/component/Component.js +30 -12
  104. package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  105. package/lib/mjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  106. package/lib/mjs/components/_classes/componentModal/ComponentModal.js +1 -1
  107. package/lib/mjs/components/_classes/input/Input.d.ts +1 -1
  108. package/lib/mjs/components/_classes/input/Input.js +3 -3
  109. package/lib/mjs/components/_classes/list/ListComponent.js +1 -1
  110. package/lib/mjs/components/_classes/nested/NestedComponent.js +7 -7
  111. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  112. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
  113. package/lib/mjs/components/address/Address.js +1 -1
  114. package/lib/mjs/components/alert/Alert.js +1 -1
  115. package/lib/mjs/components/button/Button.js +1 -1
  116. package/lib/mjs/components/checkbox/Checkbox.js +1 -1
  117. package/lib/mjs/components/container/Container.js +1 -1
  118. package/lib/mjs/components/currency/Currency.js +1 -1
  119. package/lib/mjs/components/datagrid/DataGrid.js +1 -1
  120. package/lib/mjs/components/datamap/DataMap.js +7 -2
  121. package/lib/mjs/components/datetime/DateTime.d.ts +1 -1
  122. package/lib/mjs/components/datetime/DateTime.js +15 -13
  123. package/lib/mjs/components/day/Day.js +2 -2
  124. package/lib/mjs/components/editgrid/EditGrid.js +1 -1
  125. package/lib/mjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  126. package/lib/mjs/components/fieldset/Fieldset.js +1 -0
  127. package/lib/mjs/components/file/File.js +1 -1
  128. package/lib/mjs/components/form/Form.js +13 -2
  129. package/lib/mjs/components/form/editForm/Form.edit.form.js +3 -2
  130. package/lib/mjs/components/number/Number.js +1 -1
  131. package/lib/mjs/components/panel/Panel.js +1 -1
  132. package/lib/mjs/components/radio/Radio.d.ts +8 -0
  133. package/lib/mjs/components/radio/Radio.js +16 -6
  134. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  135. package/lib/mjs/components/select/Select.js +7 -3
  136. package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -1
  137. package/lib/mjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  138. package/lib/mjs/components/selectboxes/SelectBoxes.js +1 -1
  139. package/lib/mjs/components/signature/Signature.js +1 -1
  140. package/lib/mjs/components/survey/Survey.js +1 -1
  141. package/lib/mjs/components/tags/Tags.js +1 -1
  142. package/lib/mjs/components/textarea/TextArea.js +9 -4
  143. package/lib/mjs/components/textfield/TextField.js +7 -2
  144. package/lib/mjs/components/time/Time.js +1 -1
  145. package/lib/mjs/formio.form.js +3 -3
  146. package/lib/mjs/providers/storage/uploadAdapter.js +1 -1
  147. package/lib/mjs/translations/en.d.ts +1 -232
  148. package/lib/mjs/translations/en.js +8 -47
  149. package/lib/mjs/utils/Evaluator.d.ts +20 -6
  150. package/lib/mjs/utils/Evaluator.js +31 -13
  151. package/lib/mjs/utils/builder.js +1 -1
  152. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +1 -1
  153. package/lib/mjs/utils/formUtils.d.ts +2 -2
  154. package/lib/mjs/utils/index.d.ts +169 -2
  155. package/lib/mjs/utils/index.js +18 -1
  156. package/lib/mjs/utils/utils.d.ts +22 -37
  157. package/lib/mjs/utils/utils.js +57 -109
  158. package/lib/mjs/widgets/CalendarWidget.d.ts +1 -8
  159. package/lib/mjs/widgets/CalendarWidget.js +17 -43
  160. package/package.json +5 -3
  161. package/lib/cjs/i18n.d.ts +0 -13
  162. package/lib/cjs/i18n.js +0 -19
  163. package/lib/cjs/utils/i18n.d.ts +0 -19
  164. package/lib/cjs/utils/i18n.js +0 -120
  165. package/lib/mjs/i18n.d.ts +0 -13
  166. package/lib/mjs/i18n.js +0 -14
  167. package/lib/mjs/utils/i18n.d.ts +0 -19
  168. package/lib/mjs/utils/i18n.js +0 -112
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const Formio_1 = require("../Formio");
7
- const InputWidget_1 = __importDefault(require("./InputWidget"));
8
- const utils_1 = require("../utils/utils");
9
6
  const moment_1 = __importDefault(require("moment"));
10
7
  const lodash_1 = __importDefault(require("lodash"));
8
+ const Formio_1 = require("../Formio");
9
+ const InputWidget_1 = __importDefault(require("./InputWidget"));
10
+ const utils_1 = require("../utils");
11
11
  const DEFAULT_FORMAT = 'yyyy-MM-dd hh:mm a';
12
12
  const ISO_8601_FORMAT = 'yyyy-MM-ddTHH:mm:ssZ';
13
13
  const isIEBrowser = (0, utils_1.getBrowserInfo)().ie;
@@ -51,29 +51,6 @@ class CalendarWidget extends InputWidget_1.default {
51
51
  else if (this.settings.time_24hr) {
52
52
  this.settings.format = this.settings.format.replace(/hh:mm a$/g, 'HH:mm');
53
53
  }
54
- this.zoneLoading = false;
55
- this.timezonesUrl = `${Formio_1.Formio.cdn['moment-timezone']}/data/packed/latest.json`;
56
- }
57
- /**
58
- * Load the timezones.
59
- * @returns {boolean} TRUE if the zones are loading, FALSE otherwise.
60
- */
61
- loadZones() {
62
- const timezone = this.timezone;
63
- if (this.zoneLoading) {
64
- return true;
65
- }
66
- if (!(0, utils_1.zonesLoaded)() && (0, utils_1.shouldLoadZones)(timezone)) {
67
- this.zoneLoading = true;
68
- (0, utils_1.loadZones)(this.timezonesUrl, timezone).then(() => {
69
- this.zoneLoading = false;
70
- this.emit('redraw');
71
- });
72
- // Return zones are loading.
73
- return true;
74
- }
75
- // Zones are already loaded.
76
- return false;
77
54
  }
78
55
  attach(input) {
79
56
  var _a;
@@ -85,7 +62,7 @@ class CalendarWidget extends InputWidget_1.default {
85
62
  };
86
63
  this.closedOn = 0;
87
64
  this.valueFormat = (this.settings.saveAs === 'date') ? ISO_8601_FORMAT : this.settings.dateFormat || ISO_8601_FORMAT;
88
- this.valueMomentFormat = (0, utils_1.convertFormatToMoment)(this.valueFormat);
65
+ this.valueMomentFormat = (0, utils_1.convertFormatToDayjs)(this.valueFormat);
89
66
  const isReadOnly = this.settings.readOnly;
90
67
  this.settings.minDate = isReadOnly ? null : (0, utils_1.getDateSetting)(this.settings.minDate);
91
68
  this.settings.maxDate = isReadOnly ? null : (0, utils_1.getDateSetting)(this.settings.maxDate);
@@ -249,9 +226,9 @@ class CalendarWidget extends InputWidget_1.default {
249
226
  */
250
227
  getDateValue(date, format, useTimezone) {
251
228
  if (useTimezone) {
252
- return (0, utils_1.momentDate)(date, this.valueFormat, this.timezone).format((0, utils_1.convertFormatToMoment)(format));
229
+ return (0, utils_1.dayjsDate)(date, this.valueFormat, this.timezone).format((0, utils_1.convertFormatToDayjs)(format));
253
230
  }
254
- return (0, moment_1.default)(date).format((0, utils_1.convertFormatToMoment)(format));
231
+ return (0, moment_1.default)(date).format((0, utils_1.convertFormatToDayjs)(format));
255
232
  }
256
233
  /**
257
234
  * Return the value of the selected date.
@@ -283,18 +260,15 @@ class CalendarWidget extends InputWidget_1.default {
283
260
  setValue(value) {
284
261
  const saveAsText = (this.settings.saveAs === 'text');
285
262
  if (!this.calendar) {
286
- value = value ? (0, utils_1.formatDate)(this.timezonesUrl, value, (0, utils_1.convertFormatToMoment)(this.settings.format), this.timezone, (0, utils_1.convertFormatToMoment)(this.valueMomentFormat)) : value;
263
+ value = value ? (0, utils_1.formatDate)(value, (0, utils_1.convertFormatToDayjs)(this.settings.format), this.timezone, (0, utils_1.convertFormatToDayjs)(this.valueMomentFormat)) : value;
287
264
  return super.setValue(value);
288
265
  }
289
266
  // If the component is a textfield that does not have timezone information included in the string value then skip
290
267
  // the timezone offset
291
- if (this.component.type === 'textfield' && !(0, utils_1.hasEncodedTimezone)(value)) {
292
- this.settings.skipOffset = true;
293
- }
294
- const zonesLoading = this.loadZones();
268
+ this.settings.skipOffset = this.component.type === 'textfield' && !(0, utils_1.hasEncodedTimezone)(value);
295
269
  if (value) {
296
- if (!saveAsText && this.settings.readOnly && !zonesLoading) {
297
- this.calendar.setDate((0, utils_1.momentDate)(value, this.valueFormat, this.timezone).format(), false);
270
+ if (!saveAsText && this.settings.readOnly) {
271
+ this.calendar.setDate((0, utils_1.dayjsDate)(value, this.valueFormat, this.timezone).format(), false);
298
272
  }
299
273
  else if (this.isValueISO8601(value)) {
300
274
  this.calendar.setDate(value, false);
@@ -307,13 +281,13 @@ class CalendarWidget extends InputWidget_1.default {
307
281
  this.calendar.clear(false);
308
282
  }
309
283
  }
310
- getValueAsString(value, format) {
284
+ getValueAsString(value, format = '') {
311
285
  const inputFormat = format || this.dateFormat;
312
286
  const valueFormat = this.calendar ? this.valueFormat : this.settings.dateFormat;
313
287
  if (this.settings.saveAs === 'text' && this.componentInstance.parent && !this.settings.readOnly) {
314
- return (0, moment_1.default)(value, (0, utils_1.convertFormatToMoment)(valueFormat)).format((0, utils_1.convertFormatToMoment)(valueFormat));
288
+ return (0, moment_1.default)(value, (0, utils_1.convertFormatToDayjs)(valueFormat)).format((0, utils_1.convertFormatToDayjs)(valueFormat));
315
289
  }
316
- return (0, utils_1.formatDate)(this.timezonesUrl, value, inputFormat, this.timezone, (0, utils_1.convertFormatToMoment)(valueFormat));
290
+ return (0, utils_1.formatDate)(value, inputFormat, this.timezone, (0, utils_1.convertFormatToDayjs)(valueFormat));
317
291
  }
318
292
  setErrorClasses(hasErrors) {
319
293
  if (!this.input) {
@@ -406,7 +380,7 @@ class CalendarWidget extends InputWidget_1.default {
406
380
  const relatedTarget = event.relatedTarget ? event.relatedTarget : activeElement;
407
381
  if (!(isIEBrowser && !relatedTarget) && !this.isCalendarElement(relatedTarget)) {
408
382
  const inputValue = this.calendar.input.value;
409
- const dateValue = inputValue ? (0, moment_1.default)(this.calendar.input.value, (0, utils_1.convertFormatToMoment)(this.valueFormat)).toDate() : inputValue;
383
+ const dateValue = inputValue ? (0, moment_1.default)(this.calendar.input.value, (0, utils_1.convertFormatToDayjs)(this.valueFormat)).toDate() : inputValue;
410
384
  this.calendar.setDate(dateValue, true, this.settings.altFormat);
411
385
  }
412
386
  else if (!this.calendar.input.value && this.calendar.config.noCalendar) {
@@ -458,14 +432,14 @@ class CalendarWidget extends InputWidget_1.default {
458
432
  return (date, format) => {
459
433
  // Only format this if this is the altFormat and the form is readOnly.
460
434
  if (this.settings.readOnly && (format === this.settings.altFormat)) {
461
- if (!this.settings.enableTime || this.loadZones() || this.settings.skipOffset) {
435
+ if (!this.settings.enableTime || this.settings.skipOffset) {
462
436
  return Flatpickr.formatDate(date, format);
463
437
  }
464
438
  const currentValue = new Date(this.getValue());
465
439
  if (currentValue.toString() === date.toString()) {
466
- return (0, utils_1.formatOffset)(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), new Date(this.componentValue), format, this.timezone);
440
+ return (0, utils_1.formatOffset)(Flatpickr.formatDate.bind(Flatpickr), new Date(this.componentValue), format, this.timezone);
467
441
  }
468
- return (0, utils_1.formatOffset)(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), date, format, this.timezone);
442
+ return (0, utils_1.formatOffset)(Flatpickr.formatDate.bind(Flatpickr), date, format, this.timezone);
469
443
  }
470
444
  return Flatpickr.formatDate(date, format);
471
445
  };
@@ -170,10 +170,11 @@ export default class Element {
170
170
  /**
171
171
  * Translate a text using the i18n system.
172
172
  * @param {string|Array<string>} text - The i18n identifier.
173
+ * @param {any} data - contextual data object containing data, component, row, etc.
173
174
  * @param {...any} args - The arguments to pass to the i18n translation.
174
175
  * @returns {string} - The translated text.
175
176
  */
176
- t(text: string | Array<string>, ...args: any[]): string;
177
+ t(text: string | Array<string>, data: any, ...args: any[]): string;
177
178
  /**
178
179
  * Alias to create a text node.
179
180
  * @param {string} text - The text to create.
@@ -1,10 +1,11 @@
1
- import EventEmitter from './EventEmitter';
2
- import { Formio } from './Formio';
3
- import * as FormioUtils from './utils/utils';
4
- import { I18n } from './utils/i18n';
5
1
  import _ from 'lodash';
6
2
  import moment from 'moment';
7
3
  import maskInput from '@formio/vanilla-text-mask';
4
+ import EventEmitter from './EventEmitter';
5
+ import { Formio } from './Formio';
6
+ import FormioUtils from './utils';
7
+ import { I18n } from '@formio/core';
8
+ import enTranslation from './translations/en';
8
9
  /**
9
10
  * The root component for all elements within the Form.io renderer.
10
11
  */
@@ -38,7 +39,7 @@ export default class Element {
38
39
  if (this.options?.language) {
39
40
  this.options.i18n.language = this.options.language;
40
41
  }
41
- this.options.i18next = this.i18next = this.options.i18next || I18n.init(this.options.i18n);
42
+ this.options.i18next = this.i18next = this.options.i18next || I18n.init({ en: enTranslation, ...this.options.i18n });
42
43
  /**
43
44
  * An instance of the EventEmitter class to handle the emitting and registration of events.
44
45
  * @type {EventEmitter}
@@ -385,11 +386,12 @@ export default class Element {
385
386
  /**
386
387
  * Translate a text using the i18n system.
387
388
  * @param {string|Array<string>} text - The i18n identifier.
389
+ * @param {any} data - contextual data object containing data, component, row, etc.
388
390
  * @param {...any} args - The arguments to pass to the i18n translation.
389
391
  * @returns {string} - The translated text.
390
392
  */
391
- t(text, ...args) {
392
- return this.i18next ? this.i18next.t(text, ...args) : text;
393
+ t(text, data, ...args) {
394
+ return this.i18next ? this.i18next.t(text, data, ...args) : text;
393
395
  }
394
396
  /**
395
397
  * Alias to create a text node.
@@ -523,9 +525,9 @@ export default class Element {
523
525
  if (this.component.filter === string && !this.options.building) {
524
526
  const evalContext = this.evalContext(data);
525
527
  evalContext.data = _.mapValues(evalContext.data, (val) => _.isString(val) ? encodeURIComponent(val) : val);
526
- return FormioUtils.interpolate(string, evalContext, options);
528
+ return FormioUtils.Evaluator.interpolate(string, evalContext, options);
527
529
  }
528
- return FormioUtils.interpolate(string, this.evalContext(data), options);
530
+ return FormioUtils.Evaluator.interpolate(string, this.evalContext(data), options);
529
531
  }
530
532
  /**
531
533
  * Performs an evaluation using the evaluation context of this component.
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter as EventEmitter3 } from 'eventemitter3';
2
- import * as utils from './utils/utils';
2
+ import { observeOverload } from './utils';
3
3
  export default class EventEmitter extends EventEmitter3 {
4
4
  constructor(conf = {}) {
5
5
  const { loadLimit = 1000, eventsSafeInterval = 300 } = conf;
@@ -7,7 +7,7 @@ export default class EventEmitter extends EventEmitter3 {
7
7
  const overloadHandler = () => {
8
8
  console.warn(`There were more than ${loadLimit} events emitted in ${eventsSafeInterval} ms. It might be caused by events' infinite loop`, this.id);
9
9
  };
10
- const dispatch = utils.observeOverload(overloadHandler, {
10
+ const dispatch = observeOverload(overloadHandler, {
11
11
  limit: loadLimit,
12
12
  delay: eventsSafeInterval
13
13
  });
package/lib/mjs/Form.js CHANGED
@@ -2,7 +2,7 @@ import Element from './Element';
2
2
  import { Formio } from './Formio';
3
3
  import Displays from './displays';
4
4
  import templates from './templates';
5
- import * as FormioUtils from './utils/utils';
5
+ import FormioUtils from './utils';
6
6
  export default class Form extends Element {
7
7
  /**
8
8
  * Represents a JSON value.
package/lib/mjs/PDF.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Formio } from './Formio';
2
2
  import Webform from './Webform';
3
- import { fastCloneDeep, eachComponent } from './utils/utils';
3
+ import { fastCloneDeep, eachComponent } from './utils';
4
4
  export default class PDF extends Webform {
5
5
  constructor(element, options) {
6
6
  options.display = 'pdf';
@@ -51,5 +51,6 @@ export default class PDFBuilder extends WebformBuilder {
51
51
  onDropzoneDrop(e: any): boolean;
52
52
  dropEvent: any;
53
53
  onDragEnd(e: any): void;
54
+ repeatablePathsComps: any[] | undefined;
54
55
  }
55
56
  import WebformBuilder from './WebformBuilder';
@@ -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;
@@ -1317,13 +1316,14 @@ export default class Webform extends NestedDataComponent {
1317
1316
  submission.metadata = submission.metadata || {};
1318
1317
  _.defaults(submission.metadata, {
1319
1318
  timezone: _.get(this, '_submission.metadata.timezone', currentTimezone()),
1320
- offset: parseInt(_.get(this, '_submission.metadata.offset', moment().utcOffset()), 10),
1319
+ offset: parseInt(_.get(this, '_submission.metadata.offset', dayjs().utcOffset()), 10),
1321
1320
  origin: document.location.origin,
1322
1321
  referrer: document.referrer,
1323
1322
  browserName: navigator.appName,
1324
1323
  userAgent: navigator.userAgent,
1325
1324
  pathName: window.location.pathname,
1326
1325
  onLine: navigator.onLine,
1326
+ language: this.language,
1327
1327
  });
1328
1328
  }
1329
1329
  submitForm(options = {}, local = false) {
@@ -78,7 +78,7 @@ export default class WebformBuilder extends Component {
78
78
  replaceDoubleQuotes(data: any, fieldsToRemoveDoubleQuotes?: any[]): any;
79
79
  updateComponent(component: any, changed: any): void;
80
80
  originalDefaultValue: any;
81
- findRepeatablePaths(): any[];
81
+ findComponentsWithRepeatablePaths(): any[];
82
82
  highlightInvalidComponents(): void;
83
83
  /**
84
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';
@@ -1109,28 +1108,52 @@ export default class WebformBuilder extends Component {
1109
1108
  // Called when we update a component.
1110
1109
  this.emit('updateComponent', component);
1111
1110
  }
1112
- findRepeatablePaths() {
1113
- const repeatablePaths = [];
1111
+ findComponentsWithRepeatablePaths() {
1112
+ const repeatablePaths = {};
1114
1113
  const keys = new Map();
1115
1114
  eachComponent(this.form.components, (comp, path, components, parent, paths) => {
1116
- if (keys.has(paths.dataPath)) {
1117
- repeatablePaths.push(paths.dataPath);
1118
- }
1119
- else {
1120
- 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
+ }
1121
1128
  }
1122
1129
  }, true);
1123
- 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;
1124
1138
  }
1125
1139
  highlightInvalidComponents() {
1126
- const repeatablePaths = this.findRepeatablePaths();
1140
+ const repeatablePathsComps = this.findComponentsWithRepeatablePaths();
1127
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;
1128
1145
  this.webform.everyComponent((comp) => {
1129
- const path = comp.path;
1130
- if (repeatablePaths.includes(path)) {
1146
+ if (repeatablePathsComps.includes(comp.component)) {
1131
1147
  comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
1132
1148
  hasInvalidComponents = true;
1133
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
+ }
1134
1157
  });
1135
1158
  this.emit('builderFormValidityChange', hasInvalidComponents);
1136
1159
  }
@@ -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);
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) {
@@ -869,23 +868,18 @@ export default class Wizard extends Webform {
869
868
  this.showErrors(errors, true, true);
870
869
  }
871
870
  // If the pages change, need to redraw the header.
872
- let currentPanels;
873
- 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;
874
875
  const currentNextPage = this.currentNextPage;
875
- if (this.hasExtraPages) {
876
- currentPanels = this.pages.map(page => page.component.key);
877
- this.establishPages();
878
- panels = this.pages.map(page => page.component.key);
879
- }
880
- else {
881
- currentPanels = this.currentPanels || this.pages.map(page => page.component.key);
882
- panels = this.establishPages().map(panel => panel.key);
883
- this.currentPanels = panels;
884
- if (this.currentPanel?.key && this.currentPanels?.length) {
885
- this.setPage(this.currentPanels.findIndex(panel => panel === this.currentPanel.key));
886
- }
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);
887
881
  }
888
- if (!_.isEqual(panels, currentPanels) || (flags && flags.fromSubmission)) {
882
+ if (panelsUpdated || (flags && flags.fromSubmission)) {
889
883
  this.redrawHeader();
890
884
  }
891
885
  // If the next page changes, then make sure to redraw navigation.
@@ -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;
@@ -165,7 +165,6 @@ declare class Component extends Element {
165
165
  get componentsMap(): object;
166
166
  /**
167
167
  * Returns if the parent should conditionally clear.
168
- *
169
168
  * @returns {boolean} - If the parent should conditionally clear.
170
169
  */
171
170
  parentShouldConditionallyClear(): boolean;