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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) 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 +26 -37
  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 +30 -41
  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 +3 -3
  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/Formio.js +11 -0
  23. package/lib/cjs/Webform.d.ts +1 -1
  24. package/lib/cjs/Webform.js +11 -9
  25. package/lib/cjs/WebformBuilder.d.ts +1 -1
  26. package/lib/cjs/WebformBuilder.js +12 -17
  27. package/lib/cjs/components/_classes/component/Component.js +2 -2
  28. package/lib/cjs/components/button/Button.d.ts +1 -1
  29. package/lib/cjs/components/button/Button.js +7 -7
  30. package/lib/cjs/components/radio/Radio.d.ts +1 -1
  31. package/lib/cjs/components/radio/Radio.js +5 -3
  32. package/lib/cjs/components/recaptcha/ReCaptcha.d.ts +1 -8
  33. package/lib/cjs/components/recaptcha/ReCaptcha.form.d.ts +2 -1
  34. package/lib/cjs/components/recaptcha/ReCaptcha.form.js +3 -2
  35. package/lib/cjs/components/recaptcha/ReCaptcha.js +1 -8
  36. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.d.ts +33 -2
  37. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +13 -2
  38. package/lib/cjs/components/select/Select.js +6 -1
  39. package/lib/cjs/components/select/editForm/Select.edit.data.js +16 -2
  40. package/lib/cjs/components/select/fixtures/comp22.js +1 -1
  41. package/lib/cjs/components/select/fixtures/comp23.d.ts +58 -0
  42. package/lib/cjs/components/select/fixtures/comp23.js +49 -0
  43. package/lib/cjs/components/select/fixtures/comp24.d.ts +47 -0
  44. package/lib/cjs/components/select/fixtures/comp24.js +40 -0
  45. package/lib/cjs/components/select/fixtures/index.d.ts +3 -1
  46. package/lib/cjs/components/select/fixtures/index.js +5 -1
  47. package/lib/cjs/components/selectboxes/SelectBoxes.js +4 -1
  48. package/lib/cjs/translations/en.d.ts +1 -0
  49. package/lib/cjs/translations/en.js +1 -0
  50. package/lib/cjs/utils/utils.d.ts +6 -0
  51. package/lib/cjs/utils/utils.js +16 -2
  52. package/lib/mjs/Formio.js +11 -0
  53. package/lib/mjs/Webform.d.ts +1 -1
  54. package/lib/mjs/Webform.js +12 -10
  55. package/lib/mjs/WebformBuilder.d.ts +1 -1
  56. package/lib/mjs/WebformBuilder.js +12 -16
  57. package/lib/mjs/components/_classes/component/Component.js +3 -3
  58. package/lib/mjs/components/button/Button.d.ts +1 -1
  59. package/lib/mjs/components/button/Button.js +7 -7
  60. package/lib/mjs/components/radio/Radio.d.ts +1 -1
  61. package/lib/mjs/components/radio/Radio.js +5 -3
  62. package/lib/mjs/components/recaptcha/ReCaptcha.d.ts +1 -8
  63. package/lib/mjs/components/recaptcha/ReCaptcha.form.d.ts +2 -1
  64. package/lib/mjs/components/recaptcha/ReCaptcha.form.js +3 -2
  65. package/lib/mjs/components/recaptcha/ReCaptcha.js +1 -8
  66. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.d.ts +33 -2
  67. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +13 -2
  68. package/lib/mjs/components/select/Select.js +6 -1
  69. package/lib/mjs/components/select/editForm/Select.edit.data.js +16 -2
  70. package/lib/mjs/components/select/fixtures/comp22.js +1 -1
  71. package/lib/mjs/components/select/fixtures/comp23.d.ts +58 -0
  72. package/lib/mjs/components/select/fixtures/comp23.js +47 -0
  73. package/lib/mjs/components/select/fixtures/comp24.d.ts +47 -0
  74. package/lib/mjs/components/select/fixtures/comp24.js +38 -0
  75. package/lib/mjs/components/select/fixtures/index.d.ts +3 -1
  76. package/lib/mjs/components/select/fixtures/index.js +3 -1
  77. package/lib/mjs/components/selectboxes/SelectBoxes.js +4 -1
  78. package/lib/mjs/translations/en.d.ts +1 -0
  79. package/lib/mjs/translations/en.js +1 -0
  80. package/lib/mjs/utils/utils.d.ts +6 -0
  81. package/lib/mjs/utils/utils.js +13 -0
  82. package/package.json +4 -4
@@ -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/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 };
@@ -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
  }
