@formio/js 5.0.0-rc.43 → 5.0.0-rc.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. package/dist/formio.embed.js +1 -1
  2. package/dist/formio.embed.min.js +1 -1
  3. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  4. package/dist/formio.form.js +602 -580
  5. package/dist/formio.form.min.js +1 -1
  6. package/dist/formio.form.min.js.LICENSE.txt +1 -11
  7. package/dist/formio.full.js +605 -583
  8. package/dist/formio.full.min.js +1 -1
  9. package/dist/formio.full.min.js.LICENSE.txt +1 -11
  10. package/dist/formio.js +10 -11
  11. package/dist/formio.min.js +1 -1
  12. package/dist/formio.min.js.LICENSE.txt +1 -1
  13. package/dist/formio.utils.js +1 -1
  14. package/dist/formio.utils.min.js +1 -1
  15. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  16. package/lib/cjs/Element.js +2 -0
  17. package/lib/cjs/Form.js +3 -1
  18. package/lib/cjs/Webform.js +93 -15
  19. package/lib/cjs/WebformBuilder.js +8 -8
  20. package/lib/cjs/components/_classes/component/Component.js +25 -8
  21. package/lib/cjs/components/_classes/componentModal/ComponentModal.js +5 -4
  22. package/lib/cjs/components/_classes/input/Input.js +1 -1
  23. package/lib/cjs/components/_classes/multivalue/Multivalue.js +1 -1
  24. package/lib/cjs/components/_classes/nested/NestedComponent.js +4 -2
  25. package/lib/cjs/components/datagrid/DataGrid.js +1 -1
  26. package/lib/cjs/components/editgrid/EditGrid.js +3 -3
  27. package/lib/cjs/components/form/Form.js +1 -1
  28. package/lib/cjs/components/html/HTML.js +2 -2
  29. package/lib/cjs/components/html/fixtures/comp3.js +40 -0
  30. package/lib/cjs/components/html/fixtures/index.js +3 -1
  31. package/lib/cjs/components/radio/Radio.js +29 -10
  32. package/lib/cjs/components/radio/editForm/Radio.edit.data.js +20 -0
  33. package/lib/cjs/components/radio/fixtures/comp11.js +85 -0
  34. package/lib/cjs/components/radio/fixtures/index.js +3 -1
  35. package/lib/cjs/components/select/Select.js +3 -0
  36. package/lib/cjs/components/select/editForm/Select.edit.data.js +63 -1
  37. package/lib/cjs/components/signature/Signature.js +1 -1
  38. package/lib/cjs/components/textarea/TextArea.js +1 -1
  39. package/lib/cjs/formio.form.js +5 -1
  40. package/lib/cjs/providers/storage/s3.js +29 -1
  41. package/lib/mjs/Element.js +2 -0
  42. package/lib/mjs/Form.js +3 -1
  43. package/lib/mjs/Webform.js +98 -16
  44. package/lib/mjs/WebformBuilder.js +8 -8
  45. package/lib/mjs/components/_classes/component/Component.js +25 -8
  46. package/lib/mjs/components/_classes/componentModal/ComponentModal.js +5 -4
  47. package/lib/mjs/components/_classes/input/Input.js +1 -1
  48. package/lib/mjs/components/_classes/multivalue/Multivalue.js +1 -1
  49. package/lib/mjs/components/_classes/nested/NestedComponent.js +4 -2
  50. package/lib/mjs/components/datagrid/DataGrid.js +1 -1
  51. package/lib/mjs/components/editgrid/EditGrid.js +3 -3
  52. package/lib/mjs/components/form/Form.js +1 -1
  53. package/lib/mjs/components/html/HTML.js +2 -2
  54. package/lib/mjs/components/html/fixtures/comp3.js +38 -0
  55. package/lib/mjs/components/html/fixtures/index.js +2 -1
  56. package/lib/mjs/components/radio/Radio.js +29 -10
  57. package/lib/mjs/components/radio/editForm/Radio.edit.data.js +20 -0
  58. package/lib/mjs/components/radio/fixtures/comp11.js +83 -0
  59. package/lib/mjs/components/radio/fixtures/index.js +2 -1
  60. package/lib/mjs/components/select/Select.js +3 -0
  61. package/lib/mjs/components/select/editForm/Select.edit.data.js +59 -1
  62. package/lib/mjs/components/signature/Signature.js +1 -1
  63. package/lib/mjs/components/textarea/TextArea.js +1 -1
  64. package/lib/mjs/formio.form.js +3 -1
  65. package/lib/mjs/providers/storage/s3.js +6 -1
  66. package/package.json +7 -8
  67. package/types/builders.d.ts +0 -7
  68. package/types/components/_classes/component/component.d.ts +0 -175
  69. package/types/components/_classes/componentmodal/componentmodal.d.ts +0 -31
  70. package/types/components/_classes/field/field.d.ts +0 -5
  71. package/types/components/_classes/input/input.d.ts +0 -30
  72. package/types/components/_classes/multivalue/multivalue.d.ts +0 -16
  73. package/types/components/_classes/nested/nestedComponent.d.ts +0 -61
  74. package/types/components/_classes/widgetcomponent/widgetComponent.d.ts +0 -6
  75. package/types/components/components.d.ts +0 -69
  76. package/types/components/schema.d.ts +0 -174
  77. package/types/displays.d.ts +0 -7
  78. package/types/element.d.ts +0 -45
  79. package/types/eventEmitter.d.ts +0 -3
  80. package/types/form.d.ts +0 -18
  81. package/types/formbuilder.d.ts +0 -6
  82. package/types/formio.d.ts +0 -1236
  83. package/types/index.d.ts +0 -18
  84. package/types/licenses.d.ts +0 -7
  85. package/types/providers.d.ts +0 -8
  86. package/types/rulesEngine/conjunctions.d.ts +0 -7
  87. package/types/rulesEngine/operators.d.ts +0 -7
  88. package/types/rulesEngine/quckRules.d.ts +0 -7
  89. package/types/rulesEngine/rules.d.ts +0 -7
  90. package/types/rulesEngine/transformers.d.ts +0 -7
  91. package/types/rulesEngine/valueSources.d.ts +0 -7
  92. package/types/templates.d.ts +0 -8
  93. package/types/utils.d.ts +0 -157
  94. package/types/widgets.d.ts +0 -4
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ title: 'Test',
5
+ name: 'test',
6
+ path: 'test',
7
+ type: 'form',
8
+ display: 'form',
9
+ components: [
10
+ {
11
+ label: 'Radio',
12
+ optionsLabelPosition: 'right',
13
+ inline: false,
14
+ tableView: false,
15
+ values: [
16
+ {
17
+ label: '0',
18
+ value: '0',
19
+ shortcut: ''
20
+ },
21
+ {
22
+ label: '1',
23
+ value: '1',
24
+ shortcut: ''
25
+ }
26
+ ],
27
+ key: 'radioNumber',
28
+ type: 'radio',
29
+ dataType: 'number',
30
+ input: true
31
+ },
32
+ {
33
+ label: 'Radio',
34
+ optionsLabelPosition: 'right',
35
+ inline: false,
36
+ tableView: false,
37
+ values: [
38
+ {
39
+ label: '0',
40
+ value: '0',
41
+ shortcut: ''
42
+ },
43
+ {
44
+ label: '1',
45
+ value: '1',
46
+ shortcut: ''
47
+ }
48
+ ],
49
+ key: 'radioString',
50
+ dataType: 'string',
51
+ type: 'radio',
52
+ input: true
53
+ },
54
+ {
55
+ label: 'Radio',
56
+ optionsLabelPosition: 'right',
57
+ inline: false,
58
+ tableView: false,
59
+ values: [
60
+ {
61
+ label: 'true',
62
+ value: 'true',
63
+ shortcut: ''
64
+ },
65
+ {
66
+ label: 'false',
67
+ value: 'false',
68
+ shortcut: ''
69
+ }
70
+ ],
71
+ key: 'radioBoolean',
72
+ dataType: 'boolean',
73
+ type: 'radio',
74
+ input: true
75
+ },
76
+ {
77
+ type: 'button',
78
+ label: 'Submit',
79
+ key: 'submit',
80
+ disableOnInvalid: true,
81
+ input: true,
82
+ tableView: false
83
+ }
84
+ ]
85
+ };
@@ -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.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp3 = exports.comp2 = exports.comp1 = void 0;
6
+ exports.comp11 = exports.comp10 = exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp4 = exports.comp3 = exports.comp2 = exports.comp1 = 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"));
@@ -24,3 +24,5 @@ const comp9_1 = __importDefault(require("./comp9"));
24
24
  exports.comp9 = comp9_1.default;
