@formio/js 5.0.0-rc.57 → 5.0.0-rc.59

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. package/dist/formio.builder.css +0 -4
  2. package/dist/formio.builder.min.css +1 -1
  3. package/dist/formio.embed.js +1 -1
  4. package/dist/formio.embed.min.js +1 -1
  5. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  6. package/dist/formio.form.css +0 -4
  7. package/dist/formio.form.js +27 -38
  8. package/dist/formio.form.min.css +1 -1
  9. package/dist/formio.form.min.js +1 -1
  10. package/dist/formio.form.min.js.LICENSE.txt +11 -3
  11. package/dist/formio.full.css +0 -4
  12. package/dist/formio.full.js +31 -42
  13. package/dist/formio.full.min.css +1 -1
  14. package/dist/formio.full.min.js +1 -1
  15. package/dist/formio.full.min.js.LICENSE.txt +11 -3
  16. package/dist/formio.js +4 -4
  17. package/dist/formio.min.js +1 -1
  18. package/dist/formio.min.js.LICENSE.txt +1 -1
  19. package/dist/formio.utils.js +15 -36
  20. package/dist/formio.utils.min.js +1 -1
  21. package/dist/formio.utils.min.js.LICENSE.txt +2 -4
  22. package/lib/cjs/CDN.d.ts +1 -0
  23. package/lib/cjs/CDN.js +6 -3
  24. package/lib/cjs/Embed.d.ts +1 -1
  25. package/lib/cjs/Embed.js +41 -7
  26. package/lib/cjs/Formio.js +11 -0
  27. package/lib/cjs/InlineEmbed.js +3 -1
  28. package/lib/cjs/Webform.d.ts +1 -1
  29. package/lib/cjs/Webform.js +11 -9
  30. package/lib/cjs/WebformBuilder.d.ts +1 -1
  31. package/lib/cjs/WebformBuilder.js +12 -17
  32. package/lib/cjs/components/_classes/component/Component.js +2 -2
  33. package/lib/cjs/components/button/Button.d.ts +1 -1
  34. package/lib/cjs/components/button/Button.js +7 -7
  35. package/lib/cjs/components/radio/Radio.d.ts +1 -1
  36. package/lib/cjs/components/radio/Radio.js +5 -3
  37. package/lib/cjs/components/recaptcha/ReCaptcha.d.ts +1 -8
  38. package/lib/cjs/components/recaptcha/ReCaptcha.form.d.ts +2 -1
  39. package/lib/cjs/components/recaptcha/ReCaptcha.form.js +3 -2
  40. package/lib/cjs/components/recaptcha/ReCaptcha.js +1 -8
  41. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.d.ts +33 -2
  42. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +13 -2
  43. package/lib/cjs/components/select/Select.js +6 -1
  44. package/lib/cjs/components/select/editForm/Select.edit.data.js +16 -2
  45. package/lib/cjs/components/select/fixtures/comp22.js +1 -1
  46. package/lib/cjs/components/select/fixtures/comp23.d.ts +58 -0
  47. package/lib/cjs/components/select/fixtures/comp23.js +49 -0
  48. package/lib/cjs/components/select/fixtures/comp24.d.ts +47 -0
  49. package/lib/cjs/components/select/fixtures/comp24.js +40 -0
  50. package/lib/cjs/components/select/fixtures/index.d.ts +3 -1
  51. package/lib/cjs/components/select/fixtures/index.js +5 -1
  52. package/lib/cjs/components/selectboxes/SelectBoxes.js +4 -1
  53. package/lib/cjs/translations/en.d.ts +1 -0
  54. package/lib/cjs/translations/en.js +1 -0
  55. package/lib/cjs/utils/utils.d.ts +6 -0
  56. package/lib/cjs/utils/utils.js +16 -2
  57. package/lib/mjs/CDN.d.ts +1 -0
  58. package/lib/mjs/CDN.js +6 -3
  59. package/lib/mjs/Embed.d.ts +1 -1
  60. package/lib/mjs/Embed.js +41 -7
  61. package/lib/mjs/Formio.js +11 -0
  62. package/lib/mjs/InlineEmbed.js +3 -1
  63. package/lib/mjs/Webform.d.ts +1 -1
  64. package/lib/mjs/Webform.js +12 -10
  65. package/lib/mjs/WebformBuilder.d.ts +1 -1
  66. package/lib/mjs/WebformBuilder.js +12 -16
  67. package/lib/mjs/components/_classes/component/Component.js +3 -3
  68. package/lib/mjs/components/button/Button.d.ts +1 -1
  69. package/lib/mjs/components/button/Button.js +7 -7
  70. package/lib/mjs/components/radio/Radio.d.ts +1 -1
  71. package/lib/mjs/components/radio/Radio.js +5 -3
  72. package/lib/mjs/components/recaptcha/ReCaptcha.d.ts +1 -8
  73. package/lib/mjs/components/recaptcha/ReCaptcha.form.d.ts +2 -1
  74. package/lib/mjs/components/recaptcha/ReCaptcha.form.js +3 -2
  75. package/lib/mjs/components/recaptcha/ReCaptcha.js +1 -8
  76. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.d.ts +33 -2
  77. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +13 -2
  78. package/lib/mjs/components/select/Select.js +6 -1
  79. package/lib/mjs/components/select/editForm/Select.edit.data.js +16 -2
  80. package/lib/mjs/components/select/fixtures/comp22.js +1 -1
  81. package/lib/mjs/components/select/fixtures/comp23.d.ts +58 -0
  82. package/lib/mjs/components/select/fixtures/comp23.js +47 -0
  83. package/lib/mjs/components/select/fixtures/comp24.d.ts +47 -0
  84. package/lib/mjs/components/select/fixtures/comp24.js +38 -0
  85. package/lib/mjs/components/select/fixtures/index.d.ts +3 -1
  86. package/lib/mjs/components/select/fixtures/index.js +3 -1
  87. package/lib/mjs/components/selectboxes/SelectBoxes.js +4 -1
  88. package/lib/mjs/translations/en.d.ts +1 -0
  89. package/lib/mjs/translations/en.js +1 -0
  90. package/lib/mjs/utils/utils.d.ts +6 -0
  91. package/lib/mjs/utils/utils.js +13 -0
  92. package/package.json +4 -4
