@formio/js 5.1.0-dev.5969.9a6e3f5 → 5.1.0-dev.5972.f3a71a8

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 (77) hide show
  1. package/dist/formio.form.js +74 -52
  2. package/dist/formio.form.min.js +1 -1
  3. package/dist/formio.full.js +77 -55
  4. package/dist/formio.full.min.js +1 -1
  5. package/dist/formio.js +3 -3
  6. package/dist/formio.min.js +1 -1
  7. package/dist/formio.utils.js +3 -3
  8. package/dist/formio.utils.min.js +1 -1
  9. package/lib/cjs/Form.js +4 -4
  10. package/lib/cjs/PDFBuilder.js +4 -4
  11. package/lib/cjs/Webform.d.ts +12 -12
  12. package/lib/cjs/Webform.js +132 -131
  13. package/lib/cjs/WebformBuilder.js +10 -10
  14. package/lib/cjs/Wizard.js +1 -1
  15. package/lib/cjs/WizardBuilder.js +1 -1
  16. package/lib/cjs/components/_classes/component/Component.js +12 -11
  17. package/lib/cjs/components/_classes/list/ListComponent.js +4 -4
  18. package/lib/cjs/components/_classes/multivalue/Multivalue.js +2 -2
  19. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +3 -3
  20. package/lib/cjs/components/address/Address.js +1 -1
  21. package/lib/cjs/components/button/Button.js +6 -6
  22. package/lib/cjs/components/checkbox/Checkbox.js +1 -1
  23. package/lib/cjs/components/datagrid/DataGrid.js +1 -1
  24. package/lib/cjs/components/datetime/DateTime.js +4 -0
  25. package/lib/cjs/components/day/Day.js +4 -20
  26. package/lib/cjs/components/editgrid/EditGrid.js +4 -4
  27. package/lib/cjs/components/file/File.js +15 -15
  28. package/lib/cjs/components/form/Form.js +4 -4
  29. package/lib/cjs/components/number/Number.js +1 -1
  30. package/lib/cjs/components/recaptcha/ReCaptcha.js +2 -2
  31. package/lib/cjs/components/select/Select.js +5 -5
  32. package/lib/cjs/components/selectboxes/SelectBoxes.js +2 -2
  33. package/lib/cjs/components/signature/Signature.d.ts +1 -1
  34. package/lib/cjs/components/signature/Signature.js +2 -2
  35. package/lib/cjs/components/survey/Survey.js +2 -2
  36. package/lib/cjs/components/textarea/TextArea.js +6 -6
  37. package/lib/cjs/components/textfield/TextField.js +3 -0
  38. package/lib/cjs/formio.form.js +4 -0
  39. package/lib/cjs/translations/en.d.ts +234 -81
  40. package/lib/cjs/translations/en.js +8 -81
  41. package/lib/cjs/utils/i18n.d.ts +5 -2
  42. package/lib/cjs/utils/i18n.js +32 -5
  43. package/lib/mjs/Form.js +4 -4
  44. package/lib/mjs/PDFBuilder.js +4 -4
  45. package/lib/mjs/Webform.d.ts +12 -12
  46. package/lib/mjs/Webform.js +142 -141
  47. package/lib/mjs/WebformBuilder.js +10 -10
  48. package/lib/mjs/Wizard.js +1 -1
  49. package/lib/mjs/WizardBuilder.js +1 -1
  50. package/lib/mjs/components/_classes/component/Component.js +12 -11
  51. package/lib/mjs/components/_classes/list/ListComponent.js +4 -4
  52. package/lib/mjs/components/_classes/multivalue/Multivalue.js +2 -2
  53. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +3 -3
  54. package/lib/mjs/components/address/Address.js +1 -1
  55. package/lib/mjs/components/button/Button.js +6 -6
  56. package/lib/mjs/components/checkbox/Checkbox.js +1 -1
  57. package/lib/mjs/components/datagrid/DataGrid.js +1 -1
  58. package/lib/mjs/components/datetime/DateTime.js +5 -1
  59. package/lib/mjs/components/day/Day.js +4 -20
  60. package/lib/mjs/components/editgrid/EditGrid.js +4 -4
  61. package/lib/mjs/components/file/File.js +15 -15
  62. package/lib/mjs/components/form/Form.js +4 -4
  63. package/lib/mjs/components/number/Number.js +1 -1
  64. package/lib/mjs/components/recaptcha/ReCaptcha.js +2 -2
  65. package/lib/mjs/components/select/Select.js +7 -7
  66. package/lib/mjs/components/selectboxes/SelectBoxes.js +2 -2
  67. package/lib/mjs/components/signature/Signature.d.ts +1 -1
  68. package/lib/mjs/components/signature/Signature.js +2 -2
  69. package/lib/mjs/components/survey/Survey.js +2 -2
  70. package/lib/mjs/components/textarea/TextArea.js +6 -6
  71. package/lib/mjs/components/textfield/TextField.js +3 -0
  72. package/lib/mjs/formio.form.js +4 -0
  73. package/lib/mjs/translations/en.d.ts +234 -81
  74. package/lib/mjs/translations/en.js +89 -3
  75. package/lib/mjs/utils/i18n.d.ts +5 -2
  76. package/lib/mjs/utils/i18n.js +32 -5
  77. package/package.json +3 -3