25
25
  const comp10_1 = __importDefault(require("./comp10"));
26
26
  exports.comp10 = comp10_1.default;
27
+ const comp11_1 = __importDefault(require("./comp11"));
28
+ exports.comp11 = comp11_1.default;
@@ -217,6 +217,9 @@ class SelectComponent extends ListComponent_1.default {
217
217
  }
218
218
  return super.shouldLoad;
219
219
  }
220
+ get selectData() {
221
+ return this.component.selectData || super.selectData;
222
+ }
220
223
  isEntireObjectDisplay() {
221
224
  return this.component.dataSrc === 'resource' && this.valueProperty === 'data';
222
225
  }
@@ -1,6 +1,36 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const lodash_1 = __importDefault(require("lodash"));
3
7
  const utils_1 = require("../../../utils/utils");
8
+ const calculateSelectData = (context) => {
9
+ const { instance, data } = context;
10
+ const rawDefaultValue = instance.downloadedResources.find(resource => lodash_1.default.get(resource, data.valueProperty) === instance.getValue());
11
+ const options = { data: {}, noeval: true };
12
+ instance.interpolate(data.template, {
13
+ item: rawDefaultValue,
14
+ }, options);
15
+ return options.data.item;
16
+ };
17
+ const setSelectData = (context) => {
18
+ // Wait before downloadedResources will be set
19
+ setTimeout(() => {
20
+ var _a;
21
+ const { instance, data } = context;
22
+ const selectDataComponent = instance === null || instance === void 0 ? void 0 : instance.root.getComponent('selectData');
23
+ // nothing can set if don't have downloaded resources
24
+ if (!selectDataComponent || !instance.getValue() || !((_a = instance.downloadedResources) === null || _a === void 0 ? void 0 : _a.length)) {
25
+ return;
26
+ }
27
+ // if valueProperty is not provided, we have entire object
28
+ const shouldCalculateUrlData = data.dataSrc === 'url' && data.data.url && data.valueProperty;
29
+ const shouldCalculateResourceData = data.dataSrc === 'resource' && data.data.resource && data.valueProperty;
30
+ const newValue = shouldCalculateUrlData || shouldCalculateResourceData ? calculateSelectData(context) : undefined;
31
+ selectDataComponent.setValue(newValue);
32
+ }, 0);
33
+ };
4
34
  exports.default = [
5
35
  {
6
36
  key: 'dataSrc',
@@ -625,5 +655,37 @@ exports.default = [
625
655
  key: 'useExactSearch',
626
656
  label: 'Use exact search',
627
657
  tooltip: 'Disables search algorithm threshold.',
628
- }
658
+ },
659
+ {
660
+ key: 'defaultValue',
661
+ onSetItems(component) {
662
+ setSelectData(component.evalContext());
663
+ },
664
+ onChange(context) {
665
+ if (context && context.flags && context.flags.modified) {
666
+ setSelectData(context);
667
+ }
668
+ },
669
+ },
670
+ {
671
+ key: 'selectData',
672
+ conditional: {
673
+ json: { 'and': [
674
+ { '!==': [{ var: 'data.valueProperty' }, null] },
675
+ { '!==': [{ var: 'data.valueProperty' }, ''] },
676
+ ] },
677
+ },
678
+ },
679
+ {
680
+ key: 'template',
681
+ onChange(context) {
682
+ if (context && context.flags && context.flags.modified) {
683
+ const defaultValueComponent = context.instance.root.getComponent('defaultValue');
684
+ if (!defaultValueComponent) {
685
+ return;
686
+ }
687
+ setSelectData(defaultValueComponent.evalContext());
688
+ }
689
+ },
690
+ },
629
691
  ];