@@ -8,7 +8,7 @@ exports.default = {
8
8
  display: 'form',
9
9
  components: [{
10
10
  label: 'Select',
11
- widget: 'choicesjs',
11
+ widget: 'html5',
12
12
  tableView: true,
13
13
  dataSrc: 'url',
14
14
  data: {
@@ -0,0 +1,58 @@
1
+ declare namespace _default {
2
+ let title: string;
3
+ let name: string;
4
+ let path: string;
5
+ let type: string;
6
+ let display: string;
7
+ let components: ({
8
+ label: string;
9
+ widget: string;
10
+ tableView: boolean;
11
+ dataSrc: string;
12
+ data: {
13
+ url: string;
14
+ headers: {
15
+ key: string;
16
+ value: string;
17
+ }[];
18
+ };
19
+ multiple: boolean;
20
+ valueProperty: string;
21
+ validateWhenHidden: boolean;
22
+ key: string;
23
+ type: string;
24
+ input: boolean;
25
+ defaultValue: string[];
26
+ selectValues: string;
27
+ disableLimit: boolean;
28
+ noRefreshOnScroll: boolean;
29
+ selectData: {
30
+ value1: {
31
+ label: string;
32
+ };
33
+ value3: {
34
+ label: string;
35
+ };
36
+ };
37
+ disableOnInvalid?: undefined;
38
+ } | {
39
+ type: string;
40
+ label: string;
41
+ key: string;
42
+ disableOnInvalid: boolean;
43
+ input: boolean;
44
+ tableView: boolean;
45
+ widget?: undefined;
46
+ dataSrc?: undefined;
47
+ data?: undefined;
48
+ multiple?: undefined;
49
+ valueProperty?: undefined;
50
+ validateWhenHidden?: undefined;
51
+ defaultValue?: undefined;
52
+ selectValues?: undefined;
53
+ disableLimit?: undefined;
54
+ noRefreshOnScroll?: undefined;
55
+ selectData?: undefined;
56
+ })[];
57
+ }
58
+ export default _default;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ title: 'FIO-8281',
5
+ name: 'fio8281',
6
+ path: 'fio8281',
7
+ type: 'form',
8
+ display: 'form',
9
+ components: [{
10
+ label: 'Select',
11
+ widget: 'choicesjs',
12
+ tableView: true,
13
+ dataSrc: 'url',
14
+ data: {
15
+ url: 'https://fake_url.com',
16
+ headers: [
17
+ {
18
+ key: '',
19
+ value: ''
20
+ },
21
+ ],
22
+ },
23
+ multiple: true,
24
+ valueProperty: 'value',
25
+ validateWhenHidden: false,
26
+ key: 'select',
27
+ type: 'select',
28
+ input: true,
29
+ defaultValue: ['value1', 'value3'],
30
+ selectValues: 'data',
31
+ disableLimit: false,
32
+ noRefreshOnScroll: false,
33
+ selectData: {
34
+ value1: {
35
+ label: 'Label 1',
36
+ },
37
+ value3: {
38
+ label: 'Label 3',
39
+ },
40
+ },
41
+ }, {
42
+ type: 'button',
43
+ label: 'Submit',
44
+ key: 'submit',
45
+ disableOnInvalid: true,
46
+ input: true,
47
+ tableView: false,
48
+ }]
49
+ };
@@ -0,0 +1,47 @@
1
+ declare namespace _default {
2
+ let title: string;
3
+ let name: string;
4
+ let path: string;
5
+ let type: string;
6
+ let display: string;
7
+ let components: ({
8
+ label: string;
9
+ widget: string;
10
+ tableView: boolean;
11
+ dataSrc: string;
12
+ data: {
13
+ resource: string;
14
+ };
15
+ template: string;
16
+ validate: {
17
+ select: boolean;
18
+ };
19
+ key: string;
20
+ type: string;
21
+ searchField: string;
22
+ input: boolean;
23
+ noRefreshOnScroll: boolean;
24
+ addResource: boolean;
25
+ reference: boolean;
26
+ valueProperty: string;
27
+ disableOnInvalid?: undefined;
28
+ } | {
29
+ type: string;
30
+ label: string;
31
+ key: string;
32
+ disableOnInvalid: boolean;
33
+ input: boolean;
34
+ tableView: boolean;
35
+ widget?: undefined;
36
+ dataSrc?: undefined;
37
+ data?: undefined;
38
+ template?: undefined;
39
+ validate?: undefined;
40
+ searchField?: undefined;
41
+ noRefreshOnScroll?: undefined;
42
+ addResource?: undefined;
43
+ reference?: undefined;
44
+ valueProperty?: undefined;
45
+ })[];
46
+ }
47
+ export default _default;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ title: 'FIO-8234',
5
+ name: 'fio8234',
6
+ path: 'fio8234',
7
+ type: 'form',
8
+ display: 'form',
9
+ components: [
10
+ {
11
+ label: 'Select',
12
+ widget: 'choicesjs',
13
+ tableView: true,
14
+ dataSrc: 'resource',
15
+ data: {
16
+ resource: '665446284c9b0163c3e0c7e6',
17
+ },
18
+ template: '<span>{{ item.data.textField1 }}</span>',
19
+ validate: {
20
+ select: false,
21
+ },
22
+ key: 'select',
23
+ type: 'select',
24
+ searchField: 'data.textField2__regex',
25
+ input: true,
26
+ noRefreshOnScroll: false,
27
+ addResource: false,
28
+ reference: false,
29
+ valueProperty: 'data.textField2',
30
+ },
31
+ {
32
+ type: 'button',
33
+ label: 'Submit',
34
+ key: 'submit',
35
+ disableOnInvalid: true,
36
+ input: true,
37
+ tableView: false,
38
+ },
39
+ ],
40
+ };
@@ -19,5 +19,7 @@ import comp19 from './comp19';
19
19
  import comp20 from './comp20';
20
20
  import comp21 from './comp21';
21
21
  import comp22 from './comp22';
22
- export { comp1, comp2, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, comp15, comp16, comp17, comp18, comp19, comp20, comp21, comp22 };
22
+ import comp23 from './comp23';
23
+ import comp24 from './comp24';
24
+ export { comp1, comp2, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, comp15, comp16, comp17, comp18, comp19, comp20, comp21, comp22, comp23, comp24 };
23
25
  export { multiSelect, multiSelectOptions } from "./comp3";
@@ -3,7 +3,7 @@ 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
- exports.comp22 = exports.comp21 = exports.comp20 = exports.comp19 = exports.comp18 = exports.comp17 = exports.comp16 = exports.comp15 = exports.comp14 = exports.comp13 = exports.comp12 = exports.comp11 = exports.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp2 = exports.comp1 = exports.multiSelectOptions = exports.multiSelect = void 0;
6
+ exports.comp24 = exports.comp23 = exports.comp22 = exports.comp21 = exports.comp20 = exports.comp19 = exports.comp18 = exports.comp17 = exports.comp16 = exports.comp15 = exports.comp14 = exports.comp13 = exports.comp12 = exports.comp11 = exports.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp2 = exports.comp1 = exports.multiSelectOptions = exports.multiSelect = void 0;
7
7
  const comp1_1 = __importDefault(require("./comp1"));
8
8
  exports.comp1 = comp1_1.default;
9
9
  const comp2_1 = __importDefault(require("./comp2"));
@@ -49,3 +49,7 @@ const comp21_1 = __importDefault(require("./comp21"));
49
49
  exports.comp21 = comp21_1.default;
50
50
  const comp22_1 = __importDefault(require("./comp22"));
51
51
  exports.comp22 = comp22_1.default;
52
+ const comp23_1 = __importDefault(require("./comp23"));
53
+ exports.comp23 = comp23_1.default;
54
+ const comp24_1 = __importDefault(require("./comp24"));
55
+ exports.comp24 = comp24_1.default;
@@ -162,11 +162,14 @@ class SelectBoxesComponent extends Radio_1.default {
162
162
  }
163
163
  return changed;
164
164
  }
165
- getValueAsString(value) {
165
+ getValueAsString(value, options = {}) {
166
166
  if (!value) {
167
167
  return '';
168
168
  }
169
169
  if (this.isSelectURL) {
170
+ if (options.modalPreview && this.loadedOptions) {
171
+ return this.loadedOptions.filter((option) => value[option.value]).map((option) => option.label).join(', ');
172
+ }
170
173
  return (0, lodash_1.default)(value).pickBy((val) => val).keys().join(', ');
171
174
  }
172
175
  return (0, lodash_1.default)(this.component.values || [])
@@ -71,5 +71,6 @@ declare namespace _default {
71
71
  let submitButtonAriaLabel: string;
72
72
  let reCaptchaTokenValidationError: string;
73
73
  let reCaptchaTokenNotSpecifiedError: string;
74
+ let apiKey: string;
74
75
  }
75
76
  export default _default;
@@ -73,4 +73,5 @@ exports.default = {
73
73
  submitButtonAriaLabel: 'Submit Form button. Click to submit the form',
74
74
  reCaptchaTokenValidationError: 'ReCAPTCHA: Token validation error',
75
75
  reCaptchaTokenNotSpecifiedError: 'ReCAPTCHA: Token is not specified in submission',
76
+ apiKey: 'API Key is not unique: {{key}}'
76
77
  };
@@ -31,6 +31,12 @@ export function getElementRect(element: HTMLElement): {
31
31
  width: number;
32
32
  height: number;
33
33
  };
34
+ /**
35
+ * Get non HTMLElement property in the window object
36
+ * @param {string} property - The window property to fetch the script plugin from.
37
+ * @returns {any | undefined} - The HTML Element property on the window object.
38
+ */
39
+ export function getScriptPlugin(property: string): any | undefined;
34
40
  /**
35
41
  * Determines the boolean value of a setting.
36
42
  * @param {string|boolean} value - A string or boolean value to convert to boolean.
@@ -30,8 +30,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  return (mod && mod.__esModule) ? mod : { "default": mod };
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.observeOverload = exports.withSwitch = exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToMoment = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.momentDate = exports.loadZones = exports.shouldLoadZones = exports.zonesLoaded = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = exports.moment = exports.ConditionOperators = exports.jsonLogic = void 0;
34
- exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = void 0;
33
+ exports.withSwitch = exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToMoment = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.momentDate = exports.loadZones = exports.shouldLoadZones = exports.zonesLoaded = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = exports.moment = exports.ConditionOperators = exports.jsonLogic = void 0;
34
+ exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = void 0;
35
35
  const lodash_1 = __importDefault(require("lodash"));
36
36
  exports._ = lodash_1.default;
37
37
  const fetch_ponyfill_1 = __importDefault(require("fetch-ponyfill"));
@@ -126,6 +126,20 @@ function getElementRect(element) {
126
126
  };
127
127
  }
128
128
  exports.getElementRect = getElementRect;
129
+ /**
130
+ * Get non HTMLElement property in the window object
131
+ * @param {string} property - The window property to fetch the script plugin from.
132
+ * @returns {any | undefined} - The HTML Element property on the window object.
133
+ */
134
+ function getScriptPlugin(property) {
135
+ const obj = window[property];
136
+ if (typeof HTMLElement === 'object' ? obj instanceof HTMLElement : //DOM2
137
+ obj && typeof obj === 'object' && true && obj.nodeType === 1 && typeof obj.nodeName === 'string') {
138
+ return undefined;
139
+ }
140
+ return obj;
141
+ }
142
+ exports.getScriptPlugin = getScriptPlugin;
129
143
  /**
130
144
  * Determines the boolean value of a setting.
131
145
  * @param {string|boolean} value - A string or boolean value to convert to boolean.
package/lib/mjs/CDN.d.ts CHANGED
@@ -10,6 +10,7 @@ declare class CDN {
10
10
  bootstrap: string;
11
11
  bootstrap4: string;
12
12
  bootstrap5: string;
13
+ bootswatch: string;
13
14
  'bootstrap-icons': string;
14
15
  ckeditor: string;
15
16
  flatpickr: string;
package/lib/mjs/CDN.js CHANGED
@@ -10,9 +10,10 @@ class CDN {
10
10
  this.libs = {
11
11
  'js': '',
12
12
  'ace': '1.4.12',
13
- 'bootstrap': '5.3.2',
13
+ 'bootstrap': '5.3.3',
14
14
  'bootstrap4': '4.6.2',
15
- 'bootstrap5': '5.3.2',
15
+ 'bootstrap5': '5.3.3',
16
+ 'bootswatch': '5.3.3',
16
17
  'bootstrap-icons': '1.11.1',
17
18
  'ckeditor': '19.0.0',
18
19
  'flatpickr': '4.6.8',
@@ -60,7 +61,9 @@ class CDN {
60
61
  if (lib) {
61
62
  url += `/${lib}`;
62
63
  }
63
- if (version && version !== 'latest') {
64
+ // Only attach the version if this is the hosted cdn.
65
+ if (cdnUrl.includes('form.io') &&
66
+ version && version !== 'latest') {
64
67
  url += `/${version}`;
65
68
  }
66
69
  return url;
@@ -26,7 +26,7 @@ export class Formio {
26
26
  static addStyles(wrapper: any, href: any): Promise<void>;
27
27
  static submitDone(instance: any, submission: any): Promise<void>;
28
28
  static formioScript(script: any, builder: any): any;
29
- static addLibrary(wrapper: any, lib: any, name: any): Promise<void>;
29
+ static addLibrary(libWrapper: any, lib: any, name: any): Promise<void>;
30
30
  static addLoader(wrapper: any): Promise<void>;
31
31
  static init(element: any, options?: {}, builder?: boolean): Promise<any>;
32
32
  static afterCreate(instance: any, wrapper: any, readyEvent: any): Promise<any>;
package/lib/mjs/Embed.js CHANGED
@@ -79,6 +79,9 @@ export class Formio {
79
79
  }
80
80
  static createElement(type, attrs, children) {
81
81
  const element = document.createElement(type);
82
+ if (!attrs) {
83
+ return element;
84
+ }
82
85
  Object.keys(attrs).forEach(key => {
83
86
  element.setAttribute(key, attrs[key]);
84
87
  });
@@ -180,20 +183,21 @@ export class Formio {
180
183
  }
181
184
  return script;
182
185
  }
183
- static async addLibrary(wrapper, lib, name) {
186
+ static async addLibrary(libWrapper, lib, name) {
184
187
  if (!lib) {
185
188
  return;
186
189
  }
187
190
  if (lib.dependencies) {
188
191
  for (let i = 0; i < lib.dependencies.length; i++) {
189
- await Formio.addLibrary(wrapper, Formio.cdn.libs[lib.dependencies[i]]);
192
+ const libName = lib.dependencies[i];
193
+ await Formio.addLibrary(libWrapper, Formio.config.libs[libName], libName);
190
194
  }
191
195
  }
192
196
  if (lib.css) {
193
- await Formio.addStyles(wrapper, lib.css);
197
+ await Formio.addStyles((lib.global ? document.body : libWrapper), lib.css);
194
198
  }
195
199
  if (lib.js) {
196
- const module = await Formio.addScript(wrapper, lib.js, lib.use ? name : false);
200
+ const module = await Formio.addScript((lib.global ? document.body : libWrapper), lib.js, lib.use ? name : false);
197
201
  if (lib.use) {
198
202
  Formio.debug(`Using ${name}`);
199
203
  const options = lib.options || {};
@@ -203,6 +207,12 @@ export class Formio {
203
207
  Formio.use((typeof lib.use === 'function' ? lib.use(module) : module), options);
204
208
  }
205
209
  }
210
+ if (lib.globalStyle) {
211
+ const style = Formio.createElement('style');
212
+ style.type = 'text/css';
213
+ style.innerHTML = lib.globalStyle;
214
+ document.body.appendChild(style);
215
+ }
206
216
  }
207
217
  static async addLoader(wrapper) {
208
218
  wrapper.appendChild(Formio.createElement('div', {
@@ -231,7 +241,16 @@ export class Formio {
231
241
  use: true
232
242
  },
233
243
  fontawesome: {
234
- css: `${Formio.cdn['font-awesome']}/css/font-awesome.min.css`
244
+ // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need
245
+ // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.
246
+ css: `https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css`,
247
+ globalStyle: `@font-face {
248
+ font-family: 'FontAwesome';
249
+ src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?v=4.7.0');
250
+ src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
251
+ font-weight: normal;
252
+ font-style: normal;
253
+ }`
235
254
  },
236
255
  bootstrap4: {
237
256
  dependencies: ['fontawesome'],
@@ -242,9 +261,24 @@ export class Formio {
242
261
  css: `${Formio.cdn.bootstrap}/css/bootstrap.min.css`
243
262
  },
244
263
  'bootstrap-icons': {
245
- css: `${Formio.cdn['bootstrap-icons']}/css/bootstrap-icons.css`
264
+ // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need
265
+ // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.
266
+ css: 'https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.min.css',
267
+ globalStyle: `@font-face {
268
+ font-display: block;
269
+ font-family: "bootstrap-icons";
270
+ src: url("https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6") format("woff2"),
271
+ url("https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6") format("woff");
272
+ }`
246
273
  }
247
274
  };
275
+ // Add all bootswatch templates.
276
+ ['cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal', 'litera', 'lumen', 'lux', 'materia', 'minty', 'pulse', 'sandstone', 'simplex', 'sketchy', 'slate', 'solar', 'spacelab', 'superhero', 'united', 'yeti'].forEach((template) => {
277
+ Formio.config.libs[template] = {
278
+ dependencies: ['bootstrap-icons'],
279
+ css: `${Formio.cdn.bootswatch}/dist/${template}/bootstrap.min.css`
280
+ };
281
+ });
248
282
  const id = Formio.config.id || `formio-${Math.random().toString(36).substring(7)}`;
249
283
  // Create a new wrapper and add the element inside of a new wrapper.
250
284
  let wrapper = Formio.createElement('div', {
@@ -252,7 +286,7 @@ export class Formio {
252
286
  });
253
287
  element.parentNode.insertBefore(wrapper, element);
254
288
  // If we include the libraries, then we will attempt to run this in shadow dom.
255
- const useShadowDom = Formio.config.includeLibs && (typeof wrapper.attachShadow === 'function');
289
+ const useShadowDom = Formio.config.includeLibs && !Formio.config.noshadow && (typeof wrapper.attachShadow === 'function');
256
290
  if (useShadowDom) {
257
291
  wrapper = wrapper.attachShadow({
258
292
  mode: 'open'
package/lib/mjs/Formio.js CHANGED
@@ -107,4 +107,15 @@ FormioCore.createForm = FormioEmbed.createForm;
107
107
  FormioCore.submitDone = FormioEmbed.submitDone;
108
108
  FormioCore.addLibrary = FormioEmbed.addLibrary;
109
109
  FormioCore.addLoader = FormioEmbed.addLoader;
110
+ FormioCore.addToGlobal = (global) => {
111
+ if (typeof global === 'object' && !global.Formio) {
112
+ global.Formio = FormioCore;
113
+ }
114
+ };
115
+ if (typeof global !== 'undefined') {
116
+ FormioCore.addToGlobal(global);
117
+ }
118
+ if (typeof window !== 'undefined') {
119
+ FormioCore.addToGlobal(window);
120
+ }
110
121
  export { FormioCore as Formio };
@@ -24,9 +24,10 @@ export function embed(config = {}) {
24
24
  let scriptSrc = thisScript.src.replace(/^([^?]+).*/, '$1').split('/');
25
25
  scriptSrc.pop();
26
26
  let cdnSrc = '';
27
- if (scriptSrc[scriptSrc.length - 1] === 'js') {
27
+ if (['js', 'offline'].includes(scriptSrc[scriptSrc.length - 1])) {
28
28
  scriptSrc.pop();
29
29
  scriptSrc = cdnSrc = scriptSrc.join('/');
30
+ scriptSrc += '/js';
30
31
  }
31
32
  else {
32
33
  scriptSrc = scriptSrc.join('/');
@@ -45,6 +46,7 @@ export function embed(config = {}) {
45
46
  base: query.base || 'https://api.form.io',
46
47
  submit: query.submit,
47
48
  includeLibs: (query.libs === 'true' || query.libs === '1'),
49
+ noshadow: (query.shadow === 'false' || query.shadow === '0'),
48
50
  template: query.template || 'bootstrap',
49
51
  debug: debug,
50
52
  config: {},
@@ -445,7 +445,7 @@ declare class Webform extends NestedDataComponent {
445
445
  */
446
446
  submit(before?: boolean, options?: any): Promise<any>;
447
447
  submitUrl(URL: any, headers: any): void;
448
- triggerRecaptcha(): void;
448
+ triggerCaptcha(): void;
449
449
  _nosubmit: any;
450
450
  get conditions(): any;
451
451
  get variables(): any;
@@ -6,7 +6,7 @@ import i18nDefaults from "./i18n";
6
6
  import { Formio } from "./Formio";
7
7
  import Components from "./components/Components";
8
8
  import NestedDataComponent from "./components/_classes/nesteddata/NestedDataComponent";
9
- import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, searchComponents, convertStringToHTMLElement, getArrayFromComponentPath, } from "./utils/utils";
9
+ import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, } from "./utils/utils";
10
10
  import { eachComponent } from "./utils/formUtils";
11
11
  // Initialize the available forms.
12
12
  Formio.forms = {};
@@ -644,7 +644,7 @@ export default class Webform extends NestedDataComponent {
644
644
  const rebuild = this.rebuild() || Promise.resolve();
645
645
  return rebuild.then(() => {
646
646
  this.emit("formLoad", form);
647
- this.triggerRecaptcha();
647
+ this.triggerCaptcha();
648
648
  // Make sure to trigger onChange after a render event occurs to speed up form rendering.
649
649
  setTimeout(() => {
650
650
  this.onChange(flags);
@@ -742,7 +742,7 @@ export default class Webform extends NestedDataComponent {
742
742
  }
743
743
  const draft = fastCloneDeep(this.submission);
744
744
  draft.state = "draft";
745
- if (!this.savingDraft) {
745
+ if (!this.savingDraft && !this.submitting) {
746
746
  this.emit("saveDraftBegin");
747
747
  this.savingDraft = true;
748
748
  this.formio
@@ -820,7 +820,7 @@ export default class Webform extends NestedDataComponent {
820
820
  };
821
821
  }
822
822
  // Metadata needs to be available before setValue
823
- this._submission.metadata = submission.metadata || {};
823
+ this._submission.metadata = submission.metadata ? _.cloneDeep(submission.metadata) : {};
824
824
  this.editing = !!submission._id;
825
825
  // Set the timezone in the options if available.
826
826
  if (!this.options.submissionTimezone &&
@@ -1504,16 +1504,18 @@ export default class Webform extends NestedDataComponent {
1504
1504
  return console.warn("You should add a URL to this button.");
1505
1505
  }
1506
1506
  }
1507
- triggerRecaptcha() {
1507
+ triggerCaptcha() {
1508
1508
  if (!this || !this.components) {
1509
1509
  return;
1510
1510
  }
1511
- const recaptchaComponent = searchComponents(this.components, {
1512
- "component.type": "recaptcha",
1513
- "component.eventType": "formLoad",
1511
+ const captchaComponent = [];
1512
+ eachComponent(this.components, (component) => {
1513
+ if (/^(re)?captcha$/.test(component.type) && component.component.eventType === 'formLoad') {
1514
+ captchaComponent.push(component);
1515
+ }
1514
1516
  });
1515
- if (recaptchaComponent.length > 0) {
1516
- recaptchaComponent[0].verify(`${this.form.name ? this.form.name : "form"}Load`);
1517
+ if (captchaComponent.length > 0) {
1518
+ captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
1517
1519
  }
1518
1520
  }
1519
1521
  set nosubmit(value) {
@@ -73,7 +73,7 @@ export default class WebformBuilder extends Component {
73
73
  onDrop(element: any, target: any, source: any, sibling: any): any;
74
74
  setForm(form: any): any;
75
75
  keyboardActionsEnabled: any;
76
- populateRecaptchaSettings(form: any): void;
76
+ populateCaptchaSettings(form: any): void;
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;
@@ -472,7 +472,7 @@ export default class WebformBuilder extends Component {
472
472
  }
473
473
  attach(element) {
474
474
  this.on('change', (form) => {
475
- this.populateRecaptchaSettings(form);
475
+ this.populateCaptchaSettings(form);
476
476
  this.webform.setAlert(false);
477
477
  });
478
478
  return super.attach(element).then(() => {
@@ -923,24 +923,24 @@ export default class WebformBuilder extends Component {
923
923
  }
924
924
  return Promise.resolve(form);
925
925
  }
926
- populateRecaptchaSettings(form) {
927
- //populate isEnabled for recaptcha form settings
928
- let isRecaptchaEnabled = false;
926
+ populateCaptchaSettings(form) {
927
+ //populate isEnabled for captcha form settings
928
+ let isCaptchaEnabled = false;
929
929
  if (this.form.components) {
930
930
  eachComponent(form.components, component => {
931
- if (isRecaptchaEnabled) {
931
+ if (isCaptchaEnabled) {
932
932
  return;
933
933
  }
934
- if (component.type === 'recaptcha') {
935
- isRecaptchaEnabled = true;
934
+ if (component.type === 'captcha') {
935
+ isCaptchaEnabled = true;
936
936
  return false;
937
937
  }
938
938
  });
939
- if (isRecaptchaEnabled) {
940
- _.set(form, 'settings.recaptcha.isEnabled', true);
939
+ if (isCaptchaEnabled) {
940
+ _.set(form, 'settings.captcha.isEnabled', true);
941
941
  }
942
- else if (_.get(form, 'settings.recaptcha.isEnabled')) {
943
- _.set(form, 'settings.recaptcha.isEnabled', false);
942
+ else if (_.get(form, 'settings.captcha.isEnabled')) {
943
+ _.set(form, 'settings.captcha.isEnabled', false);
944
944
  }
945
945
  }
946
946
  }
@@ -1104,14 +1104,10 @@ export default class WebformBuilder extends Component {
1104
1104
  let hasInvalidComponents = false;
1105
1105
  this.webform.everyComponent((comp) => {
1106
1106
  const path = comp.path;
1107
- const errors = comp.visibleErrors || [];
1108
1107
  if (repeatablePaths.includes(path)) {
1109
- comp.setCustomValidity(`API Key is not unique: ${comp.key}`);
1108
+ comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
1110
1109
  hasInvalidComponents = true;
1111
1110
  }
1112
- else if (errors.length && errors[0].message?.startsWith('API Key is not unique')) {
1113
- comp.setCustomValidity('');
1114
- }
1115
1111
  });
1116
1112
  this.emit('builderFormValidityChange', hasInvalidComponents);
1117
1113
  }