@@ -1,13 +1,13 @@
1
- import _ from "lodash";
2
- import moment from "moment";
3
- import { compareVersions } from "compare-versions";
4
- import EventEmitter from "./EventEmitter";
5
- import i18nDefaults from "./i18n";
6
- import { Formio } from "./Formio";
7
- import Components from "./components/Components";
8
- import NestedDataComponent from "./components/_classes/nesteddata/NestedDataComponent";
9
- import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, } from "./utils/utils";
10
- import { eachComponent } from "./utils/formUtils";
1
+ import _ from 'lodash';
2
+ import moment from 'moment';
3
+ import { compareVersions } from 'compare-versions';
4
+ import EventEmitter from './EventEmitter';
5
+ import i18nDefaults from './i18n';
6
+ import { Formio } from './Formio';
7
+ import Components from './components/Components';
8
+ import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent';
9
+ import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, } from './utils/utils';
10
+ import { eachComponent } from './utils/formUtils';
11
11
  // We need this here because dragula pulls in CustomEvent class that requires global to exist.
12
12
  if (typeof window !== 'undefined' && typeof window.global === 'undefined') {
13
13
  window.global = window;
@@ -22,10 +22,10 @@ Formio.registerComponent = Components.setComponent;
22
22
  * @returns {any} - The icon set.
23
23
  */
24
24
  function getIconSet(icons) {
25
- if (icons === "fontawesome") {
26
- return "fa";
25
+ if (icons === 'fontawesome') {
26
+ return 'fa';
27
27
  }
28
- return icons || "";
28
+ return icons || '';
29
29
  }
30
30
  /**
31
31
  *
@@ -40,7 +40,7 @@ function getOptions(options) {
40
40
  saveDraft: false,
41
41
  alwaysDirty: false,
42
42
  saveDraftThrottle: 5000,
43
- display: "form",
43
+ display: 'form',
44
44
  cdnUrl: Formio.cdn.baseUrl,
45
45
  });
46
46
  if (!options.events) {
@@ -84,10 +84,10 @@ function getOptions(options) {
84
84
  */
85
85
  /**
86
86
  * @typedef {object} ButtonSettings
87
- * @property {boolean} [showPrevious] - Show the "Previous" button.
88
- * @property {boolean} [showNext] - Show the "Next" button.
89
- * @property {boolean} [showCancel] - Show the "Cancel" button.
90
- * @property {boolean} [showSubmit] - Show the "Submit" button.
87
+ * @property {boolean} [showPrevious] - Show the 'Previous' button.
88
+ * @property {boolean} [showNext] - Show the 'Next' button.
89
+ * @property {boolean} [showCancel] - Show the 'Cancel' button.
90
+ * @property {boolean} [showSubmit] - Show the 'Submit' button.
91
91
  */
92
92
  /**
93
93
  * @typedef {object} FormOptions
@@ -164,8 +164,8 @@ export default class Webform extends NestedDataComponent {
164
164
  * The type of this element.
165
165
  * @type {string}
166
166
  */
167
- this.type = "form";
168
- this._src = "";
167
+ this.type = 'form';
168
+ this._src = '';
169
169
  this._loading = false;
170
170
  this._form = {};
171
171
  this.draftEnabled = false;
@@ -313,7 +313,7 @@ export default class Webform extends NestedDataComponent {
313
313
  return;
314
314
  }
315
315
  this.rebuild();
316
- this.emit("languageChanged");
316
+ this.emit('languageChanged');
317
317
  });
318
318
  }