@@ -174,7 +174,7 @@ class SignatureComponent extends Input_1.default {
174
174
  getModalPreviewTemplate() {
175
175
  return this.renderTemplate('modalPreview', {
176
176
  previewText: this.dataValue ?
177
- `<img src=${this.dataValue} ref='openModal' style="width: 100%;height: 100%;" />` :
177
+ `<img src=${this.dataValue} ${this._referenceAttributeName}='openModal' style="width: 100%;height: 100%;" />` :
178
178
  this.t('Click to Sign')
179
179
  });
180
180
  }
@@ -62,7 +62,7 @@ class TextAreaComponent extends TextField_1.default {
62
62
  info.content = value;
63
63
  if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) {
64
64
  const elementStyle = this.info.attr.style || '';
65
- const children = `<div ref="input" class="formio-editor-read-only-content" ${elementStyle ? `style='${elementStyle}'` : ''}></div>`;
65
+ const children = `<div ${this._referenceAttributeName}="input" class="formio-editor-read-only-content" ${elementStyle ? `style='${elementStyle}'` : ''}></div>`;
66
66
  return this.renderTemplate('well', {
67
67
  children,
68
68
  nestedKey: this.key,
@@ -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.Licenses = exports.Formio = exports.Form = exports.Utils = exports.Templates = exports.Widgets = exports.Providers = exports.Displays = exports.Components = exports.useModule = exports.registerModule = void 0;
6
+ exports.Webform = exports.EventEmitter = exports.Licenses = exports.Formio = exports.Form = exports.Utils = exports.Templates = exports.Widgets = exports.Providers = exports.Displays = exports.Components = exports.useModule = exports.registerModule = void 0;
7
7
  const lodash_1 = __importDefault(require("lodash"));
8
8
  const Formio_1 = require("./Formio");
9
9
  Object.defineProperty(exports, "Formio", { enumerable: true, get: function () { return Formio_1.Formio; } });
@@ -25,6 +25,10 @@ exports.Utils = utils_1.default;
25
25
  const Evaluator_1 = __importDefault(require("./utils/Evaluator"));
26
26
  const licenses_1 = __importDefault(require("./licenses"));
27
27
  exports.Licenses = licenses_1.default;
28
+ const EventEmitter_1 = __importDefault(require("./EventEmitter"));
29
+ exports.EventEmitter = EventEmitter_1.default;
30
+ const Webform_1 = __importDefault(require("./Webform"));
31
+ exports.Webform = Webform_1.default;
28
32
  Formio_1.Formio.loadModules = (path = `${Formio_1.Formio.getApiUrl()}/externalModules.js`, name = 'externalModules') => {
29
33
  Formio_1.Formio.requireLibrary(name, name, path, true)
30
34
  .then((modules) => {
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -14,7 +37,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
37
  Object.defineProperty(exports, "__esModule", { value: true });
15
38
  const xhr_1 = __importDefault(require("./xhr"));
16
39
  const util_1 = require("./util");
17
- const AbortController = window.AbortController || require('abortcontroller-polyfill/dist/cjs-ponyfill');
40
+ const loadAbortControllerPolyfill = () => __awaiter(void 0, void 0, void 0, function* () {
41
+ if (typeof AbortController === 'undefined') {
42
+ yield Promise.resolve().then(() => __importStar(require('abortcontroller-polyfill/dist/polyfill-patch-fetch')));
43
+ }
44
+ });
18
45
  function s3(formio) {
19
46
  return {
20
47
  uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback, multipartOptions) {
@@ -25,6 +52,7 @@ function s3(formio) {
25
52
  if (response.signed) {
26
53
  if (multipartOptions && Array.isArray(response.signed)) {
27
54
  // patch abort callback
55
+ yield loadAbortControllerPolyfill();
28
56
  const abortController = new AbortController();
29
57
  const abortSignal = abortController.signal;
30
58
  if (typeof abortCallback === 'function') {
@@ -69,6 +69,8 @@ export default class Element {
69
69
  *
70
70
  * @param {string} event - The event you wish to register the handler for.
71
71
  * @param {function} cb - The callback handler to handle this event.
72
+ * @param {boolean} [internal] - This is an internal event handler.
73
+ * @param {boolean} [once] - This event should only fire once.
72
74
  */
73
75
  on(event, cb, internal, once = false) {
74
76
  if (!this.events) {
package/lib/mjs/Form.js CHANGED
@@ -97,7 +97,9 @@ export default class Form extends Element {
97
97
  this.element.appendChild(this.loader);
98
98
  }
99
99
  else if (this.loader) {
100
- this.element.removeChild(this.loader);
100
+ if (this.element.contains(this.loader)) {
101
+ this.element.removeChild(this.loader);
102
+ }
101
103
  this.loader = null;
102
104
  }
103
105
  }
@@ -1,12 +1,13 @@
1
1
  import _ from 'lodash';
2
2
  import moment from 'moment';
3
3
  import { compareVersions } from 'compare-versions';
4
+ import { Component } from '@formio/core';
4
5
  import EventEmitter from './EventEmitter';
5
6
  import i18nDefaults from './i18n';
6
7
  import { Formio } from './Formio';
7
8
  import Components from './components/Components';
8
9
  import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent';
9
- import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, searchComponents, convertStringToHTMLElement, getArrayFromComponentPath, interpolateErrors } from './utils/utils';
10
+ import { fastCloneDeep, currentTimezone, unescapeHTML, getStringFromComponentPath, searchComponents, convertStringToHTMLElement, getArrayFromComponentPath, } from './utils/utils';
10
11
  import { eachComponent } from './utils/formUtils';
11
12
  // Initialize the available forms.
12
13
  Formio.forms = {};
@@ -34,32 +35,113 @@ function getOptions(options) {
34
35
  }
35
36
  return options;
36
37
  }
38
+ /**
39
+ * Represents a JSON value.
40
+ * @typedef {(string | number | boolean | null | JSONArray | JSONObject)} JSON
41
+ */
42
+ /**
43
+ * Represents a JSON array.
44
+ * @typedef {Array<JSON>} JSONArray
45
+ */
46
+ /**
47
+ * Represents a JSON object.
48
+ * @typedef {{[key: string]: JSON}} JSONObject
49
+ */
50
+ /**
51
+ * @typedef {Object} FormioHooks
52
+ * @property {function} [beforeSubmit]
53
+ * @property {function} [beforeCancel]
54
+ * @property {function} [beforeNext]
55
+ * @property {function} [beforePrev]
56
+ * @property {function} [attachComponent]
57
+ * @property {function} [setDataValue]
58
+ * @property {function} [addComponents]
59
+ * @property {function} [addComponent]
60
+ * @property {function} [customValidation]
61
+ * @property {function} [attachWebform]
62
+ */
63
+ /**
64
+ * @typedef {Object} SanitizeConfig
65
+ * @property {string[]} [addAttr]
66
+ * @property {string[]} [addTags]
67
+ * @property {string[]} [allowedAttrs]
68
+ * @property {string[]} [allowedTags]
69
+ * @property {string[]} [allowedUriRegex]
70
+ * @property {string[]} [addUriSafeAttr]
71
+ */
72
+ /**
73
+ * @typedef {Object} ButtonSettings
74
+ * @property {boolean} [showPrevious]
75
+ * @property {boolean} [showNext]
76
+ * @property {boolean} [showCancel]
77
+ * @property {boolean} [showSubmit]
78
+ */
79
+ /**
80
+ * @typedef {Object} FormOptions
81
+ * @property {boolean} [saveDraft] - Enable the save draft feature.
82
+ * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
83
+ * @property {boolean} [readOnly] - Set this form to readOnly.
84
+ * @property {boolean} [noAlerts] - Disable the alerts dialog.
85
+ * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
86
+ * @property {string} [template] - Custom logic for creation of elements.
87
+ * @property {boolean} [noDefaults] - Exclude default values from the settings.
88
+ * @property {any} [fileService] - The file service for this form.
89
+ * @property {EventEmitter} [events] - The EventEmitter for this form.
90
+ * @property {string} [language] - The language to render this form in.
91
+ * @property {{[key: string]: string}} [i18next] - The i18next configuration for this form.
92
+ * @property {boolean} [viewAsHtml] - View the form as raw HTML.
93
+ * @property {'form' | 'html' | 'flat' | 'builder' | 'pdf'} [renderMode] - The render mode for this form.
94
+ * @property {boolean} [highlightErrors] - Highlight any errors on the form.
95
+ * @property {string} [componentErrorClass] - The error class for components.
96
+ * @property {any} [templates] - The templates for this form.
97
+ * @property {string} [iconset] - The iconset for this form.
98
+ * @property {Component[]} [components] - The components for this form.
99
+ * @property {{[key: string]: boolean}} [disabled] - Disabled components for this form.
100
+ * @property {boolean} [showHiddenFields] - Show hidden fields.
101
+ * @property {{[key: string]: boolean}} [hide] - Hidden components for this form.
102
+ * @property {{[key: string]: boolean}} [show] - Components to show for this form.
103
+ * @property {Formio} [formio] - The Formio instance for this form.
104
+ * @property {string} [decimalSeparator] - The decimal separator for this form.
105
+ * @property {string} [thousandsSeparator] - The thousands separator for this form.
106
+ * @property {FormioHooks} [hooks] - The hooks for this form.
107
+ * @property {boolean} [alwaysDirty] - Always be dirty.
108
+ * @property {boolean} [skipDraftRestore] - Skip restoring a draft.
109
+ * @property {'form' | 'wizard' | 'pdf'} [display] - The display for this form.
110
+ * @property {string} [cdnUrl] - The CDN url for this form.
111
+ * @property {boolean} [flatten] - Flatten the form.
112
+ * @property {boolean} [sanitize] - Sanitize the form.
113
+ * @property {SanitizeConfig} [sanitizeConfig] - The sanitize configuration for this form.
114
+ * @property {ButtonSettings} [buttonSettings] - The button settings for this form.
115
+ * @property {Object} [breadCrumbSettings] - The breadcrumb settings for this form.
116
+ * @property {boolean} [allowPrevious] - Allow the previous button (for Wizard forms).
117
+ * @property {string[]} [wizardButtonOrder] - The order of the buttons (for Wizard forms).
118
+ * @property {boolean} [showCheckboxBackground] - Show the checkbox background.
119
+ * @property {number} [zoom] - The zoom for PDF forms.
120
+ */
37
121
  /**
38
122
  * Renders a Form.io form within the webpage.
39
123
  */
40
124
  export default class Webform extends NestedDataComponent {
125
+ /**
126
+ * @type {FormOptions} - the options for this Webform.
127
+ */
128
+ options;
41
129
  /**
42
130
  * Creates a new Form instance.
43
131
  *
44
- * @param {Object} options - The options to create a new form instance.
45
- * @param {boolean} options.saveDraft - Set this if you would like to enable the save draft feature.
46
- * @param {boolean} options.saveDraftThrottle - The throttle for the save draft feature.
47
- * @param {boolean} options.readOnly - Set this form to readOnly
48
- * @param {boolean} options.noAlerts - Set to true to disable the alerts dialog.
49
- * @param {boolean} options.i18n - The translation file for this rendering. @see https://github.com/formio/formio.js/blob/master/i18n.js
50
- * @param {boolean} options.template - Provides a way to inject custom logic into the creation of every element rendered within the form.
132
+ * @param {HTMLElement | Object | FormOptions} [elementOrOptions] - The DOM element to render this form within or the options to create this form instance.
133
+ * @param {FormOptions} [options] - The options to create a new form instance.
51
134
  */
52
- /* eslint-disable max-statements */
53
- constructor() {
54
- let element, options;
55
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
56
- element = arguments[0];
57
- options = arguments[1];
135
+ constructor(elementOrOptions, options) {
136
+ let element, formOptions;
137
+ if (elementOrOptions instanceof HTMLElement || options) {
138
+ element = elementOrOptions;
139
+ formOptions = options;
58
140
  }
59
141
  else {
60
- options = arguments[0];
142
+ formOptions = elementOrOptions;
61
143
  }
62
- super(null, getOptions(options));
144
+ super(null, getOptions(formOptions));
63
145
  this.setElement(element);
64
146
  // Keep track of all available forms globally.
65
147
  Formio.forms[this.id] = this;
@@ -157,7 +157,7 @@ export default class WebformBuilder extends Component {
157
157
  return element;
158
158
  }
159
159
  // Attach container and component to element for later reference.
160
- const containerElement = element.querySelector(`[ref="${component.component.key}-container"]`) || element;
160
+ const containerElement = element.querySelector(`[${this._referenceAttributeName}="${component.component.key}-container"]`) || element;
161
161
  containerElement.formioContainer = container;
162
162
  containerElement.formioComponent = component;
163
163
  // Add container to draggable list.
@@ -1009,7 +1009,7 @@ export default class WebformBuilder extends Component {
1009
1009
  };
1010
1010
  const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1011
1011
  this.preview.form.components.forEach(component => this.replaceDoubleQuotes(component, fieldsToRemoveDoubleQuotes));
1012
- const previewElement = this.componentEdit.querySelector('[ref="preview"]');
1012
+ const previewElement = this.componentEdit.querySelector(`[${this._referenceAttributeName}="preview"]`);
1013
1013
  if (previewElement) {
1014
1014
  this.setContent(previewElement, this.preview.render(), null, sanitizeConfig);
1015
1015
  this.preview.attach(previewElement);
@@ -1176,7 +1176,7 @@ export default class WebformBuilder extends Component {
1176
1176
  this.emit('saveComponent', schema, originalComp, parentComponentSchema, path, index, isNew, originalComponentSchema);
1177
1177
  }
1178
1178
  attachEditComponentControls(component, parent, isNew, original, ComponentClass) {
1179
- const cancelButtons = this.componentEdit.querySelectorAll('[ref="cancelButton"]');
1179
+ const cancelButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="cancelButton"]`);
1180
1180
  cancelButtons.forEach((cancelButton) => {
1181
1181
  this.editForm.addEventListener(cancelButton, 'click', (event) => {
1182
1182
  event.preventDefault();
@@ -1186,7 +1186,7 @@ export default class WebformBuilder extends Component {
1186
1186
  this.highlightInvalidComponents();
1187
1187
  });
1188
1188
  });
1189
- const removeButtons = this.componentEdit.querySelectorAll('[ref="removeButton"]');
1189
+ const removeButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="removeButton"]`);
1190
1190
  removeButtons.forEach((removeButton) => {
1191
1191
  this.editForm.addEventListener(removeButton, 'click', (event) => {
1192
1192
  event.preventDefault();
@@ -1198,7 +1198,7 @@ export default class WebformBuilder extends Component {
1198
1198
  this.highlightInvalidComponents();
1199
1199
  });
1200
1200
  });
1201
- const saveButtons = this.componentEdit.querySelectorAll('[ref="saveButton"]');
1201
+ const saveButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="saveButton"]`);
1202
1202
  saveButtons.forEach((saveButton) => {
1203
1203
  this.editForm.addEventListener(saveButton, 'click', (event) => {
1204
1204
  event.preventDefault();
@@ -1214,7 +1214,7 @@ export default class WebformBuilder extends Component {
1214
1214
  this.saveComponent(component, parent, isNew, original);
1215
1215
  });
1216
1216
  });
1217
- const previewButtons = this.componentEdit.querySelectorAll('[ref="previewButton"]');
1217
+ const previewButtons = this.componentEdit.querySelectorAll(`[${this._referenceAttributeName}="previewButton"]`);
1218
1218
  previewButtons.forEach((previewButton) => {
1219
1219
  this.editForm.addEventListener(previewButton, 'click', (event) => {
1220
1220
  event.preventDefault();
@@ -1227,7 +1227,7 @@ export default class WebformBuilder extends Component {
1227
1227
  showPreview: this.showPreview,
1228
1228
  helplinks: this.helplinks,
1229
1229
  }));
1230
- this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
1230
+ this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
1231
1231
  this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
1232
1232
  });
1233
1233
  });
@@ -1326,7 +1326,7 @@ export default class WebformBuilder extends Component {
1326
1326
  }));
1327
1327
  this.dialog = this.createModal(this.componentEdit, _.get(this.options, 'dialogAttr', {}));
1328
1328
  // This is the attach step.
1329
- this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
1329
+ this.editForm.attach(this.componentEdit.querySelector(`[${this._referenceAttributeName}="editForm"]`));
1330
1330
  this.hook('editFormWrapper');
1331
1331
  this.updateComponent(componentCopy);
1332
1332
  this.editForm.on('change', (event) => {
@@ -326,6 +326,10 @@ export default class Component extends Element {
326
326
  this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;
327
327
  this._visible = this._parentVisible && this.conditionallyVisible(null, data);
328
328
  this._parentDisabled = false;
329
+ /**
330
+ * The reference attribute name for this component
331
+ */
332
+ this._referenceAttributeName = 'ref';
329
333
  /**
330
334
  * Used to trigger a new change in this component.
331
335
  * @type {function} - Call to trigger a change in this component.
@@ -778,21 +782,22 @@ export default class Component extends Element {
778
782
  const name = names[names.length - 1];
779
783
  const templatesByName = Templates.defaultTemplates[name];
780
784
  if (!templatesByName) {
781
- return `Unknown template: ${name}`;
785
+ return { template: `Unknown template: ${name}` };
782
786
  }
783
787
  const templateByMode = this.checkTemplateMode(templatesByName, modes);
784
788
  if (templateByMode) {
785
- return templateByMode;
789
+ return { template: templateByMode };
786
790
  }
787
- return templatesByName.form;
791
+ return { template: templatesByName.form };
788
792
  }
789
793
  checkTemplate(templates, names, modes) {
790
794
  for (const name of names) {
791
795
  const templatesByName = templates[name];
792
796
  if (templatesByName) {
797
+ const { referenceAttributeName } = templatesByName;
793
798
  const templateByMode = this.checkTemplateMode(templatesByName, modes);
794
799
  if (templateByMode) {
795
- return templateByMode;
800
+ return { template: templateByMode, referenceAttributeName };
796
801
  }
797
802
  }
798
803
  }
@@ -849,7 +854,11 @@ export default class Component extends Element {
849
854
  `${name}`,
850
855
  ];
851
856
  // Allow template alters.
852
- return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(this.getTemplate(names, mode), data), data, mode);
857
+ const { referenceAttributeName, template } = this.getTemplate(names, mode);
858
+ if (referenceAttributeName) {
859
+ this._referenceAttributeName = referenceAttributeName;
860
+ }
861
+ return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);
853
862
  }
854
863
  /**
855
864
  * Sanitize an html string.
@@ -963,11 +972,19 @@ export default class Component extends Element {
963
972
  // Return current timezone if none are provided.
964
973
  return currentTimezone();
965
974
  }
966
- loadRefs(element, refs) {
975
+ /**
976
+ *
977
+ * @param {HTMLElement} element - The containing DOM element to query for the ref value.
978
+ * @param {object} refs - The references to load.
979
+ * @param {string} [referenceAttributeName] - The attribute name to use for the reference.
980
+ */
981
+ loadRefs(element, refs, referenceAttributeName) {
967
982
  for (const ref in refs) {
968
983
  const refType = refs[ref];
969
984
  const isString = typeof refType === 'string';
970
- const selector = isString && refType.includes('scope') ? `:scope > [ref="${ref}"]` : `[ref="${ref}"]`;
985
+ const selector = isString && refType.includes('scope')
986
+ ? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`
987
+ : `[${referenceAttributeName || this._referenceAttributeName || 'ref'}="${ref}"]`;
971
988
  if (isString && refType.startsWith('single')) {
972
989
  this.refs[ref] = element.querySelector(selector);
973
990
  }
@@ -1042,7 +1059,7 @@ export default class Component extends Element {
1042
1059
  });
1043
1060
  }
1044
1061
  createComponentModal(element, modalShouldBeOpened, currentValue) {
1045
- return new ComponentModal(this, element, modalShouldBeOpened, currentValue);
1062
+ return new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
1046
1063
  }
1047
1064
  attach(element) {
1048
1065
  if (!this.builderMode && !this.previewMode && this.component.modalEdit) {
@@ -8,7 +8,8 @@ export default class ComponentModal {
8
8
  children,
9
9
  });
10
10
  }
11
- constructor(component, element, isOpened, currentValue) {
11
+ constructor(component, element, isOpened, currentValue, referenceAttributeName = 'ref') {
12
+ this._referenceAttributeName = referenceAttributeName;
12
13
  this.isOpened = isOpened;
13
14
  this.component = component;
14
15
  this.element = element;
@@ -142,10 +143,10 @@ export default class ComponentModal {
142
143
  showDialog() {
143
144
  this.dialogElement = this.component.ce('div');
144
145
  const dialogContent = `
145
- <h3 ref="dialogHeader">${this.component.t('Do you want to clear changes?')}</h3>
146
+ <h3 ${this._referenceAttributeName}="dialogHeader">${this.component.t('Do you want to clear changes?')}</h3>
146
147
  <div style="display:flex; justify-content: flex-end;">
147
- <button ref="dialogCancelButton" class="btn btn-secondary">${this.component.t('Cancel')}</button>
148
- <button ref="dialogYesButton" class="btn btn-danger">${this.component.t('Yes, delete it')}</button>
148
+ <button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary">${this.component.t('Cancel')}</button>
149
+ <button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger">${this.component.t('Yes, delete it')}</button>
149
150
  </div>
150
151
  `;
151
152
  this.dialogElement.innerHTML = dialogContent;
@@ -101,7 +101,7 @@ export default class Input extends Multivalue {
101
101
  }).trim();
102
102
  if (this.component.prefix !== calendarIcon) {
103
103
  // converting string to HTML markup to render correctly DateTime component in portal.form.io
104
- return convertStringToHTMLElement(calendarIcon, '[ref="icon"]');
104
+ return convertStringToHTMLElement(calendarIcon, `[${this._referenceAttributeName}="icon"]`);
105
105
  }
106
106
  }
107
107
  return this.component.suffix;
@@ -32,7 +32,7 @@ export default class Multivalue extends Field {
32
32
  render() {
33
33
  // If single value field.
34
34
  if (!this.useWrapper()) {
35
- return super.render(`<div ref="element">
35
+ return super.render(`<div ${this._referenceAttributeName}="element">
36
36
  ${this.renderElement(this.component.type !== 'hidden' ? this.dataValue : '')}
37
37
  </div>`);
38
38
  }