@@ -6,7 +6,7 @@ import isMobile from 'ismobilejs';
6
6
  import { processOne, processOneSync, validateProcessInfo } from '@formio/core/process';
7
7
  import { Formio } from '../../../Formio';
8
8
  import * as FormioUtils from '../../../utils/utils';
9
- import { fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone } from '../../../utils/utils';
9
+ import { fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone, getScriptPlugin } from '../../../utils/utils';
10
10
  import Element from '../../../Element';
11
11
  import ComponentModal from '../componentModal/ComponentModal';
12
12
  import Widgets from '../../../widgets';
@@ -3463,7 +3463,7 @@ Component.requireLibrary = function (name, property, src, polling) {
3463
3463
  }.bind(Component.externalLibraries[name]);
3464
3464
  }
3465
3465
  // See if the plugin already exists.
3466
- const plugin = _.get(window, property);
3466
+ const plugin = getScriptPlugin(property);
3467
3467
  if (plugin) {
3468
3468
  Component.externalLibraries[name].resolve(plugin);
3469
3469
  }
@@ -3506,7 +3506,7 @@ Component.requireLibrary = function (name, property, src, polling) {
3506
3506
  // if no callback is provided, then check periodically for the script.
3507
3507
  if (polling) {
3508
3508
  setTimeout(function checkLibrary() {
3509
- const plugin = _.get(window, property);
3509
+ const plugin = getScriptPlugin(property);
3510
3510
  if (plugin) {
3511
3511
  Component.externalLibraries[name].resolve(plugin);
3512
3512
  }
@@ -31,6 +31,6 @@ export default class ButtonComponent extends Field {
31
31
  openOauth(settings: any): void;
32
32
  get oauthComponentPath(): any;
33
33
  focus(): void;
34
- triggerReCaptcha(): void;
34
+ triggerCaptcha(): void;
35
35
  }
36
36
  import Field from '../_classes/field/Field';
@@ -267,7 +267,7 @@ export default class ButtonComponent extends Field {
267
267
  super.detach();
268
268
  }
269
269
  onClick(event) {
270
- this.triggerReCaptcha();
270
+ this.triggerCaptcha();
271
271
  // Don't click if disabled or in builder mode.
272
272
  if (this.disabled || this.options.attachMode === 'builder') {
273
273
  return;
@@ -453,20 +453,20 @@ export default class ButtonComponent extends Field {
453
453
  this.refs.button.focus();
454
454
  }
455
455
  }
456
- triggerReCaptcha() {
456
+ triggerCaptcha() {
457
457
  if (!this.root) {
458
458
  return;
459
459
  }
460
- let recaptchaComponent;
460
+ let captchaComponent;
461
461
  this.root.everyComponent((component) => {
462
- if (component.component.type === 'recaptcha' &&
462
+ if (/^(re)?captcha$/.test(component.component.type) &&
463
463
  component.component.eventType === 'buttonClick' &&
464
464
  component.component.buttonKey === this.component.key) {
465
- recaptchaComponent = component;
465
+ captchaComponent = component;
466
466
  }
467
467
  });
468
- if (recaptchaComponent) {
469
- recaptchaComponent.verify(`${this.component.key}Click`);
468
+ if (captchaComponent) {
469
+ captchaComponent.verify(`${this.component.key}Click`);
470
470
  }
471
471
  }
472
472
  }
@@ -48,7 +48,7 @@ export default class RadioComponent extends ListComponent {
48
48
  detach(element: any): void;
49
49
  validateValueProperty(): boolean;
50
50
  validateValueAvailability(setting: any, value: any): boolean;
51
- getValueAsString(value: any): any;
51
+ getValueAsString(value: any, options?: {}): any;
52
52
  setValueAt(index: any, value: any): void;
53
53
  loadItems(url: any, search: any, headers: any, options: any, method: any, body: any): void;
54
54
  loadItemsFromMetadata(): void;
@@ -226,17 +226,19 @@ export default class RadioComponent extends ListComponent {
226
226
  }
227
227
  return false;
228
228
  }
229
- getValueAsString(value) {
229
+ getValueAsString(value, options = {}) {
230
230
  if (_.isObject(value)) {
231
231
  value = JSON.stringify(value);
232
232
  }
233
233
  else if (!_.isString(value)) {
234
234
  value = _.toString(value);
235
235
  }
236
- if (this.component.dataSrc !== 'values') {
236
+ const isModalPreviewWithUrlDataSource = options.modalPreview && this.component.dataSrc === 'url';
237
+ if (this.component.dataSrc !== 'values' && !isModalPreviewWithUrlDataSource) {
237
238
  return value;
238
239
  }
239
- const option = _.find(this.component.values, (v) => v.value === value);
240
+ const values = isModalPreviewWithUrlDataSource ? this.loadedOptions : this.component.values;
241
+ const option = _.find(values, (v) => v.value === value);
240
242
  if (!value) {
241
243
  return _.get(option, 'label', '');
242
244
  }
@@ -1,12 +1,5 @@
1
1
  export default class ReCaptchaComponent extends Component {
2
- static get builderInfo(): {
3
- title: string;
4
- group: string;
5
- icon: string;
6
- documentation: string;
7
- weight: number;
8
- schema: any;
9
- };
2
+ static get builderInfo(): {};
10
3
  static savedValueTypes(): never[];
11
4
  render(): string;
12
5
  recaptchaResult: any;
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * The Edit Form function.
3
+ * @param {...any} extend - The components that extend the edit form.
3
4
  * @returns {import('@formio/core').Component[]} - The edit form components.
4
5
  */
5
- export default function _default(): import('@formio/core').Component[];
6
+ export default function _default(...extend: any[]): import('@formio/core').Component[];
@@ -2,9 +2,10 @@ import Components from '../Components';
2
2
  import ReCaptchaEditDisplay from './editForm/ReCaptcha.edit.display';
3
3
  /**
4
4
  * The Edit Form function.
5
+ * @param {...any} extend - The components that extend the edit form.
5
6
  * @returns {import('@formio/core').Component[]} - The edit form components.
6
7
  */
7
- export default function () {
8
+ export default function (...extend) {
8
9
  return Components.baseEditForm([
9
10
  {
10
11
  key: 'display',
@@ -26,5 +27,5 @@ export default function () {
26
27
  key: 'logic',
27
28
  ignore: true
28
29
  },
29
- ]);
30
+ ], ...extend);
30
31
  }
@@ -12,14 +12,7 @@ export default class ReCaptchaComponent extends Component {
12
12
  }, ...extend);
13
13
  }
14
14
  static get builderInfo() {
15
- return {
16
- title: 'reCAPTCHA',
17
- group: 'premium',
18
- icon: 'refresh',
19
- documentation: '/userguide/form-building/premium-components#recaptcha',
20
- weight: 40,
21
- schema: ReCaptchaComponent.schema()
22
- };
15
+ return {};
23
16
  }
24
17
  static savedValueTypes() {
25
18
  return [];
@@ -1,4 +1,21 @@
1
1
  declare const _default: ({
2
+ key: string;
3
+ weight: number;
4
+ type: string;
5
+ tag: string;
6
+ className: string;
7
+ content: string;
8
+ label?: undefined;
9
+ tooltip?: undefined;
10
+ values?: undefined;
11
+ validate?: undefined;
12
+ input?: undefined;
13
+ dataSrc?: undefined;
14
+ valueProperty?: undefined;
15
+ customConditional?: undefined;
16
+ data?: undefined;
17
+ ignore?: undefined;
18
+ } | {
2
19
  key: string;
3
20
  label: string;
4
21
  tooltip: string;
@@ -7,7 +24,13 @@ declare const _default: ({
7
24
  label: string;
8
25
  value: string;
9
26
  }[];
27
+ validate: {
28
+ required: boolean;
29
+ };
10
30
  weight: number;
31
+ tag?: undefined;
32
+ className?: undefined;
33
+ content?: undefined;
11
34
  input?: undefined;
12
35
  dataSrc?: undefined;
13
36
  valueProperty?: undefined;
@@ -27,16 +50,24 @@ declare const _default: ({
27
50
  data: {
28
51
  custom(context: any): any[];
29
52
  };
53
+ tag?: undefined;
54
+ className?: undefined;
55
+ content?: undefined;
30
56
  values?: undefined;
57
+ validate?: undefined;
31
58
  ignore?: undefined;
32
59
  } | {
33
60
  key: string;
34
61
  ignore: boolean;
62
+ weight?: undefined;
63
+ type?: undefined;
64
+ tag?: undefined;
65
+ className?: undefined;
66
+ content?: undefined;
35
67
  label?: undefined;
36
68
  tooltip?: undefined;
37
- type?: undefined;
38
69
  values?: undefined;
39
- weight?: undefined;
70
+ validate?: undefined;
40
71
  input?: undefined;
41
72
  dataSrc?: undefined;
42
73
  valueProperty?: undefined;
@@ -1,9 +1,17 @@
1
1
  import { getContextButtons } from '../../../utils/utils';
2
2
  export default [
3
+ {
4
+ key: 'recaptchaInfo',
5
+ weight: -10,
6
+ type: 'htmlelement',
7
+ tag: 'div',
8
+ className: 'alert alert-danger',
9
+ content: 'This component has been deprecated and will be removed. Use the CAPTCHA component instead.',
10
+ },
3
11
  {
4
12
  key: 'eventType',
5
13
  label: 'Type of event',
6
- tooltip: 'Specify type of event that this reCAPTCHA would react to',
14
+ tooltip: 'Specify type of event that this CAPTCHA would react to. If Button Click is selected, then the CAPTCHA widget will be displayed and verification will occur after clicking on the button.',
7
15
  type: 'radio',
8
16
  values: [
9
17
  {
@@ -15,6 +23,9 @@ export default [
15
23
  value: 'buttonClick'
16
24
  }
17
25
  ],
26
+ validate: {
27
+ required: true
28
+ },
18
29
  weight: 650
19
30
  },
20
31
  {
@@ -24,7 +35,7 @@ export default [
24
35
  key: 'buttonKey',
25
36
  dataSrc: 'custom',
26
37
  valueProperty: 'value',
27
- tooltip: 'Specify key of button on this form that this reCAPTCHA should react to',
38
+ tooltip: 'Specify key of button on this form that this CAPTCHA should react to',
28
39
  weight: 660,
29
40
  customConditional(context) {
30
41
  return context.data.eventType === 'buttonClick';
@@ -226,9 +226,10 @@ export default class SelectComponent extends ListComponent {
226
226
  }
227
227
  selectValueAndLabel(data) {
228
228
  const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));
229
+ const readOnlyResourceLabelData = this.options.readOnly && (this.component.dataSrc === 'resource' || this.component.dataSrc === 'url') && this.selectData;
229
230
  return {
230
231
  value,
231
- label: this.itemTemplate((this.isEntireObjectDisplay() && !_.isObject(data.data)) ? { data: data } : data, value)
232
+ label: this.itemTemplate((this.isEntireObjectDisplay() && !_.isObject(data.data)) ? { data: data } : readOnlyResourceLabelData || data, value)
232
233
  };
233
234
  }
234
235
  itemTemplate(data, value) {
@@ -1492,6 +1493,10 @@ export default class SelectComponent extends ListComponent {
1492
1493
  }
1493
1494
  asString(value, options = {}) {
1494
1495
  value = value ?? this.getValue();
1496
+ if (options.modalPreview && this.selectData) {
1497
+ const { label } = this.selectValueAndLabel(value);
1498
+ return label;
1499
+ }
1495
1500
  //need to convert values to strings to be able to compare values with available options that are strings
1496
1501
  const convertToString = (data, valueProperty) => {
1497
1502
  if (valueProperty) {
@@ -1,14 +1,28 @@
1
1
  import _ from 'lodash';
2
2
  import { eachComponent } from '../../../utils/utils';
3
- const calculateSelectData = (context) => {
3
+ const calculateSingleSelectData = (context, defaultValue) => {
4
4
  const { instance, data } = context;
5
- const rawDefaultValue = instance.downloadedResources.find(resource => _.get(resource, data.valueProperty) === instance.getValue());
5
+ const rawDefaultValue = instance.downloadedResources.find(resource => _.get(resource, data.valueProperty) === defaultValue);
6
6
  const options = { data: {}, noeval: true };
7
7
  instance.interpolate(data.template, {
8
8
  item: rawDefaultValue,
9
9
  }, options);
10
10
  return options.data.item;
11
11
  };
12
+ const calculateSelectData = (context) => {
13
+ const { instance } = context;
14
+ const defaultValue = instance.getValue();
15
+ if (instance.component.multiple) {
16
+ const multiSelectData = {};
17
+ (defaultValue ?? []).forEach((defaultValueItem) => {
18
+ multiSelectData[defaultValueItem] = calculateSingleSelectData(context, defaultValueItem);
19
+ });
20
+ return multiSelectData;
21
+ }
22
+ else {
23
+ return calculateSingleSelectData(context, defaultValue);
24
+ }
25
+ };
12
26
  const setSelectData = (context) => {
13
27
  // Wait before downloadedResources will be set
14
28
  setTimeout(() => {
@@ -6,7 +6,7 @@ export default {
6
6
  display: 'form',
7
7
  components: [{
8
8
  label: 'Select',
9
- widget: 'choicesjs',
9
+ widget: 'html5',
10
10
  tableView: true,
11
11
  dataSrc: 'url',
12
12
  data: {