319
319
  get componentComponents() {
@@ -331,18 +331,18 @@ export default class Webform extends NestedDataComponent {
331
331
  addLanguage(code, lang, active = false) {
332
332
  if (this.i18next) {
333
333
  var translations = _.assign(fastCloneDeep(i18nDefaults.resources.en.translation), lang);
334
- this.i18next.addResourceBundle(code, "translation", translations, true, true);
334
+ this.i18next.addResourceBundle(code, 'translation', translations, true, true);
335
335
  if (active) {
336
336
  this.language = code;
337
337
  }
338
338
  }
339
339
  }
340
340
  keyboardCatchableElement(element) {
341
- if (element.nodeName === "TEXTAREA") {
341
+ if (element.nodeName === 'TEXTAREA') {
342
342
  return false;
343
343
  }
344
- if (element.nodeName === "INPUT") {
345
- return ["text", "email", "password"].indexOf(element.type) === -1;
344
+ if (element.nodeName === 'INPUT') {
345
+ return ['text', 'email', 'password'].indexOf(element.type) === -1;
346
346
  }
347
347
  return true;
348
348
  }
@@ -353,15 +353,15 @@ export default class Webform extends NestedDataComponent {
353
353
  }
354
354
  const ctrl = event.ctrlKey || event.metaKey;
355
355
  const keyCode = event.keyCode;
356
- let char = "";
356
+ let char = '';
357
357
  if (65 <= keyCode && keyCode <= 90) {
358
358
  char = String.fromCharCode(keyCode);
359
359
  }
360
360
  else if (keyCode === 13) {
361
- char = "Enter";
361
+ char = 'Enter';
362
362
  }
363
363
  else if (keyCode === 27) {
364
- char = "Esc";
364
+ char = 'Esc';
365
365
  }
366
366
  _.each(this.shortcuts, (shortcut) => {
367
367
  if (shortcut.ctrl && !ctrl) {
@@ -378,9 +378,9 @@ export default class Webform extends NestedDataComponent {
378
378
  return;
379
379
  }
380
380
  shortcut = _.capitalize(shortcut);
381
- if (shortcut === "Enter" || shortcut === "Esc") {
381
+ if (shortcut === 'Enter' || shortcut === 'Esc') {
382
382
  // Restrict Enter and Esc only for buttons
383
- if (element.tagName !== "BUTTON") {
383
+ if (element.tagName !== 'BUTTON') {
384
384
  return;
385
385
  }
386
386
  this.shortcuts.push({
@@ -480,13 +480,13 @@ export default class Webform extends NestedDataComponent {
480
480
  * @returns {boolean} - TRUE means the url was set, FALSE otherwise.
481
481
  */
482
482
  setUrl(value, options) {
483
- if (!value || typeof value !== "string" || value === this._src) {
483
+ if (!value || typeof value !== 'string' || value === this._src) {
484
484
  return false;
485
485
  }
486
486
  this._src = value;
487
487
  this.nosubmit = true;
488
488
  this.formio = this.options.formio = new Formio(value, options);
489
- if (this.type === "form") {
489
+ if (this.type === 'form') {
490
490
  // Set the options source so this can be passed to other components.
491
491
  this.options.src = value;
492
492
  }
@@ -519,17 +519,17 @@ export default class Webform extends NestedDataComponent {
519
519
  }
520
520
  /**
521
521
  * Set the loading state for this form, and also show the loader spinner.
522
- * @param {boolean} loading - If this form should be "loading" or not.
522
+ * @param {boolean} loading - If this form should be 'loading' or not.
523
523
  */
524
524
  set loading(loading) {
525
525
  if (this._loading !== loading) {
526
526
  this._loading = loading;
527
527
  if (!this.loader && loading) {
528
- this.loader = this.ce("div", {
529
- class: "loader-wrapper",
528
+ this.loader = this.ce('div', {
529
+ class: 'loader-wrapper',
530
530
  });
531
- const spinner = this.ce("div", {
532
- class: "loader text-center",
531
+ const spinner = this.ce('div', {
532
+ class: 'loader text-center',
533
533
  });
534
534
  this.loader.appendChild(spinner);
535
535
  }
@@ -613,18 +613,18 @@ export default class Webform extends NestedDataComponent {
613
613
  // Use the sanitize config from the form settings or the global sanitize config if it is not provided in the options
614
614
  if (!this.options.sanitizeConfig && !this.builderMode) {
615
615
  this.options.sanitizeConfig =
616
- _.get(form, "settings.sanitizeConfig") ||
617
- _.get(form, "globalSettings.sanitizeConfig");
616
+ _.get(form, 'settings.sanitizeConfig') ||
617
+ _.get(form, 'globalSettings.sanitizeConfig');
618
618
  }
619
- if ("schema" in form && compareVersions(form.schema, "1.x") > 0) {
619
+ if ('schema' in form && compareVersions(form.schema, '1.x') > 0) {
620
620
  this.ready.then(() => {
621
- this.setAlert("alert alert-danger", "Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.");
621
+ this.setAlert('alert alert-danger', this.t('newFormSchema'));
622
622
  });
623
623
  }
624
624
  // See if they pass a module, and evaluate it if so.
625
625
  if (form && form.module) {
626
626
  let formModule = null;
627
- if (typeof form.module === "string") {
627
+ if (typeof form.module === 'string') {
628
628
  try {
629
629
  formModule = this.evaluate(`return ${form.module}`);
630
630
  }
@@ -646,7 +646,7 @@ export default class Webform extends NestedDataComponent {
646
646
  this.initialized = false;
647
647
  const rebuild = this.rebuild() || Promise.resolve();
648
648
  return rebuild.then(() => {
649
- this.emit("formLoad", form);
649
+ this.emit('formLoad', form);
650
650
  this.triggerCaptcha();
651
651
  // Make sure to trigger onChange after a render event occurs to speed up form rendering.
652
652
  setTimeout(() => {
@@ -720,7 +720,7 @@ export default class Webform extends NestedDataComponent {
720
720
  setSubmission(submission, flags = {}) {
721
721
  flags = {
722
722
  ...flags,
723
- fromSubmission: _.has(flags, "fromSubmission") ? flags.fromSubmission : true,
723
+ fromSubmission: _.has(flags, 'fromSubmission') ? flags.fromSubmission : true,
724
724
  };
725
725
  return (this.onSubmission = this.formReady
726
726
  .then((resolveFlags) => {
@@ -736,26 +736,26 @@ export default class Webform extends NestedDataComponent {
736
736
  .catch((err) => this.submissionReadyReject(err)));
737
737
  }
738
738
  handleDraftError(errName, errDetails, restoreDraft) {
739
- const errorMessage = _.trim(`${this.t(errName)} ${errDetails || ""}`);
739
+ const errorMessage = _.trim(`${this.t(errName)} ${errDetails || ''}`);
740
740
  console.warn(errorMessage);
741
- this.emit(restoreDraft ? "restoreDraftError" : "saveDraftError", errDetails || errorMessage);
741
+ this.emit(restoreDraft ? 'restoreDraftError' : 'saveDraftError', errDetails || errorMessage);
742
742
  }
743
743
  saveDraft() {
744
744
  if (!this.draftEnabled || this.parent?.component.reference === false) {
745
745
  return;
746
746
  }
747
747
  if (!this.formio) {
748
- this.handleDraftError("saveDraftInstanceError");
748
+ this.handleDraftError('saveDraftInstanceError');
749
749
  return;
750
750
  }
751
751
  if (!Formio.getUser()) {
752
- this.handleDraftError("saveDraftAuthError");
752
+ this.handleDraftError('saveDraftAuthError');
753
753
  return;
754
754
  }
755
755
  const draft = fastCloneDeep(this.submission);
756
- draft.state = "draft";
756
+ draft.state = 'draft';
757
757
  if (!this.savingDraft && !this.submitting) {
758
- this.emit("saveDraftBegin");
758
+ this.emit('saveDraftBegin');
759
759
  this.savingDraft = true;
760
760
  this.formio
761
761
  .saveSubmission(draft)
@@ -763,11 +763,11 @@ export default class Webform extends NestedDataComponent {
763
763
  // Set id to submission to avoid creating new draft submission
764
764
  this.submission._id = sub._id;
765
765
  this.savingDraft = false;
766
- this.emit("saveDraft", sub);
766
+ this.emit('saveDraft', sub);
767
767
  })
768
768
  .catch((err) => {
769
769
  this.savingDraft = false;
770
- this.handleDraftError("saveDraftError", err);
770
+ this.handleDraftError('saveDraftError', err);
771
771
  });
772
772
  }
773
773
  }
@@ -778,7 +778,7 @@ export default class Webform extends NestedDataComponent {
778
778
  restoreDraft(userId) {
779
779
  const formio = this.formio || this.options.formio;
780
780
  if (!formio) {
781
- this.handleDraftError("restoreDraftInstanceError", null, true);
781
+ this.handleDraftError('restoreDraftInstanceError', null, true);
782
782
  return;
783
783
  }
784
784
  this.savingDraft = true;
@@ -796,22 +796,22 @@ export default class Webform extends NestedDataComponent {
796
796
  return this.setSubmission(draft).then(() => {
797
797
  this.draftEnabled = true;
798
798
  this.savingDraft = false;
799
- this.emit("restoreDraft", draft);
799
+ this.emit('restoreDraft', draft);
800
800
  });
801
801
  }
802
802
  // Enable drafts so that we can keep track of changes.
803
803
  this.draftEnabled = true;
804
804
  this.savingDraft = false;
805
- this.emit("restoreDraft", null);
805
+ this.emit('restoreDraft', null);
806
806
  })
807
807
  .catch((err) => {
808
808
  this.draftEnabled = true;
809
809
  this.savingDraft = false;
810
- this.handleDraftError("restoreDraftError", err, true);
810
+ this.handleDraftError('restoreDraftError', err, true);
811
811
  });
812
812
  }
813
813
  get schema() {
814
- const schema = fastCloneDeep(_.omit(this._form, ["components"]));
814
+ const schema = fastCloneDeep(_.omit(this._form, ['components']));
815
815
  schema.components = [];
816
816
  this.eachComponent((component) => schema.components.push(component.schema));
817
817
  return schema;
@@ -886,10 +886,10 @@ export default class Webform extends NestedDataComponent {
886
886
  else {
887
887
  this.component = this.form;
888
888
  }
889
- this.component.type = "form";
889
+ this.component.type = 'form';
890
890
  this.component.input = false;
891
891
  this.addComponents();
892
- this.on("submitButton", (options) => {
892
+ this.on('submitButton', (options) => {
893
893
  this.submit(false, options).catch((e) => {
894
894
  if (options?.instance) {
895
895
  options.instance.loading = false;
@@ -897,11 +897,11 @@ export default class Webform extends NestedDataComponent {
897
897
  return e !== false && e !== undefined && console.log(e);
898
898
  });
899
899
  }, true);
900
- this.on("checkValidity", (data) => this.validate(data, { dirty: true, process: "change" }), true);
901
- this.on("requestUrl", (args) => this.submitUrl(args.url, args.headers), true);
902
- this.on("resetForm", () => this.resetValue(), true);
903
- this.on("deleteSubmission", () => this.deleteSubmission(), true);
904
- this.on("refreshData", () => this.updateValue(), true);
900
+ this.on('checkValidity', (data) => this.validate(data, { dirty: true, process: 'change' }), true);
901
+ this.on('requestUrl', (args) => this.submitUrl(args.url, args.headers), true);
902
+ this.on('resetForm', () => this.resetValue(), true);
903
+ this.on('deleteSubmission', () => this.deleteSubmission(), true);
904
+ this.on('refreshData', () => this.updateValue(), true);
905
905
  this.executeFormController();
906
906
  return this.formReady;
907
907
  }
@@ -926,19 +926,19 @@ export default class Webform extends NestedDataComponent {
926
926
  *
927
927
  */
928
928
  teardown() {
929
- this.emit("formDelete", this.id);
929
+ this.emit('formDelete', this.id);
930
930
  delete Formio.forms[this.id];
931
931
  delete this.executeShortcuts;
932
932
  delete this.triggerSaveDraft;
933
933
  super.teardown();
934
934
  }
935
935
  destroy(all = false) {
936
- this.off("submitButton");
937
- this.off("checkValidity");
938
- this.off("requestUrl");
939
- this.off("resetForm");
940
- this.off("deleteSubmission");
941
- this.off("refreshData");
936
+ this.off('submitButton');
937
+ this.off('checkValidity');
938
+ this.off('requestUrl');
939
+ this.off('resetForm');
940
+ this.off('deleteSubmission');
941
+ this.off('refreshData');
942
942
  return super.destroy(all);
943
943
  }
944
944
  build(element) {
@@ -951,17 +951,17 @@ export default class Webform extends NestedDataComponent {
951
951
  return this.ready;
952
952
  }
953
953
  getClassName() {
954
- let classes = "formio-form";
954
+ let classes = 'formio-form';
955
955
  if (this.options.readOnly) {
956
- classes += " formio-read-only";
956
+ classes += ' formio-read-only';
957
957
  }
958
958
  return classes;
959
959
  }
960
960
  render() {
961
- return super.render(this.renderTemplate("webform", {
961
+ return super.render(this.renderTemplate('webform', {
962
962
  classes: this.getClassName(),
963
963
  children: this.renderComponents(),
964
- }), this.builderMode ? "builder" : "form", true);
964
+ }), this.builderMode ? 'builder' : 'form', true);
965
965
  }
966
966
  redraw() {
967
967
  // Don't bother if we have not built yet.
@@ -974,13 +974,13 @@ export default class Webform extends NestedDataComponent {
974
974
  }
975
975
  attach(element) {
976
976
  this.setElement(element);
977
- this.loadRefs(element, { webform: "single" });
977
+ this.loadRefs(element, { webform: 'single' });
978
978
  const childPromise = this.attachComponents(this.refs.webform);
979
- this.addEventListener(document, "keydown", this.executeShortcuts);
979
+ this.addEventListener(document, 'keydown', this.executeShortcuts);
980
980
  this.currentForm = this;
981
- this.hook("attachWebform", element, this);
981
+ this.hook('attachWebform', element, this);
982
982
  return childPromise.then(() => {
983
- this.emit("render", this.element);
983
+ this.emit('render', this.element);
984
984
  return this.setValue(this._submission, {
985
985
  noUpdateEvent: true,
986
986
  });
@@ -1003,7 +1003,7 @@ export default class Webform extends NestedDataComponent {
1003
1003
  }
1004
1004
  /**
1005
1005
  * Sets a new alert to display in the error dialog of the form.
1006
- * @param {string} type - The type of alert to display. "danger", "success", "warning", etc.
1006
+ * @param {string} type - The type of alert to display. 'danger', 'success', 'warning', etc.
1007
1007
  * @param {string} message - The message to show in the alert.
1008
1008
  * @param {object} options - The options for the alert.
1009
1009
  */
@@ -1012,8 +1012,8 @@ export default class Webform extends NestedDataComponent {
1012
1012
  if (this.alert) {
1013
1013
  if (this.refs.errorRef && this.refs.errorRef.length) {
1014
1014
  this.refs.errorRef.forEach((el) => {
1015
- this.removeEventListener(el, "click");
1016
- this.removeEventListener(el, "keypress");
1015
+ this.removeEventListener(el, 'click');
1016
+ this.removeEventListener(el, 'keypress');
1017
1017
  });
1018
1018
  }
1019
1019
  this.removeChild(this.alert);
@@ -1023,7 +1023,7 @@ export default class Webform extends NestedDataComponent {
1023
1023
  }
1024
1024
  if (this.options.noAlerts) {
1025
1025
  if (!message) {
1026
- this.emit("error", false);
1026
+ this.emit('error', false);
1027
1027
  }
1028
1028
  return;
1029
1029
  }
@@ -1031,8 +1031,8 @@ export default class Webform extends NestedDataComponent {
1031
1031
  try {
1032
1032
  if (this.refs.errorRef && this.refs.errorRef.length) {
1033
1033
  this.refs.errorRef.forEach((el) => {
1034
- this.removeEventListener(el, "click");
1035
- this.removeEventListener(el, "keypress");
1034
+ this.removeEventListener(el, 'click');
1035
+ this.removeEventListener(el, 'keypress');
1036
1036
  });
1037
1037
  }
1038
1038
  this.removeChild(this.alert);
@@ -1052,19 +1052,19 @@ export default class Webform extends NestedDataComponent {
1052
1052
  attrs: attrs,
1053
1053
  type,
1054
1054
  };
1055
- this.alert = convertStringToHTMLElement(this.renderTemplate("alert", templateOptions), `#${attrs.id}`);
1055
+ this.alert = convertStringToHTMLElement(this.renderTemplate('alert', templateOptions), `#${attrs.id}`);
1056
1056
  }
1057
1057
  if (!this.alert) {
1058
1058
  return;
1059
1059
  }
1060
- this.loadRefs(this.alert, { errorRef: "multiple" });
1060
+ this.loadRefs(this.alert, { errorRef: 'multiple' });
1061
1061
  if (this.refs.errorRef && this.refs.errorRef.length) {
1062
1062
  this.refs.errorRef.forEach((el) => {
1063
- this.addEventListener(el, "click", (e) => {
1063
+ this.addEventListener(el, 'click', (e) => {
1064
1064
  const key = e.currentTarget.dataset.componentKey;
1065
1065
  this.focusOnComponent(key);
1066
1066
  });
1067
- this.addEventListener(el, "keydown", (e) => {
1067
+ this.addEventListener(el, 'keydown', (e) => {
1068
1068
  if (e.keyCode === 13) {
1069
1069
  e.preventDefault();
1070
1070
  const key = e.currentTarget.dataset.componentKey;
@@ -1142,8 +1142,8 @@ export default class Webform extends NestedDataComponent {
1142
1142
  (err.context?.component && err.context?.component.key) ||
1143
1143
  (err.component && err.component.key) ||
1144
1144
  (err.fromServer && err.path);
1145
- const formattedKeyOrPath = keyOrPath ? getStringFromComponentPath(keyOrPath) : "";
1146
- if (typeof err !== "string" && !err.formattedKeyOrPath) {
1145
+ const formattedKeyOrPath = keyOrPath ? getStringFromComponentPath(keyOrPath) : '';
1146
+ if (typeof err !== 'string' && !err.formattedKeyOrPath) {
1147
1147
  err.formattedKeyOrPath = formattedKeyOrPath;
1148
1148
  }
1149
1149
  return {
@@ -1153,18 +1153,18 @@ export default class Webform extends NestedDataComponent {
1153
1153
  };
1154
1154
  errors.forEach(({ message, context, fromServer, component }, index) => {
1155
1155
  const text = !component?.label || context?.hasLabel || fromServer
1156
- ? this.t("alertMessage", { message: this.t(message) })
1157
- : this.t("alertMessageWithLabel", {
1156
+ ? this.t('alertMessage', { message: this.t(message) })
1157
+ : this.t('alertMessageWithLabel', {
1158
1158
  label: this.t(component?.label),
1159
1159
  message: this.t(message),
1160
1160
  });
1161
1161
  displayedErrors.push(createListItem(text, index));
1162
1162
  });
1163
1163
  }
1164
- const errorsList = this.renderTemplate("errorsList", { errors: displayedErrors });
1165
- this.root.setAlert("danger", errorsList);
1164
+ const errorsList = this.renderTemplate('errorsList', { errors: displayedErrors });
1165
+ this.root.setAlert('danger', errorsList);
1166
1166
  if (triggerEvent) {
1167
- this.emit("error", errors);
1167
+ this.emit('error', errors);
1168
1168
  }
1169
1169
  return errors;
1170
1170
  }
@@ -1184,23 +1184,23 @@ export default class Webform extends NestedDataComponent {
1184
1184
  noValidate: true,
1185
1185
  noCheck: true,
1186
1186
  });
1187
- this.setAlert("success", `<p>${this.t("complete")}</p>`);
1187
+ this.setAlert('success', `<p>${this.t('complete')}</p>`);
1188
1188
  // Cancel triggered saveDraft to prevent overriding the submitted state
1189
1189
  if (this.draftEnabled && this.triggerSaveDraft?.cancel) {
1190
1190
  this.triggerSaveDraft.cancel();
1191
1191
  }
1192
- this.emit("submit", submission, saved);
1192
+ this.emit('submit', submission, saved);
1193
1193
  if (saved) {
1194
- this.emit("submitDone", submission);
1194
+ this.emit('submitDone', submission);
1195
1195
  }
1196
1196
  return submission;
1197
1197
  }
1198
1198
  normalizeError(error) {
1199
1199
  if (error) {
1200
- if (typeof error === "object" && "details" in error) {
1200
+ if (typeof error === 'object' && 'details' in error) {
1201
1201
  error = error.details;
1202
1202
  }
1203
- if (typeof error === "string") {
1203
+ if (typeof error === 'string') {
1204
1204
  error = { message: error };
1205
1205
  }
1206
1206
  }
@@ -1215,10 +1215,10 @@ export default class Webform extends NestedDataComponent {
1215
1215
  error = this.normalizeError(error);
1216
1216
  this.submitting = false;
1217
1217
  this.setPristine(false);
1218
- this.emit("submitError", error || this.errors);
1218
+ this.emit('submitError', error || this.errors);
1219
1219
  // Allow for silent cancellations (no error message, no submit button error state)
1220
1220
  if (error && error.silent) {
1221
- this.emit("change", { isValid: true }, { silent: true });
1221
+ this.emit('change', { isValid: true }, { silent: true });
1222
1222
  return false;
1223
1223
  }
1224
1224
  const errors = this.showErrors(error, true);
@@ -1272,12 +1272,12 @@ export default class Webform extends NestedDataComponent {
1272
1272
  this.triggerSaveDraft();
1273
1273
  }
1274
1274
  if (!flags || !flags.noEmit) {
1275
- this.emit("change", value, flags, modified);
1275
+ this.emit('change', value, flags, modified);
1276
1276
  isChangeEventEmitted = true;
1277
1277
  }
1278
1278
  // The form is initialized after the first change event occurs.
1279
1279
  if (isChangeEventEmitted && !this.initialized) {
1280
- this.emit("initialized");
1280
+ this.emit('initialized');
1281
1281
  this.initialized = true;
1282
1282
  }
1283
1283
  }
@@ -1287,7 +1287,7 @@ export default class Webform extends NestedDataComponent {
1287
1287
  */
1288
1288
  deleteSubmission() {
1289
1289
  return this.formio.deleteSubmission().then(() => {
1290
- this.emit("submissionDeleted", this.submission);
1290
+ this.emit('submissionDeleted', this.submission);
1291
1291
  this.resetValue();
1292
1292
  });
1293
1293
  }
@@ -1298,13 +1298,13 @@ export default class Webform extends NestedDataComponent {
1298
1298
  * @returns {boolean} - TRUE means the submission was cancelled, FALSE otherwise.
1299
1299
  */
1300
1300
  cancel(noconfirm) {
1301
- const shouldReset = this.hook("beforeCancel", true);
1302
- if (shouldReset && (noconfirm || confirm(this.t("confirmCancel")))) {
1301
+ const shouldReset = this.hook('beforeCancel', true);
1302
+ if (shouldReset && (noconfirm || confirm(this.t('confirmCancel')))) {
1303
1303
  this.resetValue();
1304
1304
  return true;
1305
1305
  }
1306
1306
  else {
1307
- this.emit("cancelSubmit");
1307
+ this.emit('cancelSubmit');
1308
1308
  return false;
1309
1309
  }
1310
1310
  }
@@ -1312,8 +1312,8 @@ export default class Webform extends NestedDataComponent {
1312
1312
  // Add in metadata about client submitting the form
1313
1313
  submission.metadata = submission.metadata || {};
1314
1314
  _.defaults(submission.metadata, {
1315
- timezone: _.get(this, "_submission.metadata.timezone", currentTimezone()),
1316
- offset: parseInt(_.get(this, "_submission.metadata.offset", moment().utcOffset()), 10),
1315
+ timezone: _.get(this, '_submission.metadata.timezone', currentTimezone()),
1316
+ offset: parseInt(_.get(this, '_submission.metadata.offset', moment().utcOffset()), 10),
1317
1317
  origin: document.location.origin,
1318
1318
  referrer: document.referrer,
1319
1319
  browserName: navigator.appName,
@@ -1334,26 +1334,26 @@ export default class Webform extends NestedDataComponent {
1334
1334
  }
1335
1335
  const submission = fastCloneDeep(this.submission || {});
1336
1336
  this.setMetadata(submission);
1337
- submission.state = options.state || submission.state || "submitted";
1338
- const isDraft = submission.state === "draft";
1339
- this.hook("beforeSubmit", { ...submission, component: options.component }, (err, data) => {
1337
+ submission.state = options.state || submission.state || 'submitted';
1338
+ const isDraft = submission.state === 'draft';
1339
+ this.hook('beforeSubmit', { ...submission, component: options.component }, (err, data) => {
1340
1340
  if (err) {
1341
1341
  return reject(err);
1342
1342
  }
1343
- submission._vnote = data && data._vnote ? data._vnote : "";
1343
+ submission._vnote = data && data._vnote ? data._vnote : '';
1344
1344
  try {
1345
1345
  if (!isDraft && !options.noValidate) {
1346
1346
  if (!submission.data) {
1347
- return reject("Invalid Submission");
1347
+ return reject('Invalid Submission');
1348
1348
  }
1349
1349
  const errors = this.validate(submission.data, {
1350
1350
  local,
1351
1351
  dirty: true,
1352
1352
  silentCheck: false,
1353
- process: "submit",
1353
+ process: 'submit',
1354
1354
  });
1355
1355
  if (errors.length ||
1356
- options.beforeSubmitResults?.some((result) => result.status === "rejected")) {
1356
+ options.beforeSubmitResults?.some((result) => result.status === 'rejected')) {
1357
1357
  return reject(errors);
1358
1358
  }
1359
1359
  }
@@ -1362,18 +1362,18 @@ export default class Webform extends NestedDataComponent {
1362
1362
  console.error(err);
1363
1363
  }
1364
1364
  this.everyComponent((comp) => {
1365
- if (submission._vnote && comp.type === "form" && comp.component.reference) {
1365
+ if (submission._vnote && comp.type === 'form' && comp.component.reference) {
1366
1366
  _.get(submission.data, local ? comp.paths?.localDataPath : comp.path, {})._vnote = submission._vnote;
1367
1367
  }
1368
1368
  const { persistent } = comp.component;
1369
- if (persistent === "client-only") {
1369
+ if (persistent === 'client-only') {
1370
1370
  _.unset(submission.data, local ? comp.paths?.localDataPath : comp.path);
1371
1371
  }
1372
1372
  });
1373
- this.hook("customValidation", { ...submission, component: options.component }, (err) => {
1373
+ this.hook('customValidation', { ...submission, component: options.component }, (err) => {
1374
1374
  if (err) {
1375
1375
  // If string is returned, cast to object.
1376
- if (typeof err === "string") {
1376
+ if (typeof err === 'string') {
1377
1377
  err = {
1378
1378
  message: err,
1379
1379
  };
@@ -1387,8 +1387,8 @@ export default class Webform extends NestedDataComponent {
1387
1387
  if (this._form && this._form.action) {
1388
1388
  const method = submission.data._id &&
1389
1389
  this._form.action.includes(submission.data._id)
1390
- ? "PUT"
1391
- : "POST";
1390
+ ? 'PUT'
1391
+ : 'POST';
1392
1392
  return Formio.makeStaticRequest(this._form.action, method, submission, this.formio ? this.formio.options : {})
1393
1393
  .then((result) => resolve({
1394
1394
  submission: result,
@@ -1408,8 +1408,8 @@ export default class Webform extends NestedDataComponent {
1408
1408
  }
1409
1409
  // If this is an actionUrl, then make sure to save the action and not the submission.
1410
1410
  const submitMethod = submitFormio.actionUrl
1411
- ? "saveAction"
1412
- : "saveSubmission";
1411
+ ? 'saveAction'
1412
+ : 'saveSubmission';
1413
1413
  submitFormio[submitMethod](submission)
1414
1414
  .then((result) => resolve({
1415
1415
  submission: result,
@@ -1426,14 +1426,14 @@ export default class Webform extends NestedDataComponent {
1426
1426
  setServerErrors(error) {
1427
1427
  if (error.details) {
1428
1428
  this.serverErrors = error.details
1429
- .filter((err) => (err.level ? err.level === "error" : err))
1429
+ .filter((err) => (err.level ? err.level === 'error' : err))
1430
1430
  .map((err) => {
1431
1431
  err.fromServer = true;
1432
1432
  return err;
1433
1433
  });
1434
1434
  }
1435
- else if (typeof error === "string") {
1436
- this.serverErrors = [{ fromServer: true, level: "error", message: error }];
1435
+ else if (typeof error === 'string') {
1436
+ this.serverErrors = [{ fromServer: true, level: 'error', message: error }];
1437
1437
  }
1438
1438
  }
1439
1439
  executeSubmit(options) {
@@ -1491,17 +1491,17 @@ export default class Webform extends NestedDataComponent {
1491
1491
  }
1492
1492
  submitUrl(URL, headers) {
1493
1493
  if (!URL) {
1494
- return console.warn("Missing URL argument");
1494
+ return console.warn(this.t('missingUrl'));
1495
1495
  }
1496
1496
  const submission = this.submission || {};
1497
1497
  const API_URL = URL;
1498
1498
  const settings = {
1499
- method: "POST",
1499
+ method: 'POST',
1500
1500
  headers: {},
1501
1501
  };
1502
1502
  if (headers && headers.length > 0) {
1503
1503
  headers.map((e) => {
1504
- if (e.header !== "" && e.value !== "") {
1504
+ if (e.header !== '' && e.value !== '') {
1505
1505
  settings.headers[e.header] = this.interpolate(e.value, submission);
1506
1506
  }
1507
1507
  });
@@ -1511,21 +1511,22 @@ export default class Webform extends NestedDataComponent {
1511
1511
  headers: settings.headers,
1512
1512
  })
1513
1513
  .then(() => {
1514
- this.emit("requestDone");
1515
- this.setAlert("success", "<p> Success </p>");
1514
+ this.emit('requestDone');
1515
+ this.setAlert('success', `<p> ${this.t('success')} </p>`);
1516
1516
  })
1517
1517
  .catch((e) => {
1518
- const message = `${e.statusText ? e.statusText : ""} ${e.status ? e.status : e}`;
1519
- this.emit("error", message);
1518
+ const message = `${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`;
1519
+ this.emit('error', message);
1520
1520
  console.error(message);
1521
- this.setAlert("danger", `<p> ${message} </p>`);
1521
+ this.setAlert('danger', `<p> ${message} </p>`);
1522
1522
  return Promise.reject(this.onSubmissionError(e));
1523
1523
  });
1524
1524
  }
1525
1525
  else {
1526
- this.emit("error", "You should add a URL to this button.");
1527
- this.setAlert("warning", "You should add a URL to this button.");
1528
- return console.warn("You should add a URL to this button.");
1526
+ const message = this.t('urlNotAttachedToBtn');
1527
+ this.emit('error', message);
1528
+ this.setAlert('warning', message);
1529
+ return console.warn(message);
1529
1530
  }
1530
1531
  }
1531
1532
  triggerCaptcha() {
@@ -1544,7 +1545,7 @@ export default class Webform extends NestedDataComponent {
1544
1545
  }
1545
1546
  set nosubmit(value) {
1546
1547
  this._nosubmit = !!value;
1547
- this.emit("nosubmit", this._nosubmit);
1548
+ this.emit('nosubmit', this._nosubmit);
1548
1549
  }
1549
1550
  get nosubmit() {
1550
1551
  return this._nosubmit || false;