@formio/js 5.0.0-rc.47 → 5.0.0-rc.48
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.js +1 -1
- package/dist/formio.embed.min.js.LICENSE.txt +1 -1
- package/dist/formio.form.js +10 -10
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -1
- package/dist/formio.full.js +10 -10
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -1
- package/dist/formio.js +2 -2
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +1 -1
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Webform.d.ts +11 -1
- package/lib/cjs/Webform.js +3 -1
- package/lib/cjs/components/_classes/component/Component.d.ts +4 -4
- package/lib/cjs/components/_classes/component/Component.js +5 -7
- package/lib/cjs/components/_classes/nested/NestedComponent.d.ts +5 -6
- package/lib/cjs/components/_classes/nested/NestedComponent.js +5 -5
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +1 -1
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -1
- package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
- package/lib/cjs/components/day/Day.d.ts +1 -0
- package/lib/cjs/components/html/HTML.js +2 -2
- package/lib/cjs/components/select/Select.d.ts +4 -1
- package/lib/cjs/components/select/Select.js +57 -34
- package/lib/cjs/components/select/fixtures/comp22.d.ts +51 -0
- package/lib/cjs/components/select/fixtures/comp22.js +43 -0
- package/lib/cjs/components/select/fixtures/index.d.ts +2 -1
- package/lib/cjs/components/select/fixtures/index.js +3 -1
- package/lib/mjs/Webform.d.ts +11 -1
- package/lib/mjs/Webform.js +3 -1
- package/lib/mjs/components/_classes/component/Component.d.ts +4 -4
- package/lib/mjs/components/_classes/component/Component.js +5 -7
- package/lib/mjs/components/_classes/nested/NestedComponent.d.ts +5 -6
- package/lib/mjs/components/_classes/nested/NestedComponent.js +5 -5
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +1 -1
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.d.ts +1 -1
- package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
- package/lib/mjs/components/day/Day.d.ts +1 -0
- package/lib/mjs/components/html/HTML.js +2 -2
- package/lib/mjs/components/select/Select.d.ts +4 -1
- package/lib/mjs/components/select/Select.js +56 -33
- package/lib/mjs/components/select/fixtures/comp22.d.ts +51 -0
- package/lib/mjs/components/select/fixtures/comp22.js +41 -0
- package/lib/mjs/components/select/fixtures/index.d.ts +2 -1
- package/lib/mjs/components/select/fixtures/index.js +2 -1
- package/package.json +2 -2
package/dist/formio.full.js
CHANGED
@@ -893,7 +893,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
893
893
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
894
894
|
|
895
895
|
"use strict";
|
896
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateRequiredInfo = exports.validateRequiredSync = exports.validateRequired = exports.shouldValidate = void 0;\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst util_1 = __webpack_require__(/*! ../util */ \"./node_modules/@formio/core/lib/process/validation/util.js\");\nconst isAddressComponentDataObject = (value) => {\n return value !== null && typeof value === 'object' && value.mode && value.address && typeof value.address === 'object';\n};\nconst shouldValidate = (context) => {\n var _a;\n const { component } = context;\n if ((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required) {\n return true;\n }\n return false;\n};\nexports.shouldValidate = shouldValidate;\nconst validateRequired = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateRequiredSync)(context);\n});\nexports.validateRequired = validateRequired;\nconst validateRequiredSync = (context) => {\n const error = new error_1.FieldError('required', Object.assign(Object.assign({}, context), { setting: true }));\n const { component, value } = context;\n if (!(0, exports.shouldValidate)(context)) {\n return null;\n }\n if ((
|
896
|
+
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateRequiredInfo = exports.validateRequiredSync = exports.validateRequired = exports.shouldValidate = void 0;\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst util_1 = __webpack_require__(/*! ../util */ \"./node_modules/@formio/core/lib/process/validation/util.js\");\nconst isAddressComponent = (component) => {\n return component.type === 'address';\n};\nconst isDayComponent = (component) => {\n return component.type === 'day';\n};\nconst isAddressComponentDataObject = (value) => {\n return value !== null && typeof value === 'object' && value.mode && value.address && typeof value.address === 'object';\n};\n// Checkboxes and selectboxes consider false to be falsy, whereas other components with\n// settable values (e.g. radio, select, datamap, container, etc.) consider it truthy\nconst isComponentThatCannotHaveFalseValue = (component) => {\n return component.type === 'checkbox' || component.type === 'selectboxes';\n};\nconst valueIsPresent = (value, considerFalseTruthy) => {\n // Evaluate for 3 out of 6 falsy values (\"\", null, undefined), don't check for 0\n // and only check for false under certain conditions\n if (value === null || value === undefined || value === \"\" || (!considerFalseTruthy && value === false)) {\n return false;\n }\n // Evaluate for empty object\n else if ((0, util_1.isEmptyObject)(value)) {\n return false;\n }\n // Evaluate for empty array\n else if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n // Recursively evaluate\n else if (typeof value === 'object') {\n return Object.values(value).some((val) => valueIsPresent(val, considerFalseTruthy));\n }\n return true;\n};\nconst shouldValidate = (context) => {\n var _a;\n const { component } = context;\n if (((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required) && !component.hidden) {\n return true;\n }\n return false;\n};\nexports.shouldValidate = shouldValidate;\nconst validateRequired = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateRequiredSync)(context);\n});\nexports.validateRequired = validateRequired;\nconst validateRequiredSync = (context) => {\n const error = new error_1.FieldError('required', Object.assign(Object.assign({}, context), { setting: true }));\n const { component, value } = context;\n if (!(0, exports.shouldValidate)(context)) {\n return null;\n }\n if (isAddressComponent(component) && isAddressComponentDataObject(value)) {\n return (0, util_1.isEmptyObject)(value.address) ? error : Object.values(value.address).every((val) => !!val) ? null : error;\n }\n else if (isDayComponent(component) && value === '00/00/0000') {\n return error;\n }\n else if (isComponentThatCannotHaveFalseValue(component)) {\n return !valueIsPresent(value, false) ? error : null;\n }\n return !valueIsPresent(value, true) ? error : null;\n};\nexports.validateRequiredSync = validateRequiredSync;\nexports.validateRequiredInfo = {\n name: 'validateRequired',\n process: exports.validateRequired,\n processSync: exports.validateRequiredSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateRequired.js?");
|
897
897
|
|
898
898
|
/***/ }),
|
899
899
|
|
@@ -5385,7 +5385,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5385
5385
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5386
5386
|
|
5387
5387
|
"use strict";
|
5388
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst moment_1 = __importDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\nconst compare_versions_1 = __webpack_require__(/*! compare-versions */ \"./node_modules/compare-versions/lib/esm/index.js\");\nconst core_1 = __webpack_require__(/*! @formio/core */ \"./node_modules/@formio/core/lib/index.js\");\nconst EventEmitter_1 = __importDefault(__webpack_require__(/*! ./EventEmitter */ \"./lib/cjs/EventEmitter.js\"));\nconst i18n_1 = __importDefault(__webpack_require__(/*! ./i18n */ \"./lib/cjs/i18n.js\"));\nconst Formio_1 = __webpack_require__(/*! ./Formio */ \"./lib/cjs/Formio.js\");\nconst Components_1 = __importDefault(__webpack_require__(/*! ./components/Components */ \"./lib/cjs/components/Components.js\"));\nconst NestedDataComponent_1 = __importDefault(__webpack_require__(/*! ./components/_classes/nesteddata/NestedDataComponent */ \"./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js\"));\nconst utils_1 = __webpack_require__(/*! ./utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst formUtils_1 = __webpack_require__(/*! ./utils/formUtils */ \"./lib/cjs/utils/formUtils.js\");\n// Initialize the available forms.\nFormio_1.Formio.forms = {};\n// Allow people to register components.\nFormio_1.Formio.registerComponent = Components_1.default.setComponent;\nfunction getIconSet(icons) {\n if (icons === 'fontawesome') {\n return 'fa';\n }\n return icons || '';\n}\nfunction getOptions(options) {\n options = lodash_1.default.defaults(options, {\n submitOnEnter: false,\n iconset: getIconSet((options && options.icons) ? options.icons : Formio_1.Formio.icons),\n i18next: null,\n saveDraft: false,\n alwaysDirty: false,\n saveDraftThrottle: 5000,\n display: 'form',\n cdnUrl: Formio_1.Formio.cdn.baseUrl\n });\n if (!options.events) {\n options.events = new EventEmitter_1.default();\n }\n return options;\n}\n/**\n * Represents a JSON value.\n * @typedef {(string | number | boolean | null | JSONArray | JSONObject)} JSON\n */\n/**\n * Represents a JSON array.\n * @typedef {Array<JSON>} JSONArray\n */\n/**\n * Represents a JSON object.\n * @typedef {{[key: string]: JSON}} JSONObject\n */\n/**\n * @typedef {Object} FormioHooks\n * @property {function} [beforeSubmit]\n * @property {function} [beforeCancel]\n * @property {function} [beforeNext]\n * @property {function} [beforePrev]\n * @property {function} [attachComponent]\n * @property {function} [setDataValue]\n * @property {function} [addComponents]\n * @property {function} [addComponent]\n * @property {function} [customValidation]\n * @property {function} [attachWebform]\n */\n/**\n * @typedef {Object} SanitizeConfig\n * @property {string[]} [addAttr]\n * @property {string[]} [addTags]\n * @property {string[]} [allowedAttrs]\n * @property {string[]} [allowedTags]\n * @property {string[]} [allowedUriRegex]\n * @property {string[]} [addUriSafeAttr]\n */\n/**\n * @typedef {Object} ButtonSettings\n * @property {boolean} [showPrevious]\n * @property {boolean} [showNext]\n * @property {boolean} [showCancel]\n * @property {boolean} [showSubmit]\n */\n/**\n * @typedef {Object} FormOptions\n * @property {boolean} [saveDraft] - Enable the save draft feature.\n * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.\n * @property {boolean} [readOnly] - Set this form to readOnly.\n * @property {boolean} [noAlerts] - Disable the alerts dialog.\n * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.\n * @property {string} [template] - Custom logic for creation of elements.\n * @property {boolean} [noDefaults] - Exclude default values from the settings.\n * @property {any} [fileService] - The file service for this form.\n * @property {EventEmitter} [events] - The EventEmitter for this form.\n * @property {string} [language] - The language to render this form in.\n * @property {{[key: string]: string}} [i18next] - The i18next configuration for this form.\n * @property {boolean} [viewAsHtml] - View the form as raw HTML.\n * @property {'form' | 'html' | 'flat' | 'builder' | 'pdf'} [renderMode] - The render mode for this form.\n * @property {boolean} [highlightErrors] - Highlight any errors on the form.\n * @property {string} [componentErrorClass] - The error class for components.\n * @property {any} [templates] - The templates for this form.\n * @property {string} [iconset] - The iconset for this form.\n * @property {Component[]} [components] - The components for this form.\n * @property {{[key: string]: boolean}} [disabled] - Disabled components for this form.\n * @property {boolean} [showHiddenFields] - Show hidden fields.\n * @property {{[key: string]: boolean}} [hide] - Hidden components for this form.\n * @property {{[key: string]: boolean}} [show] - Components to show for this form.\n * @property {Formio} [formio] - The Formio instance for this form.\n * @property {string} [decimalSeparator] - The decimal separator for this form.\n * @property {string} [thousandsSeparator] - The thousands separator for this form.\n * @property {FormioHooks} [hooks] - The hooks for this form.\n * @property {boolean} [alwaysDirty] - Always be dirty.\n * @property {boolean} [skipDraftRestore] - Skip restoring a draft.\n * @property {'form' | 'wizard' | 'pdf'} [display] - The display for this form.\n * @property {string} [cdnUrl] - The CDN url for this form.\n * @property {boolean} [flatten] - Flatten the form.\n * @property {boolean} [sanitize] - Sanitize the form.\n * @property {SanitizeConfig} [sanitizeConfig] - The sanitize configuration for this form.\n * @property {ButtonSettings} [buttonSettings] - The button settings for this form.\n * @property {Object} [breadCrumbSettings] - The breadcrumb settings for this form.\n * @property {boolean} [allowPrevious] - Allow the previous button (for Wizard forms).\n * @property {string[]} [wizardButtonOrder] - The order of the buttons (for Wizard forms).\n * @property {boolean} [showCheckboxBackground] - Show the checkbox background.\n * @property {number} [zoom] - The zoom for PDF forms.\n */\n/**\n * Renders a Form.io form within the webpage.\n */\nclass Webform extends NestedDataComponent_1.default {\n /**\n * Creates a new Form instance.\n *\n * @param {HTMLElement | Object | FormOptions} [elementOrOptions] - The DOM element to render this form within or the options to create this form instance.\n * @param {FormOptions} [options] - The options to create a new form instance.\n */\n constructor(elementOrOptions, options) {\n let element, formOptions;\n if (elementOrOptions instanceof HTMLElement || options) {\n element = elementOrOptions;\n formOptions = options;\n }\n else {\n formOptions = elementOrOptions;\n }\n super(null, getOptions(formOptions));\n this.executeShortcuts = (event) => {\n const { target } = event;\n if (!this.keyboardCatchableElement(target)) {\n return;\n }\n const ctrl = event.ctrlKey || event.metaKey;\n const keyCode = event.keyCode;\n let char = '';\n if (65 <= keyCode && keyCode <= 90) {\n char = String.fromCharCode(keyCode);\n }\n else if (keyCode === 13) {\n char = 'Enter';\n }\n else if (keyCode === 27) {\n char = 'Esc';\n }\n lodash_1.default.each(this.shortcuts, (shortcut) => {\n if (shortcut.ctrl && !ctrl) {\n return;\n }\n if (shortcut.shortcut === char) {\n shortcut.element.click();\n event.preventDefault();\n }\n });\n };\n this.setElement(element);\n // Keep track of all available forms globally.\n Formio_1.Formio.forms[this.id] = this;\n // Set the base url.\n if (this.options.baseUrl) {\n Formio_1.Formio.setBaseUrl(this.options.baseUrl);\n }\n /**\n * The type of this element.\n * @type {string}\n */\n this.type = 'form';\n this._src = '';\n this._loading = false;\n this._form = {};\n this.draftEnabled = false;\n this.savingDraft = true;\n if (this.options.saveDraftThrottle) {\n this.triggerSaveDraft = lodash_1.default.throttle(this.saveDraft.bind(this), this.options.saveDraftThrottle);\n }\n else {\n this.triggerSaveDraft = this.saveDraft.bind(this);\n }\n /**\n * Determines if this form should submit the API on submit.\n * @type {boolean}\n */\n this.nosubmit = false;\n /**\n * Determines if the form has tried to be submitted, error or not.\n *\n * @type {boolean}\n */\n this.submitted = false;\n /**\n * Determines if the form is being submitted at the moment.\n *\n * @type {boolean}\n */\n this.submitting = false;\n /**\n * The Formio instance for this form.\n * @type {Formio}\n */\n this.formio = null;\n /**\n * The loader HTML element.\n * @type {HTMLElement}\n */\n this.loader = null;\n /**\n * The alert HTML element\n * @type {HTMLElement}\n */\n this.alert = null;\n /**\n * Promise that is triggered when the submission is done loading.\n * @type {Promise}\n */\n this.onSubmission = null;\n /**\n * Determines if this submission is explicitly set.\n * @type {boolean}\n */\n this.submissionSet = false;\n /**\n * Promise that executes when the form is ready and rendered.\n * @type {Promise}\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.formReady.then(() => {\n * console.log('The form is ready!');\n * });\n * form.src = 'https://examples.form.io/example';\n */\n this.formReady = new Promise((resolve, reject) => {\n /**\n * Called when the formReady state of this form has been resolved.\n *\n * @type {function}\n */\n this.formReadyResolve = resolve;\n /**\n * Called when this form could not load and is rejected.\n *\n * @type {function}\n */\n this.formReadyReject = reject;\n });\n /**\n * Promise that executes when the submission is ready and rendered.\n * @type {Promise}\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.submissionReady.then(() => {\n * console.log('The submission is ready!');\n * });\n * form.src = 'https://examples.form.io/example/submission/234234234234234243';\n */\n this.submissionReady = new Promise((resolve, reject) => {\n /**\n * Called when the formReady state of this form has been resolved.\n *\n * @type {function}\n */\n this.submissionReadyResolve = resolve;\n /**\n * Called when this form could not load and is rejected.\n *\n * @type {function}\n */\n this.submissionReadyReject = reject;\n });\n this.shortcuts = [];\n // Set language after everything is established.\n this.language = this.i18next.language;\n // See if we need to restore the draft from a user.\n if (this.options.saveDraft && !this.options.skipDraftRestore) {\n this.formReady.then(() => {\n const user = Formio_1.Formio.getUser();\n // Only restore a draft if the submission isn't explicitly set.\n if (user && !this.submissionSet) {\n this.restoreDraft(user._id);\n }\n });\n }\n this.component.clearOnHide = false;\n // Ensure the root is set to this component.\n this.root = this;\n this.localRoot = this;\n }\n /* eslint-enable max-statements */\n get language() {\n return this.options.language;\n }\n get emptyValue() {\n return null;\n }\n componentContext() {\n return this._data;\n }\n /**\n * Sets the language for this form.\n *\n * @param lang\n * @return {Promise}\n */\n set language(lang) {\n if (!this.i18next) {\n return;\n }\n this.options.language = lang;\n if (this.i18next.language === lang) {\n return;\n }\n this.i18next.changeLanguage(lang, (err) => {\n if (err) {\n return;\n }\n this.rebuild();\n this.emit('languageChanged');\n });\n }\n get componentComponents() {\n return this.form.components;\n }\n get shadowRoot() {\n return this.options.shadowRoot;\n }\n /**\n * Add a language for translations\n *\n * @param code\n * @param lang\n * @param active\n * @return {*}\n */\n addLanguage(code, lang, active = false) {\n if (this.i18next) {\n var translations = lodash_1.default.assign((0, utils_1.fastCloneDeep)(i18n_1.default.resources.en.translation), lang);\n this.i18next.addResourceBundle(code, 'translation', translations, true, true);\n if (active) {\n this.language = code;\n }\n }\n }\n keyboardCatchableElement(element) {\n if (element.nodeName === 'TEXTAREA') {\n return false;\n }\n if (element.nodeName === 'INPUT') {\n return [\n 'text',\n 'email',\n 'password'\n ].indexOf(element.type) === -1;\n }\n return true;\n }\n addShortcut(element, shortcut) {\n if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {\n return;\n }\n shortcut = lodash_1.default.capitalize(shortcut);\n if (shortcut === 'Enter' || shortcut === 'Esc') {\n // Restrict Enter and Esc only for buttons\n if (element.tagName !== 'BUTTON') {\n return;\n }\n this.shortcuts.push({\n shortcut,\n element\n });\n }\n else {\n this.shortcuts.push({\n ctrl: true,\n shortcut,\n element\n });\n }\n }\n removeShortcut(element, shortcut) {\n if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {\n return;\n }\n lodash_1.default.remove(this.shortcuts, {\n shortcut,\n element\n });\n }\n /**\n * Get the embed source of the form.\n *\n * @returns {string}\n */\n get src() {\n return this._src;\n }\n /**\n * Loads the submission if applicable.\n */\n loadSubmission() {\n this.loadingSubmission = true;\n if (this.formio.submissionId) {\n this.onSubmission = this.formio.loadSubmission().then((submission) => this.setSubmission(submission), (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));\n }\n else {\n this.submissionReadyResolve();\n }\n return this.submissionReady;\n }\n /**\n * Set the src of the form renderer.\n *\n * @param value\n * @param options\n */\n setSrc(value, options) {\n if (this.setUrl(value, options)) {\n this.nosubmit = false;\n return this.formio.loadForm({ params: { live: 1 } }).then((form) => {\n const setForm = this.setForm(form);\n this.loadSubmission();\n return setForm;\n }).catch((err) => {\n console.warn(err);\n this.formReadyReject(err);\n });\n }\n return Promise.resolve();\n }\n /**\n * Set the Form source, which is typically the Form.io embed URL.\n *\n * @param {string} value - The value of the form embed url.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.formReady.then(() => {\n * console.log('The form is formReady!');\n * });\n * form.src = 'https://examples.form.io/example';\n */\n set src(value) {\n this.setSrc(value);\n }\n /**\n * Get the embed source of the form.\n *\n * @returns {string}\n */\n get url() {\n return this._src;\n }\n /**\n * Sets the url of the form renderer.\n *\n * @param value\n * @param options\n */\n setUrl(value, options) {\n if (!value ||\n (typeof value !== 'string') ||\n (value === this._src)) {\n return false;\n }\n this._src = value;\n this.nosubmit = true;\n this.formio = this.options.formio = new Formio_1.Formio(value, options);\n if (this.type === 'form') {\n // Set the options source so this can be passed to other components.\n this.options.src = value;\n }\n return true;\n }\n /**\n * Set the form source but don't initialize the form and submission from the url.\n *\n * @param {string} value - The value of the form embed url.\n */\n set url(value) {\n this.setUrl(value);\n }\n /**\n * Called when both the form and submission have been loaded.\n *\n * @returns {Promise} - The promise to trigger when both form and submission have loaded.\n */\n get ready() {\n return this.formReady.then(() => {\n return super.ready.then(() => {\n return this.loadingSubmission ? this.submissionReady : true;\n });\n });\n }\n /**\n * Returns if this form is loading.\n *\n * @returns {boolean} - TRUE means the form is loading, FALSE otherwise.\n */\n get loading() {\n return this._loading;\n }\n /**\n * Set the loading state for this form, and also show the loader spinner.\n *\n * @param {boolean} loading - If this form should be \"loading\" or not.\n */\n set loading(loading) {\n if (this._loading !== loading) {\n this._loading = loading;\n if (!this.loader && loading) {\n this.loader = this.ce('div', {\n class: 'loader-wrapper'\n });\n const spinner = this.ce('div', {\n class: 'loader text-center'\n });\n this.loader.appendChild(spinner);\n }\n /* eslint-disable max-depth */\n if (this.loader) {\n try {\n if (loading) {\n this.prependTo(this.loader, this.wrapper);\n }\n else {\n this.removeChildFrom(this.loader, this.wrapper);\n }\n }\n catch (err) {\n // ingore\n }\n }\n /* eslint-enable max-depth */\n }\n }\n /**\n * Sets the JSON schema for the form to be rendered.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.setForm({\n * components: [\n * {\n * type: 'textfield',\n * key: 'firstName',\n * label: 'First Name',\n * placeholder: 'Enter your first name.',\n * input: true\n * },\n * {\n * type: 'textfield',\n * key: 'lastName',\n * label: 'Last Name',\n * placeholder: 'Enter your last name',\n * input: true\n * },\n * {\n * type: 'button',\n * action: 'submit',\n * label: 'Submit',\n * theme: 'primary'\n * }\n * ]\n * });\n *\n * @param {Object} form - The JSON schema of the form @see https://examples.form.io/example for an example JSON schema.\n * @param flags\n * @returns {*}\n */\n setForm(form, flags) {\n var _a, _b, _c;\n const isFormAlreadySet = this._form && ((_a = this._form.components) === null || _a === void 0 ? void 0 : _a.length);\n try {\n // Do not set the form again if it has been already set\n if (isFormAlreadySet && JSON.stringify(this._form) === JSON.stringify(form)) {\n return Promise.resolve();\n }\n // Create the form.\n this._form = (flags === null || flags === void 0 ? void 0 : flags.keepAsReference) ? form : lodash_1.default.cloneDeep(form);\n if (this.onSetForm) {\n this.onSetForm(lodash_1.default.cloneDeep(this._form), form);\n }\n if ((_c = (_b = this.parent) === null || _b === void 0 ? void 0 : _b.component) === null || _c === void 0 ? void 0 : _c.modalEdit) {\n return Promise.resolve();\n }\n }\n catch (err) {\n console.warn(err);\n // If provided form is not a valid JSON object, do not set it too\n return Promise.resolve();\n }\n // Allow the form to provide component overrides.\n if (form && form.settings && form.settings.components) {\n this.options.components = form.settings.components;\n }\n if (form && form.properties) {\n this.options.properties = form.properties;\n }\n // Use the sanitize config from the form settings or the global sanitize config if it is not provided in the options\n if (!this.options.sanitizeConfig && !this.builderMode) {\n this.options.sanitizeConfig = lodash_1.default.get(form, 'settings.sanitizeConfig') || lodash_1.default.get(form, 'globalSettings.sanitizeConfig');\n }\n if ('schema' in form && (0, compare_versions_1.compareVersions)(form.schema, '1.x') > 0) {\n this.ready.then(() => {\n this.setAlert('alert alert-danger', 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.');\n });\n }\n // See if they pass a module, and evaluate it if so.\n if (form && form.module) {\n let formModule = null;\n if (typeof form.module === 'string') {\n try {\n formModule = this.evaluate(`return ${form.module}`);\n }\n catch (err) {\n console.warn(err);\n }\n }\n else {\n formModule = form.module;\n }\n if (formModule) {\n Formio_1.Formio.use(formModule);\n // Since we got here after instantiation, we need to manually apply form options.\n if (formModule.options && formModule.options.form) {\n this.options = Object.assign(this.options, formModule.options.form);\n }\n }\n }\n this.initialized = false;\n const rebuild = this.rebuild() || Promise.resolve();\n return rebuild.then(() => {\n this.emit('formLoad', form);\n this.triggerRecaptcha();\n // Make sure to trigger onChange after a render event occurs to speed up form rendering.\n setTimeout(() => {\n this.onChange(flags);\n this.formReadyResolve();\n }, 0);\n return this.formReady;\n });\n }\n /**\n * Gets the form object.\n *\n * @returns {Object} - The form JSON schema.\n */\n get form() {\n if (!this._form) {\n this._form = {\n components: []\n };\n }\n return this._form;\n }\n /**\n * Sets the form value.\n *\n * @alias setForm\n * @param {Object} form - The form schema object.\n */\n set form(form) {\n this.setForm(form);\n }\n /**\n * Returns the submission object that was set within this form.\n *\n * @returns {Object}\n */\n get submission() {\n return this.getValue();\n }\n /**\n * Sets the submission of a form.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.src = 'https://examples.form.io/example';\n * form.submission = {data: {\n * firstName: 'Joe',\n * lastName: 'Smith',\n * email: 'joe@example.com'\n * }};\n *\n * @param {Object} submission - The Form.io submission object.\n */\n set submission(submission) {\n this.setSubmission(submission);\n }\n /**\n * Sets a submission and returns the promise when it is ready.\n * @param submission\n * @param flags\n * @return {Promise.<TResult>}\n */\n setSubmission(submission, flags = {}) {\n flags = Object.assign(Object.assign({}, flags), { fromSubmission: lodash_1.default.has(flags, 'fromSubmission') ? flags.fromSubmission : true });\n return this.onSubmission = this.formReady.then((resolveFlags) => {\n if (resolveFlags) {\n flags = Object.assign(Object.assign({}, flags), resolveFlags);\n }\n this.submissionSet = true;\n this.triggerChange(flags);\n this.emit('beforeSetSubmission', submission);\n this.setValue(submission, flags);\n return this.submissionReadyResolve(submission);\n }, (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));\n }\n handleDraftError(errName, errDetails, restoreDraft) {\n const errorMessage = lodash_1.default.trim(`${this.t(errName)} ${errDetails || ''}`);\n console.warn(errorMessage);\n this.emit(restoreDraft ? 'restoreDraftError' : 'saveDraftError', errDetails || errorMessage);\n }\n /**\n * Saves a submission draft.\n */\n saveDraft() {\n if (!this.draftEnabled) {\n return;\n }\n if (!this.formio) {\n this.handleDraftError('saveDraftInstanceError');\n return;\n }\n if (!Formio_1.Formio.getUser()) {\n this.handleDraftError('saveDraftAuthError');\n return;\n }\n const draft = (0, utils_1.fastCloneDeep)(this.submission);\n draft.state = 'draft';\n if (!this.savingDraft) {\n this.emit('saveDraftBegin');\n this.savingDraft = true;\n this.formio.saveSubmission(draft).then((sub) => {\n // Set id to submission to avoid creating new draft submission\n this.submission._id = sub._id;\n this.savingDraft = false;\n this.emit('saveDraft', sub);\n })\n .catch(err => {\n this.savingDraft = false;\n this.handleDraftError('saveDraftError', err);\n });\n }\n }\n /**\n * Restores a draft submission based on the user who is authenticated.\n *\n * @param {userId} - The user id where we need to restore the draft from.\n */\n restoreDraft(userId) {\n const formio = this.formio || this.options.formio;\n if (!formio) {\n this.handleDraftError('restoreDraftInstanceError', null, true);\n return;\n }\n this.savingDraft = true;\n formio.loadSubmissions({\n params: {\n state: 'draft',\n owner: userId\n }\n }).then(submissions => {\n if (submissions.length > 0 && !this.options.skipDraftRestore) {\n const draft = (0, utils_1.fastCloneDeep)(submissions[0]);\n return this.setSubmission(draft).then(() => {\n this.draftEnabled = true;\n this.savingDraft = false;\n this.emit('restoreDraft', draft);\n });\n }\n // Enable drafts so that we can keep track of changes.\n this.draftEnabled = true;\n this.savingDraft = false;\n this.emit('restoreDraft', null);\n })\n .catch(err => {\n this.draftEnabled = true;\n this.savingDraft = false;\n this.handleDraftError('restoreDraftError', err, true);\n });\n }\n get schema() {\n const schema = (0, utils_1.fastCloneDeep)(lodash_1.default.omit(this._form, ['components']));\n schema.components = [];\n this.eachComponent((component) => schema.components.push(component.schema));\n return schema;\n }\n mergeData(_this, _that) {\n lodash_1.default.mergeWith(_this, _that, (thisValue, thatValue) => {\n if (Array.isArray(thisValue) && Array.isArray(thatValue) && thisValue.length !== thatValue.length) {\n return thatValue;\n }\n });\n }\n setValue(submission, flags = {}) {\n if (!submission || !submission.data) {\n submission = {\n data: {},\n metadata: submission.metadata,\n };\n }\n // Metadata needs to be available before setValue\n this._submission.metadata = submission.metadata || {};\n this.editing = !!submission._id;\n // Set the timezone in the options if available.\n if (!this.options.submissionTimezone &&\n submission.metadata &&\n submission.metadata.timezone) {\n this.options.submissionTimezone = submission.metadata.timezone;\n }\n const changed = super.setValue(submission.data, flags);\n if (!flags.sanitize) {\n this.mergeData(this.data, submission.data);\n }\n submission.data = this.data;\n this._submission = submission;\n return changed;\n }\n getValue() {\n if (!this._submission.data) {\n this._submission.data = {};\n }\n if (this.viewOnly) {\n return this._submission;\n }\n const submission = this._submission;\n submission.data = this.data;\n return this._submission;\n }\n /**\n * Build the form.\n */\n init() {\n if (this.options.submission) {\n const submission = lodash_1.default.extend({}, this.options.submission);\n this._submission = submission;\n this._data = submission.data;\n }\n else {\n this._submission = this._submission || { data: {} };\n }\n // Remove any existing components.\n if (this.components && this.components.length) {\n this.destroyComponents();\n this.components = [];\n }\n if (this.component) {\n this.component.components = this.form ? this.form.components : [];\n }\n else {\n this.component = this.form;\n }\n this.component.type = 'form';\n this.component.input = false;\n this.addComponents();\n this.on('submitButton', options => {\n this.submit(false, options).catch(e => {\n options.instance.loading = false;\n return e !== false && e !== undefined && console.log(e);\n });\n }, true);\n this.on('checkValidity', (data) => this.validate(data, { dirty: true, process: 'change' }), true);\n this.on('requestUrl', (args) => (this.submitUrl(args.url, args.headers)), true);\n this.on('resetForm', () => this.resetValue(), true);\n this.on('deleteSubmission', () => this.deleteSubmission(), true);\n this.on('refreshData', () => this.updateValue(), true);\n this.executeFormController();\n return this.formReady;\n }\n executeFormController() {\n // If no controller value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n if (!this.form || !this.form.controller\n || ((!this.visible || this.component.hidden) && this.component.clearOnHide && !this.rootPristine)) {\n return false;\n }\n this.formReady.then(() => {\n this.evaluate(this.form.controller, {\n components: this.components,\n instance: this,\n });\n });\n }\n teardown() {\n this.emit('formDelete', this.id);\n delete Formio_1.Formio.forms[this.id];\n delete this.executeShortcuts;\n delete this.triggerSaveDraft;\n super.teardown();\n }\n destroy(all = false) {\n this.off('submitButton');\n this.off('checkValidity');\n this.off('requestUrl');\n this.off('resetForm');\n this.off('deleteSubmission');\n this.off('refreshData');\n return super.destroy(all);\n }\n build(element) {\n if (element || this.element) {\n return this.ready.then(() => {\n element = element || this.element;\n super.build(element);\n });\n }\n return this.ready;\n }\n getClassName() {\n let classes = 'formio-form';\n if (this.options.readOnly) {\n classes += ' formio-read-only';\n }\n return classes;\n }\n render() {\n return super.render(this.renderTemplate('webform', {\n classes: this.getClassName(),\n children: this.renderComponents(),\n }), this.builderMode ? 'builder' : 'form', true);\n }\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element) {\n return Promise.resolve();\n }\n this.clear();\n this.setContent(this.element, this.render());\n return this.attach(this.element);\n }\n attach(element) {\n this.setElement(element);\n this.loadRefs(element, { webform: 'single' });\n const childPromise = this.attachComponents(this.refs.webform);\n this.addEventListener(document, 'keydown', this.executeShortcuts);\n this.currentForm = this;\n this.hook('attachWebform', element, this);\n return childPromise.then(() => {\n this.emit('render', this.element);\n return this.setValue(this._submission, {\n noUpdateEvent: true,\n });\n });\n }\n hasRequiredFields() {\n let result = false;\n (0, formUtils_1.eachComponent)(this.form.components, (component) => {\n if (component.validate.required) {\n result = true;\n return true;\n }\n }, true);\n return result;\n }\n resetValue() {\n lodash_1.default.each(this.getComponents(), (comp) => (comp.resetValue()));\n this.setPristine(true);\n this.onChange({ resetValue: true });\n }\n /**\n * Sets a new alert to display in the error dialog of the form.\n *\n * @param {string} type - The type of alert to display. \"danger\", \"success\", \"warning\", etc.\n * @param {string} message - The message to show in the alert.\n * @param {Object} options\n */\n setAlert(type, message, options) {\n if (!type && this.submitted) {\n if (this.alert) {\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.removeEventListener(el, 'click');\n this.removeEventListener(el, 'keypress');\n });\n }\n this.removeChild(this.alert);\n this.alert = null;\n }\n return;\n }\n if (this.options.noAlerts) {\n if (!message) {\n this.emit('error', false);\n }\n return;\n }\n if (this.alert) {\n try {\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.removeEventListener(el, 'click');\n this.removeEventListener(el, 'keypress');\n });\n }\n this.removeChild(this.alert);\n this.alert = null;\n }\n catch (err) {\n // ignore\n }\n }\n if (message) {\n const attrs = {\n class: (options && options.classes) || `alert alert-${type}`,\n id: `error-list-${this.id}`,\n };\n const templateOptions = {\n message: message instanceof HTMLElement ? message.outerHTML : message,\n attrs: attrs,\n type\n };\n this.alert = (0, utils_1.convertStringToHTMLElement)(this.renderTemplate('alert', templateOptions), `#${attrs.id}`);\n }\n if (!this.alert) {\n return;\n }\n this.loadRefs(this.alert, { errorRef: 'multiple' });\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.addEventListener(el, 'click', (e) => {\n const key = e.currentTarget.dataset.componentKey;\n this.focusOnComponent(key);\n });\n this.addEventListener(el, 'keydown', (e) => {\n if (e.keyCode === 13) {\n e.preventDefault();\n const key = e.currentTarget.dataset.componentKey;\n this.focusOnComponent(key);\n }\n });\n });\n }\n this.prepend(this.alert);\n }\n /**\n * Focus on selected component.\n *\n * @param {string} key - The key of selected component.\n * @returns {*}\n */\n focusOnComponent(key) {\n if (key) {\n const component = this.getComponent(key);\n if (component) {\n component.focus();\n }\n }\n }\n /**\n * Show the errors of this form within the alert dialog.\n *\n * @param {Object} error - An optional additional error to display along with the component errors.\n * @returns {*}\n */\n /* eslint-disable no-unused-vars */\n showErrors(errors, triggerEvent) {\n this.loading = false;\n if (!Array.isArray(errors)) {\n errors = [errors];\n }\n errors = errors.concat(this.customErrors).filter((err) => !!err);\n if (!errors.length) {\n this.setAlert(false);\n return;\n }\n // Mark any components as invalid if in a custom message.\n errors.forEach((err) => {\n const { components = [] } = err;\n if (err.component) {\n components.push(err.component);\n }\n if (err.path) {\n components.push(err.path);\n }\n components.forEach((path) => {\n const originalPath = (0, utils_1.getStringFromComponentPath)(path);\n const component = this.getComponent(path, lodash_1.default.identity, originalPath);\n if (err.fromServer) {\n if (component.serverErrors) {\n component.serverErrors.push(err);\n }\n else {\n component.serverErrors = [err];\n }\n }\n const components = lodash_1.default.compact(Array.isArray(component) ? component : [component]);\n components.forEach((component) => component.setCustomValidity(err.message, true));\n });\n });\n const displayedErrors = [];\n if (errors.length) {\n errors = lodash_1.default.uniqBy(errors, error => error.message);\n const createListItem = (message, index) => {\n var _a, _b, _c;\n const err = errors[index];\n const messageFromIndex = !lodash_1.default.isUndefined(index) && errors && errors[index];\n const keyOrPath = ((messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.formattedKeyOrPath) || (messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.path) || ((_a = messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.context) === null || _a === void 0 ? void 0 : _a.path)) || (((_b = err.context) === null || _b === void 0 ? void 0 : _b.component) && ((_c = err.context) === null || _c === void 0 ? void 0 : _c.component.key)) || (err.component && err.component.key) || err.fromServer && err.path;\n const formattedKeyOrPath = keyOrPath ? (0, utils_1.getStringFromComponentPath)(keyOrPath) : '';\n if (typeof err !== 'string' && !err.formattedKeyOrPath) {\n err.formattedKeyOrPath = formattedKeyOrPath;\n }\n return {\n message: (0, utils_1.unescapeHTML)(message),\n keyOrPath: formattedKeyOrPath\n };\n };\n errors.forEach(({ message, context, fromServer, component }, index) => {\n const text = !(component === null || component === void 0 ? void 0 : component.label) || (context === null || context === void 0 ? void 0 : context.hasLabel) || fromServer\n ? this.t('alertMessage', { message: this.t(message) })\n : this.t('alertMessageWithLabel', {\n label: this.t(component === null || component === void 0 ? void 0 : component.label),\n message: this.t(message),\n });\n displayedErrors.push(createListItem(text, index));\n });\n }\n const errorsList = this.renderTemplate('errorsList', { errors: displayedErrors });\n this.root.setAlert('danger', errorsList);\n if (triggerEvent) {\n this.emit('error', errors);\n }\n return errors;\n }\n /* eslint-enable no-unused-vars */\n /**\n * Called when the submission has completed, or if the submission needs to be sent to an external library.\n *\n * @param {Object} submission - The submission object.\n * @param {boolean} saved - Whether or not this submission was saved to the server.\n * @returns {object} - The submission object.\n */\n onSubmit(submission, saved) {\n var _a;\n this.loading = false;\n this.submitting = false;\n this.setPristine(true);\n // We want to return the submitted submission and setValue will mutate the submission so cloneDeep it here.\n this.setValue((0, utils_1.fastCloneDeep)(submission), {\n noValidate: true,\n noCheck: true\n });\n this.setAlert('success', `<p>${this.t('complete')}</p>`);\n // Cancel triggered saveDraft to prevent overriding the submitted state\n if (this.draftEnabled && ((_a = this.triggerSaveDraft) === null || _a === void 0 ? void 0 : _a.cancel)) {\n this.triggerSaveDraft.cancel();\n }\n this.emit('submit', submission, saved);\n if (saved) {\n this.emit('submitDone', submission);\n }\n return submission;\n }\n normalizeError(error) {\n if (error) {\n if (typeof error === 'object' && 'details' in error) {\n error = error.details;\n }\n if (typeof error === 'string') {\n error = { message: error };\n }\n }\n return error;\n }\n /**\n * Called when an error occurs during the submission.\n *\n * @param {Object} error - The error that occured.\n */\n onSubmissionError(error) {\n error = this.normalizeError(error);\n this.submitting = false;\n this.setPristine(false);\n this.emit('submitError', error || this.errors);\n // Allow for silent cancellations (no error message, no submit button error state)\n if (error && error.silent) {\n this.emit('change', { isValid: true }, { silent: true });\n return false;\n }\n const errors = this.showErrors(error, true);\n if (this.root && this.root.alert) {\n this.scrollIntoView(this.root.alert);\n }\n return errors;\n }\n /**\n * Trigger the change event for this form.\n *\n * @param changed\n * @param flags\n */\n onChange(flags, changed, modified, changes) {\n flags = flags || {};\n let isChangeEventEmitted = false;\n super.onChange(flags, true);\n const value = lodash_1.default.clone(this.submission);\n flags.changed = value.changed = changed;\n flags.changes = changes;\n if (modified && this.pristine) {\n this.pristine = false;\n }\n this.checkData(value.data, flags);\n const shouldValidate = !flags.noValidate || flags.fromIFrame || (flags.fromSubmission && this.rootPristine && this.pristine && flags.changed);\n const errors = shouldValidate ? this.validate(value.data, Object.assign(Object.assign({}, flags), { process: 'change' })) : [];\n value.isValid = errors.length === 0;\n this.loading = false;\n if (this.submitted) {\n // show server errors while they are not cleaned/fixed\n const nonComponentServerErrors = lodash_1.default.filter(this.serverErrors || [], err => !err.component && !err.path);\n this.showErrors(nonComponentServerErrors.length ? nonComponentServerErrors : errors);\n }\n // See if we need to save the draft of the form.\n if (modified && this.options.saveDraft) {\n this.triggerSaveDraft();\n }\n if (!flags || !flags.noEmit) {\n this.emit('change', value, flags, modified);\n isChangeEventEmitted = true;\n }\n // The form is initialized after the first change event occurs.\n if (isChangeEventEmitted && !this.initialized) {\n this.emit('initialized');\n this.initialized = true;\n }\n }\n /**\n * Send a delete request to the server.\n */\n deleteSubmission() {\n return this.formio.deleteSubmission()\n .then(() => {\n this.emit('submissionDeleted', this.submission);\n this.resetValue();\n });\n }\n /**\n * Cancels the submission.\n *\n * @alias reset\n */\n cancel(noconfirm) {\n const shouldReset = this.hook('beforeCancel', true);\n if (shouldReset && (noconfirm || confirm(this.t('confirmCancel')))) {\n this.resetValue();\n return true;\n }\n else {\n this.emit('cancelSubmit');\n return false;\n }\n }\n setMetadata(submission) {\n // Add in metadata about client submitting the form\n submission.metadata = submission.metadata || {};\n lodash_1.default.defaults(submission.metadata, {\n timezone: lodash_1.default.get(this, '_submission.metadata.timezone', (0, utils_1.currentTimezone)()),\n offset: parseInt(lodash_1.default.get(this, '_submission.metadata.offset', (0, moment_1.default)().utcOffset()), 10),\n origin: document.location.origin,\n referrer: document.referrer,\n browserName: navigator.appName,\n userAgent: navigator.userAgent,\n pathName: window.location.pathname,\n onLine: navigator.onLine\n });\n }\n submitForm(options = {}) {\n this.clearServerErrors();\n return new Promise((resolve, reject) => {\n // Read-only forms should never submit.\n if (this.options.readOnly) {\n return resolve({\n submission: this.submission,\n saved: false\n });\n }\n const submission = (0, utils_1.fastCloneDeep)(this.submission || {});\n this.setMetadata(submission);\n submission.state = options.state || submission.state || 'submitted';\n const isDraft = (submission.state === 'draft');\n this.hook('beforeSubmit', Object.assign(Object.assign({}, submission), { component: options.component }), (err, data) => {\n var _a;\n if (err) {\n return reject(err);\n }\n submission._vnote = data && data._vnote ? data._vnote : '';\n try {\n if (!isDraft && !options.noValidate) {\n if (!submission.data) {\n return reject('Invalid Submission');\n }\n const errors = this.validate(submission.data, {\n dirty: true,\n silentCheck: false,\n process: 'submit'\n });\n if (errors.length || ((_a = options.beforeSubmitResults) === null || _a === void 0 ? void 0 : _a.some((result) => result.status === 'rejected'))) {\n return reject(errors);\n }\n }\n }\n catch (err) {\n console.error(err);\n }\n this.everyComponent((comp) => {\n if (submission._vnote && comp.type === 'form' && comp.component.reference) {\n lodash_1.default.get(submission.data, comp.path, {})._vnote = submission._vnote;\n }\n const { persistent } = comp.component;\n if (persistent === 'client-only') {\n lodash_1.default.unset(submission.data, comp.path);\n }\n });\n this.hook('customValidation', Object.assign(Object.assign({}, submission), { component: options.component }), (err) => {\n if (err) {\n // If string is returned, cast to object.\n if (typeof err === 'string') {\n err = {\n message: err\n };\n }\n // Ensure err is an array.\n err = Array.isArray(err) ? err : [err];\n return reject(err);\n }\n this.loading = true;\n // Use the form action to submit the form if available.\n if (this._form && this._form.action) {\n const method = (submission.data._id && this._form.action.includes(submission.data._id)) ? 'PUT' : 'POST';\n return Formio_1.Formio.makeStaticRequest(this._form.action, method, submission, this.formio ? this.formio.options : {})\n .then((result) => resolve({\n submission: result,\n saved: true,\n }))\n .catch((error) => {\n this.setServerErrors(error);\n return reject(error);\n });\n }\n const submitFormio = this.formio;\n if (this.nosubmit || !submitFormio) {\n return resolve({\n submission,\n saved: false,\n });\n }\n // If this is an actionUrl, then make sure to save the action and not the submission.\n const submitMethod = submitFormio.actionUrl ? 'saveAction' : 'saveSubmission';\n submitFormio[submitMethod](submission)\n .then((result) => resolve({\n submission: result,\n saved: true,\n }))\n .catch((error) => {\n this.setServerErrors(error);\n return reject(error);\n });\n });\n });\n });\n }\n setServerErrors(error) {\n if (error.details) {\n this.serverErrors = error.details.filter((err) => err.level ? err.level === 'error' : err).map((err) => {\n err.fromServer = true;\n return err;\n });\n }\n else if (typeof error === 'string') {\n this.serverErrors = [{ fromServer: true, level: 'error', message: error }];\n }\n }\n executeSubmit(options) {\n this.submitted = true;\n this.submitting = true;\n return this.submitForm(options)\n .then(({ submission, saved }) => this.onSubmit(submission, saved))\n .then((results) => {\n this.submissionInProcess = false;\n return results;\n })\n .catch((err) => {\n this.submissionInProcess = false;\n return Promise.reject(this.onSubmissionError(err));\n });\n }\n clearServerErrors() {\n var _a;\n (_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.forEach((error) => {\n if (error.path) {\n const pathArray = (0, utils_1.getArrayFromComponentPath)(error.path);\n const component = this.getComponent(pathArray, lodash_1.default.identity, error.formattedKeyOrPath);\n if (component) {\n component.serverErrors = [];\n }\n }\n });\n this.serverErrors = [];\n }\n /**\n * Submits the form.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.src = 'https://examples.form.io/example';\n * form.submission = {data: {\n * firstName: 'Joe',\n * lastName: 'Smith',\n * email: 'joe@example.com'\n * }};\n * form.submit().then((submission) => {\n * console.log(submission);\n * });\n *\n * @param {boolean} before - If this submission occured from the before handlers.\n *\n * @returns {Promise} - A promise when the form is done submitting.\n */\n submit(before, options = {}) {\n this.submissionInProcess = true;\n if (!before) {\n return this.beforeSubmit(options).then(() => this.executeSubmit(options));\n }\n else {\n return this.executeSubmit(options);\n }\n }\n submitUrl(URL, headers) {\n if (!URL) {\n return console.warn('Missing URL argument');\n }\n const submission = this.submission || {};\n const API_URL = URL;\n const settings = {\n method: 'POST',\n headers: {}\n };\n if (headers && headers.length > 0) {\n headers.map((e) => {\n if (e.header !== '' && e.value !== '') {\n settings.headers[e.header] = this.interpolate(e.value, submission);\n }\n });\n }\n if (API_URL && settings) {\n Formio_1.Formio.makeStaticRequest(API_URL, settings.method, submission, { headers: settings.headers }).then(() => {\n this.emit('requestDone');\n this.setAlert('success', '<p> Success </p>');\n }).catch((e) => {\n const message = `${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`;\n this.emit('error', message);\n console.error(message);\n this.setAlert('danger', `<p> ${message} </p>`);\n return Promise.reject(this.onSubmissionError(e));\n });\n }\n else {\n this.emit('error', 'You should add a URL to this button.');\n this.setAlert('warning', 'You should add a URL to this button.');\n return console.warn('You should add a URL to this button.');\n }\n }\n triggerRecaptcha() {\n if (!this || !this.components) {\n return;\n }\n const recaptchaComponent = (0, utils_1.searchComponents)(this.components, {\n 'component.type': 'recaptcha',\n 'component.eventType': 'formLoad'\n });\n if (recaptchaComponent.length > 0) {\n recaptchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);\n }\n }\n set nosubmit(value) {\n this._nosubmit = !!value;\n this.emit('nosubmit', this._nosubmit);\n }\n get nosubmit() {\n return this._nosubmit || false;\n }\n get conditions() {\n var _a, _b;\n return (_b = (_a = this.schema.settings) === null || _a === void 0 ? void 0 : _a.conditions) !== null && _b !== void 0 ? _b : [];\n }\n get variables() {\n var _a, _b;\n return (_b = (_a = this.schema.settings) === null || _a === void 0 ? void 0 : _a.variables) !== null && _b !== void 0 ? _b : [];\n }\n}\nexports[\"default\"] = Webform;\nWebform.setBaseUrl = Formio_1.Formio.setBaseUrl;\nWebform.setApiUrl = Formio_1.Formio.setApiUrl;\nWebform.setAppUrl = Formio_1.Formio.setAppUrl;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Webform.js?");
|
5388
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst moment_1 = __importDefault(__webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"));\nconst compare_versions_1 = __webpack_require__(/*! compare-versions */ \"./node_modules/compare-versions/lib/esm/index.js\");\nconst core_1 = __webpack_require__(/*! @formio/core */ \"./node_modules/@formio/core/lib/index.js\");\nconst EventEmitter_1 = __importDefault(__webpack_require__(/*! ./EventEmitter */ \"./lib/cjs/EventEmitter.js\"));\nconst i18n_1 = __importDefault(__webpack_require__(/*! ./i18n */ \"./lib/cjs/i18n.js\"));\nconst Formio_1 = __webpack_require__(/*! ./Formio */ \"./lib/cjs/Formio.js\");\nconst Components_1 = __importDefault(__webpack_require__(/*! ./components/Components */ \"./lib/cjs/components/Components.js\"));\nconst NestedDataComponent_1 = __importDefault(__webpack_require__(/*! ./components/_classes/nesteddata/NestedDataComponent */ \"./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js\"));\nconst utils_1 = __webpack_require__(/*! ./utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst formUtils_1 = __webpack_require__(/*! ./utils/formUtils */ \"./lib/cjs/utils/formUtils.js\");\n// Initialize the available forms.\nFormio_1.Formio.forms = {};\n// Allow people to register components.\nFormio_1.Formio.registerComponent = Components_1.default.setComponent;\nfunction getIconSet(icons) {\n if (icons === 'fontawesome') {\n return 'fa';\n }\n return icons || '';\n}\nfunction getOptions(options) {\n options = lodash_1.default.defaults(options, {\n submitOnEnter: false,\n iconset: getIconSet((options && options.icons) ? options.icons : Formio_1.Formio.icons),\n i18next: null,\n saveDraft: false,\n alwaysDirty: false,\n saveDraftThrottle: 5000,\n display: 'form',\n cdnUrl: Formio_1.Formio.cdn.baseUrl\n });\n if (!options.events) {\n options.events = new EventEmitter_1.default();\n }\n return options;\n}\n/**\n * Represents a JSON value.\n * @typedef {(string | number | boolean | null | JSONArray | JSONObject)} JSON\n */\n/**\n * Represents a JSON array.\n * @typedef {Array<JSON>} JSONArray\n */\n/**\n * Represents a JSON object.\n * @typedef {{[key: string]: JSON}} JSONObject\n */\n/**\n * @typedef {Object} FormioHooks\n * @property {function} [beforeSubmit]\n * @property {function} [beforeCancel]\n * @property {function} [beforeNext]\n * @property {function} [beforePrev]\n * @property {function} [attachComponent]\n * @property {function} [setDataValue]\n * @property {function} [addComponents]\n * @property {function} [addComponent]\n * @property {function} [customValidation]\n * @property {function} [attachWebform]\n */\n/**\n * @typedef {Object} SanitizeConfig\n * @property {string[]} [addAttr]\n * @property {string[]} [addTags]\n * @property {string[]} [allowedAttrs]\n * @property {string[]} [allowedTags]\n * @property {string[]} [allowedUriRegex]\n * @property {string[]} [addUriSafeAttr]\n */\n/**\n * @typedef {Object} ButtonSettings\n * @property {boolean} [showPrevious]\n * @property {boolean} [showNext]\n * @property {boolean} [showCancel]\n * @property {boolean} [showSubmit]\n */\n/**\n * @typedef {Object} FormOptions\n * @property {boolean} [saveDraft] - Enable the save draft feature.\n * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.\n * @property {boolean} [readOnly] - Set this form to readOnly.\n * @property {boolean} [noAlerts] - Disable the alerts dialog.\n * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.\n * @property {string} [template] - Custom logic for creation of elements.\n * @property {boolean} [noDefaults] - Exclude default values from the settings.\n * @property {any} [fileService] - The file service for this form.\n * @property {EventEmitter} [events] - The EventEmitter for this form.\n * @property {string} [language] - The language to render this form in.\n * @property {{[key: string]: string}} [i18next] - The i18next configuration for this form.\n * @property {boolean} [viewAsHtml] - View the form as raw HTML.\n * @property {'form' | 'html' | 'flat' | 'builder' | 'pdf'} [renderMode] - The render mode for this form.\n * @property {boolean} [highlightErrors] - Highlight any errors on the form.\n * @property {string} [componentErrorClass] - The error class for components.\n * @property {any} [templates] - The templates for this form.\n * @property {string} [iconset] - The iconset for this form.\n * @property {Component[]} [components] - The components for this form.\n * @property {{[key: string]: boolean}} [disabled] - Disabled components for this form.\n * @property {boolean} [showHiddenFields] - Show hidden fields.\n * @property {{[key: string]: boolean}} [hide] - Hidden components for this form.\n * @property {{[key: string]: boolean}} [show] - Components to show for this form.\n * @property {Formio} [formio] - The Formio instance for this form.\n * @property {string} [decimalSeparator] - The decimal separator for this form.\n * @property {string} [thousandsSeparator] - The thousands separator for this form.\n * @property {FormioHooks} [hooks] - The hooks for this form.\n * @property {boolean} [alwaysDirty] - Always be dirty.\n * @property {boolean} [skipDraftRestore] - Skip restoring a draft.\n * @property {'form' | 'wizard' | 'pdf'} [display] - The display for this form.\n * @property {string} [cdnUrl] - The CDN url for this form.\n * @property {boolean} [flatten] - Flatten the form.\n * @property {boolean} [sanitize] - Sanitize the form.\n * @property {SanitizeConfig} [sanitizeConfig] - The sanitize configuration for this form.\n * @property {ButtonSettings} [buttonSettings] - The button settings for this form.\n * @property {Object} [breadCrumbSettings] - The breadcrumb settings for this form.\n * @property {boolean} [allowPrevious] - Allow the previous button (for Wizard forms).\n * @property {string[]} [wizardButtonOrder] - The order of the buttons (for Wizard forms).\n * @property {boolean} [showCheckboxBackground] - Show the checkbox background.\n * @property {boolean} [inputsOnly] - Only show inputs in the form and no labels.\n * @property {boolean} [building] - If we are in the process of building the form.\n * @property {number} [zoom] - The zoom for PDF forms.\n */\n/**\n * Renders a Form.io form within the webpage.\n */\nclass Webform extends NestedDataComponent_1.default {\n /**\n * Creates a new Form instance.\n *\n * @param {HTMLElement | Object | FormOptions} [elementOrOptions] - The DOM element to render this form within or the options to create this form instance.\n * @param {FormOptions} [options] - The options to create a new form instance.\n */\n constructor(elementOrOptions, options) {\n let element, formOptions;\n if (elementOrOptions instanceof HTMLElement || options) {\n element = elementOrOptions;\n formOptions = options;\n }\n else {\n formOptions = elementOrOptions;\n }\n super(null, getOptions(formOptions));\n this.executeShortcuts = (event) => {\n const { target } = event;\n if (!this.keyboardCatchableElement(target)) {\n return;\n }\n const ctrl = event.ctrlKey || event.metaKey;\n const keyCode = event.keyCode;\n let char = '';\n if (65 <= keyCode && keyCode <= 90) {\n char = String.fromCharCode(keyCode);\n }\n else if (keyCode === 13) {\n char = 'Enter';\n }\n else if (keyCode === 27) {\n char = 'Esc';\n }\n lodash_1.default.each(this.shortcuts, (shortcut) => {\n if (shortcut.ctrl && !ctrl) {\n return;\n }\n if (shortcut.shortcut === char) {\n shortcut.element.click();\n event.preventDefault();\n }\n });\n };\n this.setElement(element);\n // Keep track of all available forms globally.\n Formio_1.Formio.forms[this.id] = this;\n // Set the base url.\n if (this.options.baseUrl) {\n Formio_1.Formio.setBaseUrl(this.options.baseUrl);\n }\n /**\n * The type of this element.\n * @type {string}\n */\n this.type = 'form';\n this._src = '';\n this._loading = false;\n this._form = {};\n this.draftEnabled = false;\n this.savingDraft = true;\n if (this.options.saveDraftThrottle) {\n this.triggerSaveDraft = lodash_1.default.throttle(this.saveDraft.bind(this), this.options.saveDraftThrottle);\n }\n else {\n this.triggerSaveDraft = this.saveDraft.bind(this);\n }\n /**\n * Determines if this form should submit the API on submit.\n * @type {boolean}\n */\n this.nosubmit = false;\n /**\n * Determines if the form has tried to be submitted, error or not.\n *\n * @type {boolean}\n */\n this.submitted = false;\n /**\n * Determines if the form is being submitted at the moment.\n *\n * @type {boolean}\n */\n this.submitting = false;\n /**\n * The Formio instance for this form.\n * @type {Formio}\n */\n this.formio = null;\n /**\n * The loader HTML element.\n * @type {HTMLElement}\n */\n this.loader = null;\n /**\n * The alert HTML element\n * @type {HTMLElement}\n */\n this.alert = null;\n /**\n * Promise that is triggered when the submission is done loading.\n * @type {Promise}\n */\n this.onSubmission = null;\n /**\n * Determines if this submission is explicitly set.\n * @type {boolean}\n */\n this.submissionSet = false;\n /**\n * Promise that executes when the form is ready and rendered.\n * @type {Promise}\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.formReady.then(() => {\n * console.log('The form is ready!');\n * });\n * form.src = 'https://examples.form.io/example';\n */\n this.formReady = new Promise((resolve, reject) => {\n /**\n * Called when the formReady state of this form has been resolved.\n *\n * @type {function}\n */\n this.formReadyResolve = resolve;\n /**\n * Called when this form could not load and is rejected.\n *\n * @type {function}\n */\n this.formReadyReject = reject;\n });\n /**\n * Promise that executes when the submission is ready and rendered.\n * @type {Promise}\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.submissionReady.then(() => {\n * console.log('The submission is ready!');\n * });\n * form.src = 'https://examples.form.io/example/submission/234234234234234243';\n */\n this.submissionReady = new Promise((resolve, reject) => {\n /**\n * Called when the formReady state of this form has been resolved.\n *\n * @type {function}\n */\n this.submissionReadyResolve = resolve;\n /**\n * Called when this form could not load and is rejected.\n *\n * @type {function}\n */\n this.submissionReadyReject = reject;\n });\n this.shortcuts = [];\n // Set language after everything is established.\n this.language = this.i18next.language;\n // See if we need to restore the draft from a user.\n if (this.options.saveDraft && !this.options.skipDraftRestore) {\n this.formReady.then(() => {\n const user = Formio_1.Formio.getUser();\n // Only restore a draft if the submission isn't explicitly set.\n if (user && !this.submissionSet) {\n this.restoreDraft(user._id);\n }\n });\n }\n this.component.clearOnHide = false;\n // Ensure the root is set to this component.\n this.root = this;\n this.localRoot = this;\n }\n /* eslint-enable max-statements */\n get language() {\n return this.options.language;\n }\n get emptyValue() {\n return null;\n }\n componentContext() {\n return this._data;\n }\n /**\n * Sets the language for this form.\n *\n * @param lang\n * @return {Promise}\n */\n set language(lang) {\n if (!this.i18next) {\n return;\n }\n this.options.language = lang;\n if (this.i18next.language === lang) {\n return;\n }\n this.i18next.changeLanguage(lang, (err) => {\n if (err) {\n return;\n }\n this.rebuild();\n this.emit('languageChanged');\n });\n }\n get componentComponents() {\n return this.form.components;\n }\n get shadowRoot() {\n return this.options.shadowRoot;\n }\n /**\n * Add a language for translations\n *\n * @param code\n * @param lang\n * @param active\n * @return {*}\n */\n addLanguage(code, lang, active = false) {\n if (this.i18next) {\n var translations = lodash_1.default.assign((0, utils_1.fastCloneDeep)(i18n_1.default.resources.en.translation), lang);\n this.i18next.addResourceBundle(code, 'translation', translations, true, true);\n if (active) {\n this.language = code;\n }\n }\n }\n keyboardCatchableElement(element) {\n if (element.nodeName === 'TEXTAREA') {\n return false;\n }\n if (element.nodeName === 'INPUT') {\n return [\n 'text',\n 'email',\n 'password'\n ].indexOf(element.type) === -1;\n }\n return true;\n }\n addShortcut(element, shortcut) {\n if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {\n return;\n }\n shortcut = lodash_1.default.capitalize(shortcut);\n if (shortcut === 'Enter' || shortcut === 'Esc') {\n // Restrict Enter and Esc only for buttons\n if (element.tagName !== 'BUTTON') {\n return;\n }\n this.shortcuts.push({\n shortcut,\n element\n });\n }\n else {\n this.shortcuts.push({\n ctrl: true,\n shortcut,\n element\n });\n }\n }\n removeShortcut(element, shortcut) {\n if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {\n return;\n }\n lodash_1.default.remove(this.shortcuts, {\n shortcut,\n element\n });\n }\n /**\n * Get the embed source of the form.\n *\n * @returns {string}\n */\n get src() {\n return this._src;\n }\n /**\n * Loads the submission if applicable.\n */\n loadSubmission() {\n this.loadingSubmission = true;\n if (this.formio.submissionId) {\n this.onSubmission = this.formio.loadSubmission().then((submission) => this.setSubmission(submission), (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));\n }\n else {\n this.submissionReadyResolve();\n }\n return this.submissionReady;\n }\n /**\n * Set the src of the form renderer.\n *\n * @param value\n * @param options\n */\n setSrc(value, options) {\n if (this.setUrl(value, options)) {\n this.nosubmit = false;\n return this.formio.loadForm({ params: { live: 1 } }).then((form) => {\n const setForm = this.setForm(form);\n this.loadSubmission();\n return setForm;\n }).catch((err) => {\n console.warn(err);\n this.formReadyReject(err);\n });\n }\n return Promise.resolve();\n }\n /**\n * Set the Form source, which is typically the Form.io embed URL.\n *\n * @param {string} value - The value of the form embed url.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.formReady.then(() => {\n * console.log('The form is formReady!');\n * });\n * form.src = 'https://examples.form.io/example';\n */\n set src(value) {\n this.setSrc(value);\n }\n /**\n * Get the embed source of the form.\n *\n * @returns {string}\n */\n get url() {\n return this._src;\n }\n /**\n * Sets the url of the form renderer.\n *\n * @param value\n * @param options\n */\n setUrl(value, options) {\n if (!value ||\n (typeof value !== 'string') ||\n (value === this._src)) {\n return false;\n }\n this._src = value;\n this.nosubmit = true;\n this.formio = this.options.formio = new Formio_1.Formio(value, options);\n if (this.type === 'form') {\n // Set the options source so this can be passed to other components.\n this.options.src = value;\n }\n return true;\n }\n /**\n * Set the form source but don't initialize the form and submission from the url.\n *\n * @param {string} value - The value of the form embed url.\n */\n set url(value) {\n this.setUrl(value);\n }\n /**\n * Called when both the form and submission have been loaded.\n *\n * @returns {Promise} - The promise to trigger when both form and submission have loaded.\n */\n get ready() {\n return this.formReady.then(() => {\n return super.ready.then(() => {\n return this.loadingSubmission ? this.submissionReady : true;\n });\n });\n }\n /**\n * Returns if this form is loading.\n *\n * @returns {boolean} - TRUE means the form is loading, FALSE otherwise.\n */\n get loading() {\n return this._loading;\n }\n /**\n * Set the loading state for this form, and also show the loader spinner.\n *\n * @param {boolean} loading - If this form should be \"loading\" or not.\n */\n set loading(loading) {\n if (this._loading !== loading) {\n this._loading = loading;\n if (!this.loader && loading) {\n this.loader = this.ce('div', {\n class: 'loader-wrapper'\n });\n const spinner = this.ce('div', {\n class: 'loader text-center'\n });\n this.loader.appendChild(spinner);\n }\n /* eslint-disable max-depth */\n if (this.loader) {\n try {\n if (loading) {\n this.prependTo(this.loader, this.wrapper);\n }\n else {\n this.removeChildFrom(this.loader, this.wrapper);\n }\n }\n catch (err) {\n // ingore\n }\n }\n /* eslint-enable max-depth */\n }\n }\n /**\n * Sets the JSON schema for the form to be rendered.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.setForm({\n * components: [\n * {\n * type: 'textfield',\n * key: 'firstName',\n * label: 'First Name',\n * placeholder: 'Enter your first name.',\n * input: true\n * },\n * {\n * type: 'textfield',\n * key: 'lastName',\n * label: 'Last Name',\n * placeholder: 'Enter your last name',\n * input: true\n * },\n * {\n * type: 'button',\n * action: 'submit',\n * label: 'Submit',\n * theme: 'primary'\n * }\n * ]\n * });\n *\n * @param {Object} form - The JSON schema of the form @see https://examples.form.io/example for an example JSON schema.\n * @param flags\n * @returns {*}\n */\n setForm(form, flags) {\n var _a, _b, _c;\n const isFormAlreadySet = this._form && ((_a = this._form.components) === null || _a === void 0 ? void 0 : _a.length);\n try {\n // Do not set the form again if it has been already set\n if (isFormAlreadySet && JSON.stringify(this._form) === JSON.stringify(form)) {\n return Promise.resolve();\n }\n // Create the form.\n this._form = (flags === null || flags === void 0 ? void 0 : flags.keepAsReference) ? form : lodash_1.default.cloneDeep(form);\n if (this.onSetForm) {\n this.onSetForm(lodash_1.default.cloneDeep(this._form), form);\n }\n if ((_c = (_b = this.parent) === null || _b === void 0 ? void 0 : _b.component) === null || _c === void 0 ? void 0 : _c.modalEdit) {\n return Promise.resolve();\n }\n }\n catch (err) {\n console.warn(err);\n // If provided form is not a valid JSON object, do not set it too\n return Promise.resolve();\n }\n // Allow the form to provide component overrides.\n if (form && form.settings && form.settings.components) {\n this.options.components = form.settings.components;\n }\n if (form && form.properties) {\n this.options.properties = form.properties;\n }\n // Use the sanitize config from the form settings or the global sanitize config if it is not provided in the options\n if (!this.options.sanitizeConfig && !this.builderMode) {\n this.options.sanitizeConfig = lodash_1.default.get(form, 'settings.sanitizeConfig') || lodash_1.default.get(form, 'globalSettings.sanitizeConfig');\n }\n if ('schema' in form && (0, compare_versions_1.compareVersions)(form.schema, '1.x') > 0) {\n this.ready.then(() => {\n this.setAlert('alert alert-danger', 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.');\n });\n }\n // See if they pass a module, and evaluate it if so.\n if (form && form.module) {\n let formModule = null;\n if (typeof form.module === 'string') {\n try {\n formModule = this.evaluate(`return ${form.module}`);\n }\n catch (err) {\n console.warn(err);\n }\n }\n else {\n formModule = form.module;\n }\n if (formModule) {\n Formio_1.Formio.use(formModule);\n // Since we got here after instantiation, we need to manually apply form options.\n if (formModule.options && formModule.options.form) {\n this.options = Object.assign(this.options, formModule.options.form);\n }\n }\n }\n this.initialized = false;\n const rebuild = this.rebuild() || Promise.resolve();\n return rebuild.then(() => {\n this.emit('formLoad', form);\n this.triggerRecaptcha();\n // Make sure to trigger onChange after a render event occurs to speed up form rendering.\n setTimeout(() => {\n this.onChange(flags);\n this.formReadyResolve();\n }, 0);\n return this.formReady;\n });\n }\n /**\n * Gets the form object.\n *\n * @returns {Object} - The form JSON schema.\n */\n get form() {\n if (!this._form) {\n this._form = {\n components: []\n };\n }\n return this._form;\n }\n /**\n * Sets the form value.\n *\n * @alias setForm\n * @param {Object} form - The form schema object.\n */\n set form(form) {\n this.setForm(form);\n }\n /**\n * Returns the submission object that was set within this form.\n *\n * @returns {Object}\n */\n get submission() {\n return this.getValue();\n }\n /**\n * Sets the submission of a form.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.src = 'https://examples.form.io/example';\n * form.submission = {data: {\n * firstName: 'Joe',\n * lastName: 'Smith',\n * email: 'joe@example.com'\n * }};\n *\n * @param {Object} submission - The Form.io submission object.\n */\n set submission(submission) {\n this.setSubmission(submission);\n }\n /**\n * Sets a submission and returns the promise when it is ready.\n * @param submission\n * @param flags\n * @return {Promise.<TResult>}\n */\n setSubmission(submission, flags = {}) {\n flags = Object.assign(Object.assign({}, flags), { fromSubmission: lodash_1.default.has(flags, 'fromSubmission') ? flags.fromSubmission : true });\n return this.onSubmission = this.formReady.then((resolveFlags) => {\n if (resolveFlags) {\n flags = Object.assign(Object.assign({}, flags), resolveFlags);\n }\n this.submissionSet = true;\n this.triggerChange(flags);\n this.emit('beforeSetSubmission', submission);\n this.setValue(submission, flags);\n return this.submissionReadyResolve(submission);\n }, (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));\n }\n handleDraftError(errName, errDetails, restoreDraft) {\n const errorMessage = lodash_1.default.trim(`${this.t(errName)} ${errDetails || ''}`);\n console.warn(errorMessage);\n this.emit(restoreDraft ? 'restoreDraftError' : 'saveDraftError', errDetails || errorMessage);\n }\n /**\n * Saves a submission draft.\n */\n saveDraft() {\n if (!this.draftEnabled) {\n return;\n }\n if (!this.formio) {\n this.handleDraftError('saveDraftInstanceError');\n return;\n }\n if (!Formio_1.Formio.getUser()) {\n this.handleDraftError('saveDraftAuthError');\n return;\n }\n const draft = (0, utils_1.fastCloneDeep)(this.submission);\n draft.state = 'draft';\n if (!this.savingDraft) {\n this.emit('saveDraftBegin');\n this.savingDraft = true;\n this.formio.saveSubmission(draft).then((sub) => {\n // Set id to submission to avoid creating new draft submission\n this.submission._id = sub._id;\n this.savingDraft = false;\n this.emit('saveDraft', sub);\n })\n .catch(err => {\n this.savingDraft = false;\n this.handleDraftError('saveDraftError', err);\n });\n }\n }\n /**\n * Restores a draft submission based on the user who is authenticated.\n *\n * @param {userId} - The user id where we need to restore the draft from.\n */\n restoreDraft(userId) {\n const formio = this.formio || this.options.formio;\n if (!formio) {\n this.handleDraftError('restoreDraftInstanceError', null, true);\n return;\n }\n this.savingDraft = true;\n formio.loadSubmissions({\n params: {\n state: 'draft',\n owner: userId\n }\n }).then(submissions => {\n if (submissions.length > 0 && !this.options.skipDraftRestore) {\n const draft = (0, utils_1.fastCloneDeep)(submissions[0]);\n return this.setSubmission(draft).then(() => {\n this.draftEnabled = true;\n this.savingDraft = false;\n this.emit('restoreDraft', draft);\n });\n }\n // Enable drafts so that we can keep track of changes.\n this.draftEnabled = true;\n this.savingDraft = false;\n this.emit('restoreDraft', null);\n })\n .catch(err => {\n this.draftEnabled = true;\n this.savingDraft = false;\n this.handleDraftError('restoreDraftError', err, true);\n });\n }\n get schema() {\n const schema = (0, utils_1.fastCloneDeep)(lodash_1.default.omit(this._form, ['components']));\n schema.components = [];\n this.eachComponent((component) => schema.components.push(component.schema));\n return schema;\n }\n mergeData(_this, _that) {\n lodash_1.default.mergeWith(_this, _that, (thisValue, thatValue) => {\n if (Array.isArray(thisValue) && Array.isArray(thatValue) && thisValue.length !== thatValue.length) {\n return thatValue;\n }\n });\n }\n setValue(submission, flags = {}) {\n if (!submission || !submission.data) {\n submission = {\n data: {},\n metadata: submission.metadata,\n };\n }\n // Metadata needs to be available before setValue\n this._submission.metadata = submission.metadata || {};\n this.editing = !!submission._id;\n // Set the timezone in the options if available.\n if (!this.options.submissionTimezone &&\n submission.metadata &&\n submission.metadata.timezone) {\n this.options.submissionTimezone = submission.metadata.timezone;\n }\n const changed = super.setValue(submission.data, flags);\n if (!flags.sanitize) {\n this.mergeData(this.data, submission.data);\n }\n submission.data = this.data;\n this._submission = submission;\n return changed;\n }\n getValue() {\n if (!this._submission.data) {\n this._submission.data = {};\n }\n if (this.viewOnly) {\n return this._submission;\n }\n const submission = this._submission;\n submission.data = this.data;\n return this._submission;\n }\n /**\n * Build the form.\n */\n init() {\n if (this.options.submission) {\n const submission = lodash_1.default.extend({}, this.options.submission);\n this._submission = submission;\n this._data = submission.data;\n }\n else {\n this._submission = this._submission || { data: {} };\n }\n // Remove any existing components.\n if (this.components && this.components.length) {\n this.destroyComponents();\n this.components = [];\n }\n if (this.component) {\n this.component.components = this.form ? this.form.components : [];\n }\n else {\n this.component = this.form;\n }\n this.component.type = 'form';\n this.component.input = false;\n this.addComponents();\n this.on('submitButton', options => {\n this.submit(false, options).catch(e => {\n options.instance.loading = false;\n return e !== false && e !== undefined && console.log(e);\n });\n }, true);\n this.on('checkValidity', (data) => this.validate(data, { dirty: true, process: 'change' }), true);\n this.on('requestUrl', (args) => (this.submitUrl(args.url, args.headers)), true);\n this.on('resetForm', () => this.resetValue(), true);\n this.on('deleteSubmission', () => this.deleteSubmission(), true);\n this.on('refreshData', () => this.updateValue(), true);\n this.executeFormController();\n return this.formReady;\n }\n executeFormController() {\n // If no controller value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n if (!this.form || !this.form.controller\n || ((!this.visible || this.component.hidden) && this.component.clearOnHide && !this.rootPristine)) {\n return false;\n }\n this.formReady.then(() => {\n this.evaluate(this.form.controller, {\n components: this.components,\n instance: this,\n });\n });\n }\n teardown() {\n this.emit('formDelete', this.id);\n delete Formio_1.Formio.forms[this.id];\n delete this.executeShortcuts;\n delete this.triggerSaveDraft;\n super.teardown();\n }\n destroy(all = false) {\n this.off('submitButton');\n this.off('checkValidity');\n this.off('requestUrl');\n this.off('resetForm');\n this.off('deleteSubmission');\n this.off('refreshData');\n return super.destroy(all);\n }\n build(element) {\n if (element || this.element) {\n return this.ready.then(() => {\n element = element || this.element;\n super.build(element);\n });\n }\n return this.ready;\n }\n getClassName() {\n let classes = 'formio-form';\n if (this.options.readOnly) {\n classes += ' formio-read-only';\n }\n return classes;\n }\n render() {\n return super.render(this.renderTemplate('webform', {\n classes: this.getClassName(),\n children: this.renderComponents(),\n }), this.builderMode ? 'builder' : 'form', true);\n }\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element) {\n return Promise.resolve();\n }\n this.clear();\n this.setContent(this.element, this.render());\n return this.attach(this.element);\n }\n attach(element) {\n this.setElement(element);\n this.loadRefs(element, { webform: 'single' });\n const childPromise = this.attachComponents(this.refs.webform);\n this.addEventListener(document, 'keydown', this.executeShortcuts);\n this.currentForm = this;\n this.hook('attachWebform', element, this);\n return childPromise.then(() => {\n this.emit('render', this.element);\n return this.setValue(this._submission, {\n noUpdateEvent: true,\n });\n });\n }\n hasRequiredFields() {\n let result = false;\n (0, formUtils_1.eachComponent)(this.form.components, (component) => {\n if (component.validate.required) {\n result = true;\n return true;\n }\n }, true);\n return result;\n }\n resetValue() {\n lodash_1.default.each(this.getComponents(), (comp) => (comp.resetValue()));\n this.setPristine(true);\n this.onChange({ resetValue: true });\n }\n /**\n * Sets a new alert to display in the error dialog of the form.\n *\n * @param {string} type - The type of alert to display. \"danger\", \"success\", \"warning\", etc.\n * @param {string} message - The message to show in the alert.\n * @param {Object} options\n */\n setAlert(type, message, options) {\n if (!type && this.submitted) {\n if (this.alert) {\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.removeEventListener(el, 'click');\n this.removeEventListener(el, 'keypress');\n });\n }\n this.removeChild(this.alert);\n this.alert = null;\n }\n return;\n }\n if (this.options.noAlerts) {\n if (!message) {\n this.emit('error', false);\n }\n return;\n }\n if (this.alert) {\n try {\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.removeEventListener(el, 'click');\n this.removeEventListener(el, 'keypress');\n });\n }\n this.removeChild(this.alert);\n this.alert = null;\n }\n catch (err) {\n // ignore\n }\n }\n if (message) {\n const attrs = {\n class: (options && options.classes) || `alert alert-${type}`,\n id: `error-list-${this.id}`,\n };\n const templateOptions = {\n message: message instanceof HTMLElement ? message.outerHTML : message,\n attrs: attrs,\n type\n };\n this.alert = (0, utils_1.convertStringToHTMLElement)(this.renderTemplate('alert', templateOptions), `#${attrs.id}`);\n }\n if (!this.alert) {\n return;\n }\n this.loadRefs(this.alert, { errorRef: 'multiple' });\n if (this.refs.errorRef && this.refs.errorRef.length) {\n this.refs.errorRef.forEach(el => {\n this.addEventListener(el, 'click', (e) => {\n const key = e.currentTarget.dataset.componentKey;\n this.focusOnComponent(key);\n });\n this.addEventListener(el, 'keydown', (e) => {\n if (e.keyCode === 13) {\n e.preventDefault();\n const key = e.currentTarget.dataset.componentKey;\n this.focusOnComponent(key);\n }\n });\n });\n }\n this.prepend(this.alert);\n }\n /**\n * Focus on selected component.\n *\n * @param {string} key - The key of selected component.\n * @returns {*}\n */\n focusOnComponent(key) {\n if (key) {\n const component = this.getComponent(key);\n if (component) {\n component.focus();\n }\n }\n }\n /**\n * Show the errors of this form within the alert dialog.\n *\n * @param {Object} error - An optional additional error to display along with the component errors.\n * @returns {*}\n */\n /* eslint-disable no-unused-vars */\n showErrors(errors, triggerEvent) {\n this.loading = false;\n if (!Array.isArray(errors)) {\n errors = [errors];\n }\n errors = errors.concat(this.customErrors).filter((err) => !!err);\n if (!errors.length) {\n this.setAlert(false);\n return;\n }\n // Mark any components as invalid if in a custom message.\n errors.forEach((err) => {\n const { components = [] } = err;\n if (err.component) {\n components.push(err.component);\n }\n if (err.path) {\n components.push(err.path);\n }\n components.forEach((path) => {\n const originalPath = (0, utils_1.getStringFromComponentPath)(path);\n const component = this.getComponent(path, lodash_1.default.identity, originalPath);\n if (err.fromServer) {\n if (component.serverErrors) {\n component.serverErrors.push(err);\n }\n else {\n component.serverErrors = [err];\n }\n }\n const components = lodash_1.default.compact(Array.isArray(component) ? component : [component]);\n components.forEach((component) => component.setCustomValidity(err.message, true));\n });\n });\n const displayedErrors = [];\n if (errors.length) {\n errors = lodash_1.default.uniqBy(errors, error => error.message);\n const createListItem = (message, index) => {\n var _a, _b, _c;\n const err = errors[index];\n const messageFromIndex = !lodash_1.default.isUndefined(index) && errors && errors[index];\n const keyOrPath = ((messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.formattedKeyOrPath) || (messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.path) || ((_a = messageFromIndex === null || messageFromIndex === void 0 ? void 0 : messageFromIndex.context) === null || _a === void 0 ? void 0 : _a.path)) || (((_b = err.context) === null || _b === void 0 ? void 0 : _b.component) && ((_c = err.context) === null || _c === void 0 ? void 0 : _c.component.key)) || (err.component && err.component.key) || err.fromServer && err.path;\n const formattedKeyOrPath = keyOrPath ? (0, utils_1.getStringFromComponentPath)(keyOrPath) : '';\n if (typeof err !== 'string' && !err.formattedKeyOrPath) {\n err.formattedKeyOrPath = formattedKeyOrPath;\n }\n return {\n message: (0, utils_1.unescapeHTML)(message),\n keyOrPath: formattedKeyOrPath\n };\n };\n errors.forEach(({ message, context, fromServer, component }, index) => {\n const text = !(component === null || component === void 0 ? void 0 : component.label) || (context === null || context === void 0 ? void 0 : context.hasLabel) || fromServer\n ? this.t('alertMessage', { message: this.t(message) })\n : this.t('alertMessageWithLabel', {\n label: this.t(component === null || component === void 0 ? void 0 : component.label),\n message: this.t(message),\n });\n displayedErrors.push(createListItem(text, index));\n });\n }\n const errorsList = this.renderTemplate('errorsList', { errors: displayedErrors });\n this.root.setAlert('danger', errorsList);\n if (triggerEvent) {\n this.emit('error', errors);\n }\n return errors;\n }\n /* eslint-enable no-unused-vars */\n /**\n * Called when the submission has completed, or if the submission needs to be sent to an external library.\n *\n * @param {Object} submission - The submission object.\n * @param {boolean} saved - Whether or not this submission was saved to the server.\n * @returns {object} - The submission object.\n */\n onSubmit(submission, saved) {\n var _a;\n this.loading = false;\n this.submitting = false;\n this.setPristine(true);\n // We want to return the submitted submission and setValue will mutate the submission so cloneDeep it here.\n this.setValue((0, utils_1.fastCloneDeep)(submission), {\n noValidate: true,\n noCheck: true\n });\n this.setAlert('success', `<p>${this.t('complete')}</p>`);\n // Cancel triggered saveDraft to prevent overriding the submitted state\n if (this.draftEnabled && ((_a = this.triggerSaveDraft) === null || _a === void 0 ? void 0 : _a.cancel)) {\n this.triggerSaveDraft.cancel();\n }\n this.emit('submit', submission, saved);\n if (saved) {\n this.emit('submitDone', submission);\n }\n return submission;\n }\n normalizeError(error) {\n if (error) {\n if (typeof error === 'object' && 'details' in error) {\n error = error.details;\n }\n if (typeof error === 'string') {\n error = { message: error };\n }\n }\n return error;\n }\n /**\n * Called when an error occurs during the submission.\n *\n * @param {Object} error - The error that occured.\n */\n onSubmissionError(error) {\n error = this.normalizeError(error);\n this.submitting = false;\n this.setPristine(false);\n this.emit('submitError', error || this.errors);\n // Allow for silent cancellations (no error message, no submit button error state)\n if (error && error.silent) {\n this.emit('change', { isValid: true }, { silent: true });\n return false;\n }\n const errors = this.showErrors(error, true);\n if (this.root && this.root.alert) {\n this.scrollIntoView(this.root.alert);\n }\n return errors;\n }\n /**\n * Trigger the change event for this form.\n *\n * @param changed\n * @param flags\n */\n onChange(flags, changed, modified, changes) {\n flags = flags || {};\n let isChangeEventEmitted = false;\n super.onChange(flags, true);\n const value = lodash_1.default.clone(this.submission);\n flags.changed = value.changed = changed;\n flags.changes = changes;\n if (modified && this.pristine) {\n this.pristine = false;\n }\n this.checkData(value.data, flags);\n const shouldValidate = !flags.noValidate || flags.fromIFrame || (flags.fromSubmission && this.rootPristine && this.pristine && flags.changed);\n const errors = shouldValidate ? this.validate(value.data, Object.assign(Object.assign({}, flags), { process: 'change' })) : [];\n value.isValid = errors.length === 0;\n this.loading = false;\n if (this.submitted) {\n // show server errors while they are not cleaned/fixed\n const nonComponentServerErrors = lodash_1.default.filter(this.serverErrors || [], err => !err.component && !err.path);\n this.showErrors(nonComponentServerErrors.length ? nonComponentServerErrors : errors);\n }\n // See if we need to save the draft of the form.\n if (modified && this.options.saveDraft) {\n this.triggerSaveDraft();\n }\n if (!flags || !flags.noEmit) {\n this.emit('change', value, flags, modified);\n isChangeEventEmitted = true;\n }\n // The form is initialized after the first change event occurs.\n if (isChangeEventEmitted && !this.initialized) {\n this.emit('initialized');\n this.initialized = true;\n }\n }\n /**\n * Send a delete request to the server.\n */\n deleteSubmission() {\n return this.formio.deleteSubmission()\n .then(() => {\n this.emit('submissionDeleted', this.submission);\n this.resetValue();\n });\n }\n /**\n * Cancels the submission.\n *\n * @alias reset\n */\n cancel(noconfirm) {\n const shouldReset = this.hook('beforeCancel', true);\n if (shouldReset && (noconfirm || confirm(this.t('confirmCancel')))) {\n this.resetValue();\n return true;\n }\n else {\n this.emit('cancelSubmit');\n return false;\n }\n }\n setMetadata(submission) {\n // Add in metadata about client submitting the form\n submission.metadata = submission.metadata || {};\n lodash_1.default.defaults(submission.metadata, {\n timezone: lodash_1.default.get(this, '_submission.metadata.timezone', (0, utils_1.currentTimezone)()),\n offset: parseInt(lodash_1.default.get(this, '_submission.metadata.offset', (0, moment_1.default)().utcOffset()), 10),\n origin: document.location.origin,\n referrer: document.referrer,\n browserName: navigator.appName,\n userAgent: navigator.userAgent,\n pathName: window.location.pathname,\n onLine: navigator.onLine\n });\n }\n submitForm(options = {}) {\n this.clearServerErrors();\n return new Promise((resolve, reject) => {\n // Read-only forms should never submit.\n if (this.options.readOnly) {\n return resolve({\n submission: this.submission,\n saved: false\n });\n }\n const submission = (0, utils_1.fastCloneDeep)(this.submission || {});\n this.setMetadata(submission);\n submission.state = options.state || submission.state || 'submitted';\n const isDraft = (submission.state === 'draft');\n this.hook('beforeSubmit', Object.assign(Object.assign({}, submission), { component: options.component }), (err, data) => {\n var _a;\n if (err) {\n return reject(err);\n }\n submission._vnote = data && data._vnote ? data._vnote : '';\n try {\n if (!isDraft && !options.noValidate) {\n if (!submission.data) {\n return reject('Invalid Submission');\n }\n const errors = this.validate(submission.data, {\n dirty: true,\n silentCheck: false,\n process: 'submit'\n });\n if (errors.length || ((_a = options.beforeSubmitResults) === null || _a === void 0 ? void 0 : _a.some((result) => result.status === 'rejected'))) {\n return reject(errors);\n }\n }\n }\n catch (err) {\n console.error(err);\n }\n this.everyComponent((comp) => {\n if (submission._vnote && comp.type === 'form' && comp.component.reference) {\n lodash_1.default.get(submission.data, comp.path, {})._vnote = submission._vnote;\n }\n const { persistent } = comp.component;\n if (persistent === 'client-only') {\n lodash_1.default.unset(submission.data, comp.path);\n }\n });\n this.hook('customValidation', Object.assign(Object.assign({}, submission), { component: options.component }), (err) => {\n if (err) {\n // If string is returned, cast to object.\n if (typeof err === 'string') {\n err = {\n message: err\n };\n }\n // Ensure err is an array.\n err = Array.isArray(err) ? err : [err];\n return reject(err);\n }\n this.loading = true;\n // Use the form action to submit the form if available.\n if (this._form && this._form.action) {\n const method = (submission.data._id && this._form.action.includes(submission.data._id)) ? 'PUT' : 'POST';\n return Formio_1.Formio.makeStaticRequest(this._form.action, method, submission, this.formio ? this.formio.options : {})\n .then((result) => resolve({\n submission: result,\n saved: true,\n }))\n .catch((error) => {\n this.setServerErrors(error);\n return reject(error);\n });\n }\n const submitFormio = this.formio;\n if (this.nosubmit || !submitFormio) {\n return resolve({\n submission,\n saved: false,\n });\n }\n // If this is an actionUrl, then make sure to save the action and not the submission.\n const submitMethod = submitFormio.actionUrl ? 'saveAction' : 'saveSubmission';\n submitFormio[submitMethod](submission)\n .then((result) => resolve({\n submission: result,\n saved: true,\n }))\n .catch((error) => {\n this.setServerErrors(error);\n return reject(error);\n });\n });\n });\n });\n }\n setServerErrors(error) {\n if (error.details) {\n this.serverErrors = error.details.filter((err) => err.level ? err.level === 'error' : err).map((err) => {\n err.fromServer = true;\n return err;\n });\n }\n else if (typeof error === 'string') {\n this.serverErrors = [{ fromServer: true, level: 'error', message: error }];\n }\n }\n executeSubmit(options) {\n this.submitted = true;\n this.submitting = true;\n return this.submitForm(options)\n .then(({ submission, saved }) => this.onSubmit(submission, saved))\n .then((results) => {\n this.submissionInProcess = false;\n return results;\n })\n .catch((err) => {\n this.submissionInProcess = false;\n return Promise.reject(this.onSubmissionError(err));\n });\n }\n clearServerErrors() {\n var _a;\n (_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.forEach((error) => {\n if (error.path) {\n const pathArray = (0, utils_1.getArrayFromComponentPath)(error.path);\n const component = this.getComponent(pathArray, lodash_1.default.identity, error.formattedKeyOrPath);\n if (component) {\n component.serverErrors = [];\n }\n }\n });\n this.serverErrors = [];\n }\n /**\n * Submits the form.\n *\n * @example\n * import Webform from '@formio/js/Webform';\n * let form = new Webform(document.getElementById('formio'));\n * form.src = 'https://examples.form.io/example';\n * form.submission = {data: {\n * firstName: 'Joe',\n * lastName: 'Smith',\n * email: 'joe@example.com'\n * }};\n * form.submit().then((submission) => {\n * console.log(submission);\n * });\n *\n * @param {boolean} before - If this submission occured from the before handlers.\n *\n * @returns {Promise} - A promise when the form is done submitting.\n */\n submit(before = null, options = {}) {\n this.submissionInProcess = true;\n if (!before) {\n return this.beforeSubmit(options).then(() => this.executeSubmit(options));\n }\n else {\n return this.executeSubmit(options);\n }\n }\n submitUrl(URL, headers) {\n if (!URL) {\n return console.warn('Missing URL argument');\n }\n const submission = this.submission || {};\n const API_URL = URL;\n const settings = {\n method: 'POST',\n headers: {}\n };\n if (headers && headers.length > 0) {\n headers.map((e) => {\n if (e.header !== '' && e.value !== '') {\n settings.headers[e.header] = this.interpolate(e.value, submission);\n }\n });\n }\n if (API_URL && settings) {\n Formio_1.Formio.makeStaticRequest(API_URL, settings.method, submission, { headers: settings.headers }).then(() => {\n this.emit('requestDone');\n this.setAlert('success', '<p> Success </p>');\n }).catch((e) => {\n const message = `${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`;\n this.emit('error', message);\n console.error(message);\n this.setAlert('danger', `<p> ${message} </p>`);\n return Promise.reject(this.onSubmissionError(e));\n });\n }\n else {\n this.emit('error', 'You should add a URL to this button.');\n this.setAlert('warning', 'You should add a URL to this button.');\n return console.warn('You should add a URL to this button.');\n }\n }\n triggerRecaptcha() {\n if (!this || !this.components) {\n return;\n }\n const recaptchaComponent = (0, utils_1.searchComponents)(this.components, {\n 'component.type': 'recaptcha',\n 'component.eventType': 'formLoad'\n });\n if (recaptchaComponent.length > 0) {\n recaptchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);\n }\n }\n set nosubmit(value) {\n this._nosubmit = !!value;\n this.emit('nosubmit', this._nosubmit);\n }\n get nosubmit() {\n return this._nosubmit || false;\n }\n get conditions() {\n var _a, _b;\n return (_b = (_a = this.schema.settings) === null || _a === void 0 ? void 0 : _a.conditions) !== null && _b !== void 0 ? _b : [];\n }\n get variables() {\n var _a, _b;\n return (_b = (_a = this.schema.settings) === null || _a === void 0 ? void 0 : _a.variables) !== null && _b !== void 0 ? _b : [];\n }\n}\nexports[\"default\"] = Webform;\nWebform.setBaseUrl = Formio_1.Formio.setBaseUrl;\nWebform.setApiUrl = Formio_1.Formio.setApiUrl;\nWebform.setAppUrl = Formio_1.Formio.setAppUrl;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Webform.js?");
|
5389
5389
|
|
5390
5390
|
/***/ }),
|
5391
5391
|
|
@@ -5517,7 +5517,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5517
5517
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5518
5518
|
|
5519
5519
|
"use strict";
|
5520
|
-
eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* globals Quill, ClassicEditor, CKEDITOR */\nconst vanilla_text_mask_1 = __webpack_require__(/*! @formio/vanilla-text-mask */ \"./node_modules/@formio/vanilla-text-mask/dist/vanillaTextMask.js\");\nconst tippy_js_1 = __importDefault(__webpack_require__(/*! tippy.js */ \"./node_modules/tippy.js/dist/tippy.esm.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ismobilejs_1 = __importDefault(__webpack_require__(/*! ismobilejs */ \"./node_modules/ismobilejs/esm/index.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst Formio_1 = __webpack_require__(/*! ../../../Formio */ \"./lib/cjs/Formio.js\");\nconst FormioUtils = __importStar(__webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Element_1 = __importDefault(__webpack_require__(/*! ../../../Element */ \"./lib/cjs/Element.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst widgets_1 = __importDefault(__webpack_require__(/*! ../../../widgets */ \"./lib/cjs/widgets/index.js\"));\nconst addons_1 = __importDefault(__webpack_require__(/*! ../../../addons */ \"./lib/cjs/addons/index.js\"));\nconst uploadAdapter_1 = __webpack_require__(/*! ../../../providers/storage/uploadAdapter */ \"./lib/cjs/providers/storage/uploadAdapter.js\");\nconst en_1 = __importDefault(__webpack_require__(/*! ../../../translations/en */ \"./lib/cjs/translations/en.js\"));\nconst Templates_1 = __importDefault(__webpack_require__(/*! ../../../templates/Templates */ \"./lib/cjs/templates/Templates.js\"));\nconst isIEBrowser = FormioUtils.getBrowserInfo().ie;\n/**\n * This is the Component class\n which all elements within the FormioForm derive from.\n */\nclass Component extends Element_1.default {\n static schema(...sources) {\n return lodash_1.default.merge({\n /**\n * Determines if this component provides an input.\n */\n input: true,\n /**\n * The data key for this component (how the data is stored in the database).\n */\n key: '',\n /**\n * The input placeholder for this component.\n */\n placeholder: '',\n /**\n * The input prefix\n */\n prefix: '',\n /**\n * The custom CSS class to provide to this component.\n */\n customClass: '',\n /**\n * The input suffix.\n */\n suffix: '',\n /**\n * If this component should allow an array of values to be captured.\n */\n multiple: false,\n /**\n * The default value of this component.\n */\n defaultValue: null,\n /**\n * If the data of this component should be protected (no GET api requests can see the data)\n */\n protected: false,\n /**\n * Validate if the value of this component should be unique within the form.\n */\n unique: false,\n /**\n * If the value of this component should be persisted within the backend api database.\n */\n persistent: true,\n /**\n * Determines if the component should be within the form, but not visible.\n */\n hidden: false,\n /**\n * If the component should be cleared when hidden.\n */\n clearOnHide: true,\n /**\n * This will refresh this component options when this field changes.\n */\n refreshOn: '',\n /**\n * This will redraw the component when this field changes.\n */\n redrawOn: '',\n /**\n * If this component should be included as a column within a submission table.\n */\n tableView: false,\n /**\n * If this component should be rendering in modal.\n */\n modalEdit: false,\n /**\n * The input label provided to this component.\n */\n label: '',\n dataGridLabel: false,\n labelPosition: 'top',\n description: '',\n errorLabel: '',\n tooltip: '',\n hideLabel: false,\n tabindex: '',\n disabled: false,\n autofocus: false,\n dbIndex: false,\n customDefaultValue: '',\n calculateValue: '',\n calculateServer: false,\n widget: null,\n /**\n * Attributes that will be assigned to the input elements of this component.\n */\n attributes: {},\n /**\n * This will perform the validation on either \"change\" or \"blur\" of the input element.\n */\n validateOn: 'change',\n /**\n * The validation criteria for this component.\n */\n validate: {\n /**\n * If this component is required.\n */\n required: false,\n /**\n * Custom JavaScript validation.\n */\n custom: '',\n /**\n * If the custom validation should remain private (only the backend will see it and execute it).\n */\n customPrivate: false,\n /**\n * If this component should implement a strict date validation if the Calendar widget is implemented.\n */\n strictDateValidation: false,\n multiple: false,\n unique: false\n },\n /**\n * The simple conditional settings for a component.\n */\n conditional: {\n show: null,\n when: null,\n eq: ''\n },\n overlay: {\n style: '',\n left: '',\n top: '',\n width: '',\n height: '',\n },\n allowCalculateOverride: false,\n encrypted: false,\n showCharCount: false,\n showWordCount: false,\n properties: {},\n allowMultipleMasks: false,\n addons: [],\n }, ...sources);\n }\n /**\n * Return the simple condition settings as part of the component.\n *\n * @return {Object}\n *\n */\n static get conditionOperatorsSettings() {\n return {\n operators: ['isEqual', 'isNotEqual', 'isEmpty', 'isNotEmpty'],\n valueComponent() {\n return {\n type: 'textfield',\n widget: {\n type: 'input'\n }\n };\n }\n };\n }\n /**\n * Return the array of possible types of component value absed on its schema.\n *\n * @param schema\n * @return {Array}\n *\n */\n static savedValueTypes(schema) {\n schema = schema || {};\n return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.any];\n }\n /**\n * Provides a table view for this component. Override if you wish to do something different than using getView\n * method of your instance.\n *\n * @param value\n * @param options\n */\n /* eslint-disable no-unused-vars */\n static tableView(value, options) { }\n /* eslint-enable no-unused-vars */\n /**\n * Initialize a new Component.\n *\n * @param {Object} component - The component JSON you wish to initialize.\n * @param {Object} options - The options for this component.\n * @param {Object} data - The global data submission object this component will belong.\n */\n /* eslint-disable max-statements */\n constructor(component, options, data) {\n super(Object.assign({\n renderMode: 'form',\n attachMode: 'full',\n noDefaults: false\n }, options || {}));\n // Restore the component id.\n if (component && component.id) {\n this.id = component.id;\n }\n /**\n * Determines if this component has a condition assigned to it.\n * @type {null}\n * @private\n */\n this._hasCondition = null;\n /**\n * References to dom elements\n */\n this.refs = {};\n // Allow global override for any component JSON.\n if (component &&\n this.options.components &&\n this.options.components[component.type]) {\n lodash_1.default.merge(component, this.options.components[component.type]);\n }\n /**\n * The data path to this specific component instance.\n *\n * @type {string}\n */\n this.path = (component === null || component === void 0 ? void 0 : component.key) || '';\n /**\n * An array of all the children components errors.\n */\n this.childErrors = [];\n /**\n * Last validation errors that have occured.\n */\n this._errors = [];\n this._visibleErrors = [];\n /**\n * The Form.io component JSON schema.\n * @type {*}\n */\n this.component = this.mergeSchema(component || {});\n // Add the id to the component.\n this.component.id = this.id;\n this.afterComponentAssign();\n // Save off the original component to be used in logic.\n this.originalComponent = (0, utils_1.fastCloneDeep)(this.component);\n /**\n * If the component has been attached\n */\n this.attached = false;\n /**\n * If the component has been rendered\n */\n this.rendered = false;\n /**\n * The data object in which this component resides.\n * @type {*}\n */\n this._data = data || {};\n /**\n * Tool tip text after processing\n * @type {string}\n */\n this.tooltip = '';\n /**\n * The row path of this component.\n * @type {number}\n */\n this.row = this.options.row;\n /**\n * Points to a flat map of child components (if applicable).\n *\n * @type {Object}\n */\n this.childComponentsMap = {};\n /**\n * Determines if this component is disabled, or not.\n *\n * @type {boolean}\n */\n this._disabled = (0, utils_1.boolValue)(this.component.disabled) ? this.component.disabled : false;\n /**\n * Points to the root component, usually the FormComponent.\n *\n * @type {Component}\n */\n this.root = this.options.root || this;\n this.localRoot = this.options.localRoot || this;\n /**\n * If this input has been input and provided value.\n *\n * @type {boolean}\n */\n this.pristine = true;\n /**\n * Points to the parent component.\n *\n * @type {Component}\n */\n this.parent = this.options.parent;\n this.options.name = this.options.name || 'data';\n this._path = '';\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n /**\n * Determines if this component is visible, or not.\n */\n this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;\n this._visible = this._parentVisible && this.conditionallyVisible(null, data);\n this._parentDisabled = false;\n /**\n * The reference attribute name for this component\n */\n this._referenceAttributeName = 'ref';\n /**\n * Used to trigger a new change in this component.\n * @type {function} - Call to trigger a change in this component.\n */\n let changes = [];\n let lastChanged = null;\n let triggerArgs = [];\n const _triggerChange = lodash_1.default.debounce((...args) => {\n if (this.root) {\n this.root.changing = false;\n }\n triggerArgs = [];\n if (!args[1] && lastChanged) {\n // Set the changed component if one isn't provided.\n args[1] = lastChanged;\n }\n if (lodash_1.default.isEmpty(args[0]) && lastChanged) {\n // Set the flags if it is empty and lastChanged exists.\n args[0] = lastChanged.flags;\n }\n lastChanged = null;\n args[3] = changes;\n const retVal = this.onChange(...args);\n changes = [];\n return retVal;\n }, 100);\n this.triggerChange = (...args) => {\n if (args[1]) {\n // Make sure that during the debounce that we always track lastChanged component, even if they\n // don't provide one later.\n lastChanged = args[1];\n changes.push(lastChanged);\n }\n if (this.root) {\n this.root.changing = true;\n }\n if (args.length) {\n triggerArgs = args;\n }\n return _triggerChange(...triggerArgs);\n };\n /**\n * Used to trigger a redraw event within this component.\n *\n * @type {Function}\n */\n this.triggerRedraw = lodash_1.default.debounce(this.redraw.bind(this), 100);\n /**\n * list of attached tooltips\n * @type {Array}\n */\n this.tooltips = [];\n /**\n * List of attached addons\n * @type {Array}\n */\n this.addons = [];\n // To force this component to be invalid.\n this.invalid = false;\n if (this.component) {\n this.type = this.component.type;\n if (this.allowData && this.key) {\n this.options.name += `[${this.key}]`;\n // If component is visible or not set to clear on hide, set the default value.\n if (this.visible || !this.component.clearOnHide) {\n if (!this.hasValue()) {\n if (this.shouldAddDefaultValue) {\n this.dataValue = this.defaultValue;\n }\n }\n else {\n // Ensure the dataValue is set.\n /* eslint-disable no-self-assign */\n this.dataValue = this.dataValue;\n /* eslint-enable no-self-assign */\n }\n }\n }\n /**\n * The element information for creating the input element.\n * @type {*}\n */\n this.info = this.elementInfo();\n }\n // Allow anyone to hook into the component creation.\n this.hook('component');\n if (!this.options.skipInit) {\n this.init();\n }\n }\n /* eslint-enable max-statements */\n get componentsMap() {\n var _a;\n if ((_a = this.localRoot) === null || _a === void 0 ? void 0 : _a.childComponentsMap) {\n return this.localRoot.childComponentsMap;\n }\n const localMap = {};\n localMap[this.path] = this;\n return localMap;\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n }\n mergeSchema(component = {}) {\n return lodash_1.default.defaultsDeep(component, this.defaultSchema);\n }\n // Allow componets to notify when ready.\n get ready() {\n return Promise.resolve(this);\n }\n get isPDFReadOnlyMode() {\n return this.parent &&\n this.parent.form &&\n (this.parent.form.display === 'pdf') &&\n this.options.readOnly;\n }\n get labelInfo() {\n const label = {};\n label.hidden = this.labelIsHidden();\n label.className = '';\n label.labelPosition = this.component.labelPosition;\n label.tooltipClass = `${this.iconClass('question-sign')} text-muted`;\n const isPDFReadOnlyMode = this.isPDFReadOnlyMode;\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required) && !isPDFReadOnlyMode) {\n label.className += ' field-required';\n }\n if (label.hidden) {\n label.className += ' control-label--hidden';\n }\n if (this.info.attr.id) {\n label.for = this.info.attr.id;\n }\n return label;\n }\n init() {\n var _a;\n this.disabled = this.shouldDisabled;\n this._visible = this.conditionallyVisible(null, null);\n if ((_a = this.component.addons) === null || _a === void 0 ? void 0 : _a.length) {\n this.component.addons.forEach((addon) => this.createAddon(addon));\n }\n }\n afterComponentAssign() {\n //implement in extended classes\n }\n createAddon(addonConfiguration) {\n var _a;\n const name = addonConfiguration.name;\n if (!name) {\n return;\n }\n const settings = ((_a = addonConfiguration.settings) === null || _a === void 0 ? void 0 : _a.data) || {};\n const Addon = addons_1.default[name.value];\n let addon = null;\n if (Addon) {\n const supportedComponents = Addon.info.supportedComponents;\n const supportsThisComponentType = !(supportedComponents === null || supportedComponents === void 0 ? void 0 : supportedComponents.length) ||\n supportedComponents.indexOf(this.component.type) !== -1;\n if (supportsThisComponentType) {\n addon = new Addon(settings, this);\n this.addons.push(addon);\n }\n else {\n console.warn(`Addon ${name.label} does not support component of type ${this.component.type}.`);\n }\n }\n return addon;\n }\n teardown() {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n delete this._currentForm;\n delete this.parent;\n delete this.root;\n delete this.triggerChange;\n delete this.triggerRedraw;\n if (this.options) {\n delete this.options.root;\n delete this.options.parent;\n delete this.options.i18next;\n }\n super.teardown();\n }\n destroy(all = false) {\n super.destroy(all);\n this.detach();\n this.addons.forEach((addon) => addon.destroy());\n if (all) {\n this.teardown();\n }\n }\n get shouldDisabled() {\n return this.options.readOnly || this.component.disabled || (this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]);\n }\n get isInputComponent() {\n return !this.component.hasOwnProperty('input') || this.component.input;\n }\n get allowData() {\n return this.hasInput;\n }\n get hasInput() {\n return this.isInputComponent || (this.refs.input && this.refs.input.length);\n }\n get defaultSchema() {\n return Component.schema();\n }\n get key() {\n return lodash_1.default.get(this.component, 'key', '');\n }\n set parentVisible(value) {\n this._parentVisible = value;\n }\n get parentVisible() {\n return this._parentVisible;\n }\n set parentDisabled(value) {\n this._parentDisabled = value;\n }\n get parentDisabled() {\n return this._parentDisabled;\n }\n shouldForceVisibility(component, visibility) {\n if (!this.options[visibility]) {\n return false;\n }\n if (!component) {\n component = this.component;\n }\n if (lodash_1.default.isArray(this.options[visibility])) {\n return this.options[visibility].includes(component.key);\n }\n return this.options[visibility][component.key];\n }\n shouldForceHide(component) {\n return this.shouldForceVisibility(component, 'hide');\n }\n shouldForceShow(component) {\n return this.shouldForceVisibility(component, 'show');\n }\n /**\n *\n * @param value {boolean}\n */\n set visible(value) {\n if (this._visible !== value) {\n // Skip if this component is set to visible and is supposed to be hidden.\n if (value && this.shouldForceHide()) {\n return;\n }\n // Skip if this component is set to hidden and is supposed to be shown.\n if (!value && this.shouldForceShow()) {\n return;\n }\n this._visible = value;\n this.clearOnHide();\n this.redraw();\n }\n }\n /**\n *\n * @returns {boolean}\n */\n get visible() {\n // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown.\n if (this.builderMode || this.previewMode || this.options.showHiddenFields) {\n return true;\n }\n if (this.shouldForceHide()) {\n return false;\n }\n if (this.shouldForceShow()) {\n return true;\n }\n return this._visible && this._parentVisible;\n }\n get currentForm() {\n return this._currentForm;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n }\n get fullMode() {\n return this.options.attachMode === 'full';\n }\n get builderMode() {\n return this.options.attachMode === 'builder';\n }\n get calculatedPath() {\n console.error('component.calculatedPath was deprecated, use component.path instead.');\n return this.path;\n }\n get labelPosition() {\n return this.component.labelPosition;\n }\n get labelWidth() {\n const width = this.component.labelWidth;\n return width >= 0 ? width : 30;\n }\n get labelMargin() {\n const margin = this.component.labelMargin;\n return margin >= 0 ? margin : 3;\n }\n get isAdvancedLabel() {\n return [\n 'left-left',\n 'left-right',\n 'right-left',\n 'right-right'\n ].includes(this.labelPosition);\n }\n get labelPositions() {\n return this.labelPosition.split('-');\n }\n get skipInEmail() {\n return false;\n }\n rightDirection(direction) {\n if (this.options.condensedMode) {\n return false;\n }\n return direction === 'right';\n }\n getLabelInfo(isCondensed = false) {\n const isRightPosition = this.rightDirection(this.labelPositions[0]);\n const isLeftPosition = this.labelPositions[0] === 'left' || isCondensed;\n const isRightAlign = this.rightDirection(this.labelPositions[1]);\n let contentMargin = '';\n if (this.component.hideLabel) {\n const margin = isCondensed ? 0 : this.labelWidth + this.labelMargin;\n contentMargin = isRightPosition ? `margin-right: ${margin}%` : '';\n contentMargin = isLeftPosition ? `margin-left: ${margin}%` : '';\n }\n const labelStyles = `\n flex: ${this.labelWidth};\n ${isRightPosition ? 'margin-left' : 'margin-right'}: ${this.labelMargin}%;\n `;\n const contentStyles = `\n flex: ${100 - this.labelWidth - this.labelMargin};\n ${contentMargin};\n ${this.component.hideLabel ? `max-width: ${100 - this.labelWidth - this.labelMargin}` : ''};\n `;\n return {\n isRightPosition,\n isRightAlign,\n labelStyles,\n contentStyles\n };\n }\n /**\n * Returns only the schema that is different from the default.\n *\n * @param schema\n * @param defaultSchema\n */\n getModifiedSchema(schema, defaultSchema, recursion) {\n const modified = {};\n if (!defaultSchema) {\n return schema;\n }\n lodash_1.default.each(schema, (val, key) => {\n if (!lodash_1.default.isArray(val) && lodash_1.default.isObject(val) && defaultSchema.hasOwnProperty(key)) {\n const subModified = this.getModifiedSchema(val, defaultSchema[key], true);\n if (!lodash_1.default.isEmpty(subModified)) {\n modified[key] = subModified;\n }\n }\n else if (lodash_1.default.isArray(val)) {\n if (val.length !== 0 && !lodash_1.default.isEqual(val, defaultSchema[key])) {\n modified[key] = val;\n }\n }\n else if ((!recursion && (key === 'type')) ||\n (!recursion && (key === 'key')) ||\n (!recursion && (key === 'label')) ||\n (!recursion && (key === 'input')) ||\n (!recursion && (key === 'tableView')) ||\n (val !== '' && !defaultSchema.hasOwnProperty(key)) ||\n (val !== '' && val !== defaultSchema[key]) ||\n (defaultSchema[key] && val !== defaultSchema[key])) {\n modified[key] = val;\n }\n });\n return modified;\n }\n /**\n * Returns the JSON schema for this component.\n */\n get schema() {\n return (0, utils_1.fastCloneDeep)(this.getModifiedSchema(lodash_1.default.omit(this.component, 'id'), this.defaultSchema));\n }\n /**\n * Returns true if component is inside DataGrid\n */\n get isInDataGrid() {\n return this.inDataGrid;\n }\n /**\n * Translate a text using the i18n system.\n *\n * @param {string} text - The i18n identifier.\n * @param {Object} params - The i18n parameters to use for translation.\n */\n t(text, params = {}, ...args) {\n if (!text) {\n return '';\n }\n // Use _userInput: true to ignore translations from defaults\n if (text in en_1.default && params._userInput) {\n return text;\n }\n params.data = params.data || this.rootValue;\n params.row = params.row || this.data;\n params.component = params.component || this.component;\n return super.t(text, params, ...args);\n }\n labelIsHidden() {\n return !this.component.label ||\n ((!this.isInDataGrid && this.component.hideLabel) ||\n (this.isInDataGrid && !this.component.dataGridLabel) ||\n this.options.floatingLabels ||\n this.options.inputsOnly) && !this.builderMode;\n }\n transform(type, value) {\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n return frameworkTemplates.hasOwnProperty('transform')\n ? frameworkTemplates.transform(type, value, this)\n : (type, value) => value;\n }\n getTemplate(names, modes) {\n modes = Array.isArray(modes) ? modes : [modes];\n names = Array.isArray(names) ? names : [names];\n if (!modes.includes('form')) {\n modes.push('form');\n }\n let result = null;\n if (this.options.templates) {\n result = this.checkTemplate(this.options.templates, names, modes);\n if (result) {\n return result;\n }\n }\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n result = this.checkTemplate(frameworkTemplates, names, modes);\n if (result) {\n return result;\n }\n // Default back to bootstrap if not defined.\n const name = names[names.length - 1];\n const templatesByName = Templates_1.default.defaultTemplates[name];\n if (!templatesByName) {\n return { template: `Unknown template: ${name}` };\n }\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode };\n }\n return { template: templatesByName.form };\n }\n checkTemplate(templates, names, modes) {\n for (const name of names) {\n const templatesByName = templates[name];\n if (templatesByName) {\n const { referenceAttributeName } = templatesByName;\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode, referenceAttributeName };\n }\n }\n }\n return null;\n }\n checkTemplateMode(templatesByName, modes) {\n for (const mode of modes) {\n const templateByMode = templatesByName[mode];\n if (templateByMode) {\n return templateByMode;\n }\n }\n return null;\n }\n getFormattedAttribute(attr) {\n return attr ? this.t(attr, { _userInput: true }).replace(/\"/g, '"') : '';\n }\n getFormattedTooltip(tooltipValue) {\n const tooltip = this.interpolate(tooltipValue || '').replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return this.getFormattedAttribute(tooltip);\n }\n isHtmlRenderMode() {\n return this.options.renderMode === 'html';\n }\n renderTemplate(name, data = {}, modeOption) {\n // Need to make this fall back to form if renderMode is not found similar to how we search templates.\n const mode = modeOption || this.options.renderMode || 'form';\n data.component = this.component;\n data.self = this;\n data.options = this.options;\n data.readOnly = this.options.readOnly;\n data.iconClass = this.iconClass.bind(this);\n data.size = this.size.bind(this);\n data.t = this.t.bind(this);\n data.transform = this.transform.bind(this);\n data.id = data.id || this.id;\n data.key = data.key || this.key;\n data.value = data.value || this.dataValue;\n data.disabled = this.disabled;\n data.builder = this.builderMode;\n data.render = (...args) => {\n console.warn(`Form.io 'render' template function is deprecated.\n If you need to render template (template A) inside of another template (template B),\n pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B`);\n return this.renderTemplate(...args);\n };\n data.label = data.labelInfo || this.labelInfo;\n data.tooltip = this.getFormattedTooltip(this.component.tooltip);\n // Allow more specific template names\n const names = [\n `${name}-${this.component.type}-${this.key}`,\n `${name}-${this.component.type}`,\n `${name}-${this.key}`,\n `${name}`,\n ];\n // Allow template alters.\n const { referenceAttributeName, template } = this.getTemplate(names, mode);\n if (referenceAttributeName) {\n this._referenceAttributeName = referenceAttributeName;\n }\n return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);\n }\n /**\n * Sanitize an html string.\n *\n * @param string\n * @returns {*}\n */\n sanitize(dirty, forceSanitize, options) {\n var _a;\n if (!this.shouldSanitizeValue && !forceSanitize) {\n return dirty;\n }\n return FormioUtils.sanitize(dirty, {\n sanitizeConfig: lodash_1.default.merge(((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitizeConfig) || {}, options || {}),\n });\n }\n /**\n * Render a template string into html.\n *\n * @param template\n * @param data\n * @param actions\n *\n * @return {HTMLElement|String} - The created element or an empty string if template is not specified.\n */\n renderString(template, data) {\n if (!template) {\n return '';\n }\n // Interpolate the template and populate\n return this.interpolate(template, data);\n }\n performInputMapping(input) {\n return input;\n }\n get widget() {\n var _a;\n const settings = this.component.widget;\n if (settings && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.shadowRoot)) {\n settings.shadowRoot = this.root.shadowRoot;\n }\n const widget = settings && widgets_1.default[settings.type] ? new widgets_1.default[settings.type](settings, this.component, this) : null;\n return widget;\n }\n getBrowserLanguage() {\n const nav = window.navigator;\n const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];\n let language;\n // support for HTML 5.1 \"navigator.languages\"\n if (Array.isArray(nav.languages)) {\n for (let i = 0; i < nav.languages.length; i++) {\n language = nav.languages[i];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n }\n // support for other well known properties in browsers\n for (let i = 0; i < browserLanguagePropertyKeys.length; i++) {\n language = nav[browserLanguagePropertyKeys[i]];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n return null;\n }\n /**\n * Called before a next and previous page is triggered allowing the components\n * to perform special functions.\n *\n * @return {*}\n */\n beforePage() {\n return Promise.resolve(true);\n }\n beforeNext() {\n return this.beforePage(true);\n }\n /**\n * Called before a submission is triggered allowing the components\n * to perform special async functions.\n *\n * @return {*}\n */\n beforeSubmit() {\n return Promise.resolve(true);\n }\n /**\n * Return the submission timezone.\n *\n * @return {*}\n */\n get submissionTimezone() {\n this.options.submissionTimezone = this.options.submissionTimezone || lodash_1.default.get(this.root, 'options.submissionTimezone');\n return this.options.submissionTimezone;\n }\n get timezone() {\n return this.getTimezone(this.component);\n }\n getTimezone(settings) {\n if (settings.timezone) {\n return settings.timezone;\n }\n if (settings.displayInTimezone === 'utc') {\n return 'UTC';\n }\n const submissionTimezone = this.submissionTimezone;\n if (submissionTimezone &&\n ((settings.displayInTimezone === 'submission') ||\n ((this.options.pdf || this.options.server) && (settings.displayInTimezone === 'viewer')))) {\n return submissionTimezone;\n }\n // Return current timezone if none are provided.\n return (0, utils_1.currentTimezone)();\n }\n /**\n *\n * @param {HTMLElement} element - The containing DOM element to query for the ref value.\n * @param {object} refs - The references to load.\n * @param {string} [referenceAttributeName] - The attribute name to use for the reference.\n */\n loadRefs(element, refs, referenceAttributeName) {\n for (const ref in refs) {\n const refType = refs[ref];\n const isString = typeof refType === 'string';\n const selector = isString && refType.includes('scope')\n ? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`\n : `[${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`;\n if (isString && refType.startsWith('single')) {\n this.refs[ref] = element.querySelector(selector);\n }\n else {\n this.refs[ref] = element.querySelectorAll(selector);\n }\n }\n }\n setOpenModalElement(template) {\n this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());\n }\n getModalPreviewTemplate() {\n var _a;\n const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;\n let modalLabel;\n if (this.hasInput && ((_a = this.component.validate) === null || _a === void 0 ? void 0 : _a.required) && !this.isPDFReadOnlyMode) {\n modalLabel = { className: 'field-required' };\n }\n return this.renderTemplate('modalPreview', {\n previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'),\n messages: '',\n labelInfo: modalLabel,\n });\n }\n build(element) {\n element = element || this.element;\n this.empty(element);\n this.setContent(element, this.render());\n return this.attach(element);\n }\n get hasModalSaveButton() {\n return true;\n }\n render(children = `Unknown component: ${this.component.type}`, topLevel = false) {\n const isVisible = this.visible;\n this.rendered = true;\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n return ComponentModal_1.default.render(this, {\n visible: isVisible,\n showSaveButton: this.hasModalSaveButton,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n else {\n return this.renderTemplate('component', {\n visible: isVisible,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n }\n attachTooltips(toolTipsRefs) {\n toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach((tooltip, index) => {\n if (tooltip) {\n const tooltipAttribute = tooltip.getAttribute('data-tooltip');\n const tooltipDataTitle = tooltip.getAttribute('data-title');\n const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)\n .replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n this.tooltips[index] = (0, tippy_js_1.default)(tooltip, {\n allowHTML: true,\n trigger: 'mouseenter click focus',\n placement: 'right',\n zIndex: 10000,\n interactive: true,\n content: this.t(this.sanitize(tooltipText), { _userInput: true }),\n });\n }\n });\n }\n createComponentModal(element, modalShouldBeOpened, currentValue) {\n return new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n }\n attach(element) {\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n const openModalTemplate = this.componentModal && modalShouldBeOpened\n ? this.componentModal.openModalTemplate\n : null;\n this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue);\n this.setOpenModalElement(openModalTemplate);\n }\n this.attached = true;\n this.setElement(element);\n element.component = this;\n // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id.\n if (this.element.id) {\n this.id = this.element.id;\n this.component.id = this.id;\n }\n this.loadRefs(element, {\n messageContainer: 'single',\n tooltip: 'multiple'\n });\n this.attachTooltips(this.refs.tooltip);\n // Attach logic.\n this.attachLogic();\n this.autofocus();\n // Allow global attach.\n this.hook('attachComponent', element, this);\n // Allow attach per component type.\n const type = this.component.type;\n if (type) {\n this.hook(`attach${type.charAt(0).toUpperCase() + type.substring(1, type.length)}`, element, this);\n }\n this.restoreFocus();\n this.addons.forEach((addon) => addon.attach(element));\n return Promise.resolve();\n }\n restoreFocus() {\n var _a, _b, _c;\n const isFocused = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.path) === this.path;\n if (isFocused) {\n this.loadRefs(this.element, { input: 'multiple' });\n this.focus((_c = this.root.currentSelection) === null || _c === void 0 ? void 0 : _c.index);\n this.restoreCaretPosition();\n }\n }\n addShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || !this.root || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.addShortcut(element, shortcut);\n }\n removeShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.removeShortcut(element, shortcut);\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n // First iterate through each ref and delete the component so there are no dangling component references.\n lodash_1.default.each(this.refs, (ref) => {\n if (typeof ref === NodeList) {\n ref.forEach((elem) => {\n delete elem.component;\n });\n }\n else if (ref) {\n delete ref.component;\n }\n });\n this.refs = {};\n this.removeEventListeners();\n this.detachLogic();\n if (this.tooltip) {\n this.tooltip.destroy();\n }\n }\n checkRefresh(refreshData, changed, flags) {\n const changePath = lodash_1.default.get(changed, 'instance.path', false);\n // Don't let components change themselves.\n if (changePath && this.path === changePath) {\n return;\n }\n if (refreshData === 'data') {\n this.refresh(this.data, changed, flags);\n }\n else if ((changePath && (0, utils_1.getComponentPath)(changed.instance) === refreshData) && changed && changed.instance &&\n // Make sure the changed component is not in a different \"context\". Solves issues where refreshOn being set\n // in fields inside EditGrids could alter their state from other rows (which is bad).\n this.inContext(changed.instance)) {\n this.refresh(changed.value, changed, flags);\n }\n }\n checkRefreshOn(changes, flags = {}) {\n changes = changes || [];\n if (flags.noRefresh) {\n return;\n }\n if (!changes.length && flags.changed) {\n changes = [flags.changed];\n }\n const refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn;\n // If they wish to refresh on a value, then add that here.\n if (refreshOn) {\n if (Array.isArray(refreshOn)) {\n refreshOn.forEach(refreshData => changes.forEach(changed => this.checkRefresh(refreshData, changed, flags)));\n }\n else {\n changes.forEach(changed => this.checkRefresh(refreshOn, changed, flags));\n }\n }\n }\n /**\n * Refreshes the component with a new value.\n *\n * @param value\n */\n refresh(value) {\n if (this.hasOwnProperty('refreshOnValue')) {\n this.refreshOnChanged = !lodash_1.default.isEqual(value, this.refreshOnValue);\n }\n else {\n this.refreshOnChanged = true;\n }\n this.refreshOnValue = (0, utils_1.fastCloneDeep)(value);\n if (this.refreshOnChanged) {\n if (this.component.clearOnRefresh) {\n this.setValue(null);\n }\n this.triggerRedraw();\n }\n }\n /**\n * Checks to see if a separate component is in the \"context\" of this component. This is determined by first checking\n * if they share the same \"data\" object. It will then walk up the parent tree and compare its parents data objects\n * with the components data and returns true if they are in the same context.\n *\n * Different rows of the same EditGrid, for example, are in different contexts.\n *\n * @param component\n */\n inContext(component) {\n if (component.data === this.data) {\n return true;\n }\n let parent = this.parent;\n while (parent) {\n if (parent.data === component.data) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n get viewOnly() {\n return this.options.readOnly && this.options.viewAsHtml;\n }\n setElement(element) {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n this.element = element;\n }\n createViewOnlyElement() {\n this.setElement(this.ce('dl', {\n id: this.id\n }));\n if (this.element) {\n // Ensure you can get the component info from the element.\n this.element.component = this;\n }\n return this.element;\n }\n get defaultViewOnlyValue() {\n return '-';\n }\n /**\n * Uses the widget to determine the output string.\n *\n * @param value\n * @return {*}\n */\n getWidgetValueAsString(value, options) {\n const noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget;\n if (!value || noInputWidget) {\n if (!this.widget || !value) {\n return value;\n }\n else {\n return this.widget.getValueAsString(value);\n }\n }\n if (Array.isArray(value)) {\n const values = [];\n value.forEach((val, index) => {\n const widget = this.refs.input[index] && this.refs.input[index].widget;\n if (widget) {\n values.push(widget.getValueAsString(val, options));\n }\n });\n return values;\n }\n const widget = this.refs.input[0].widget;\n return widget.getValueAsString(value, options);\n }\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n value = this.getWidgetValueAsString(value, options);\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n if (lodash_1.default.isPlainObject(value)) {\n return JSON.stringify(value);\n }\n if (value === null || value === undefined) {\n return '';\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue);\n }\n getView(value, options) {\n if (this.component.protected) {\n return '--- PROTECTED ---';\n }\n return this.getValueAsString(value, options);\n }\n updateItems(...args) {\n this.restoreValue();\n this.onChange(...args);\n }\n /**\n * @param {*} data\n * @param {boolean} [forceUseValue=false] - if true, return 'value' property of the data\n * @return {*}\n */\n itemValue(data, forceUseValue = false) {\n if (lodash_1.default.isObject(data) && !lodash_1.default.isArray(data)) {\n if (this.valueProperty) {\n return lodash_1.default.get(data, this.valueProperty);\n }\n if (forceUseValue) {\n return data.value;\n }\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item) ? this.itemValueForHTMLMode(item) : this.itemValue(item));\n return values.join(', ');\n }\n return this.itemValue(value);\n }\n createModal(element, attr, confirm) {\n const dialog = this.ce('div', attr || {});\n this.setContent(dialog, this.renderTemplate('dialog'));\n // Add refs to dialog, not \"this\".\n dialog.refs = {};\n this.loadRefs.call(dialog, dialog, {\n dialogOverlay: 'single',\n dialogContents: 'single',\n dialogClose: 'single',\n });\n dialog.refs.dialogContents.appendChild(element);\n document.body.appendChild(dialog);\n document.body.classList.add('modal-open');\n dialog.close = () => {\n document.body.classList.remove('modal-open');\n dialog.dispatchEvent(new CustomEvent('close'));\n };\n this.addEventListener(dialog, 'close', () => this.removeChildFrom(dialog, document.body));\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n const handleCloseClick = (e) => {\n if (confirm) {\n confirm().then(() => close(e))\n .catch(() => { });\n }\n else {\n close(e);\n }\n };\n this.addEventListener(dialog.refs.dialogOverlay, 'click', handleCloseClick);\n this.addEventListener(dialog.refs.dialogClose, 'click', handleCloseClick);\n return dialog;\n }\n get optimizeRedraw() {\n if (this.options.optimizeRedraw && this.element && !this.visible) {\n this.addClass(this.element, 'formio-removed');\n return true;\n }\n return false;\n }\n /**\n * Retrieves the CSS class name of this component.\n * @returns {string} - The class name of this component.\n */\n get className() {\n let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback ` : '';\n className += `formio-component formio-component-${this.component.type} `;\n // TODO: find proper way to avoid overriding of default type-based component styles\n if (this.key && this.key !== 'form') {\n className += `formio-component-${this.key} `;\n }\n if (this.component.multiple) {\n className += 'formio-component-multiple ';\n }\n if (this.component.customClass) {\n className += this.component.customClass;\n }\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required)) {\n className += ' required';\n }\n if (this.labelIsHidden()) {\n className += ' formio-component-label-hidden';\n }\n if (!this.visible) {\n className += ' formio-hidden';\n }\n return className;\n }\n /**\n * Build the custom style from the layout values\n * @return {string} - The custom style\n */\n get customStyle() {\n let customCSS = '';\n lodash_1.default.each(this.component.style, (value, key) => {\n if (value !== '') {\n customCSS += `${key}:${value};`;\n }\n });\n return customCSS;\n }\n static get serverConditionSettings() {\n return Component.conditionOperatorsSettings;\n }\n get isMobile() {\n return (0, ismobilejs_1.default)();\n }\n /**\n * Returns the outside wrapping element of this component.\n * @returns {HTMLElement}\n */\n getElement() {\n return this.element;\n }\n /**\n * Create an evaluation context for all script executions and interpolations.\n *\n * @param additional\n * @return {*}\n */\n evalContext(additional) {\n return super.evalContext(Object.assign({\n component: this.component,\n row: this.data,\n rowIndex: this.rowIndex,\n data: this.rootValue,\n iconClass: this.iconClass.bind(this),\n // Bind the translate function to the data context of any interpolated string.\n // It is useful to translate strings in different scenarions (eg: custom edit grid templates, custom error messages etc.)\n // and desirable to be publicly available rather than calling the internal {instance.t} function in the template string.\n t: this.t.bind(this),\n submission: (this.root ? this.root._submission : {\n data: this.rootValue\n }),\n form: this.root ? this.root._form : {},\n options: this.options,\n }, additional));\n }\n /**\n * Sets the pristine flag for this component.\n *\n * @param pristine {boolean} - TRUE to make pristine, FALSE not pristine.\n */\n setPristine(pristine) {\n this.pristine = pristine;\n }\n get isPristine() {\n return this.pristine;\n }\n setDirty(dirty) {\n this.dirty = dirty;\n }\n get isDirty() {\n return this.dirty;\n }\n /**\n * Removes a value out of the data array and rebuild the rows.\n * @param {number} index - The index of the data element to remove.\n */\n removeValue(index) {\n this.splice(index);\n this.redraw();\n this.restoreValue();\n this.triggerRootChange();\n }\n iconClass(name, spinning) {\n const iconset = this.options.iconset || Templates_1.default.current.defaultIconset || 'fa';\n return Templates_1.default.current.hasOwnProperty('iconClass')\n ? Templates_1.default.current.iconClass(iconset, name, spinning)\n : this.options.iconset === 'fa' ? Templates_1.default.defaultTemplates.iconClass(iconset, name, spinning) : name;\n }\n size(size) {\n return Templates_1.default.current.hasOwnProperty('size')\n ? Templates_1.default.current.size(size)\n : size;\n }\n /**\n * The readible name for this component.\n * @returns {string} - The name of the component.\n */\n get name() {\n return this.t(this.component.label || this.component.placeholder || this.key, { _userInput: true });\n }\n get visibleErrors() {\n return this._visibleErrors;\n }\n get errors() {\n return this._errors;\n }\n /**\n * Returns the error label for this component.\n * @return {*}\n */\n get errorLabel() {\n return this.t(this.component.errorLabel\n || this.component.label\n || this.component.placeholder\n || this.key);\n }\n /**\n * Get the error message provided a certain type of error.\n * @param type\n * @return {*}\n */\n errorMessage(type) {\n return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type;\n }\n setContent(element, content, forceSanitize, sanitizeOptions) {\n if (element instanceof HTMLElement) {\n element.innerHTML = this.sanitize(content, forceSanitize, sanitizeOptions);\n return true;\n }\n return false;\n }\n restoreCaretPosition() {\n var _a, _b, _c;\n if ((_a = this.root) === null || _a === void 0 ? void 0 : _a.currentSelection) {\n if ((_b = this.refs.input) === null || _b === void 0 ? void 0 : _b.length) {\n const { selection, index } = this.root.currentSelection;\n let input = this.refs.input[index];\n const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test((i === null || i === void 0 ? void 0 : i.type) || '');\n if (input) {\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(...selection);\n }\n }\n else {\n input = this.refs.input[this.refs.input.length];\n const lastCharacter = ((_c = input.value) === null || _c === void 0 ? void 0 : _c.length) || 0;\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(lastCharacter, lastCharacter);\n }\n }\n }\n }\n }\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element || !this.element.parentNode || this.optimizeRedraw) {\n // Return a non-resolving promise.\n return Promise.resolve();\n }\n this.detach();\n this.emit('redraw');\n // Since we are going to replace the element, we need to know it's position so we can find it in the parent's children.\n const parent = this.element.parentNode;\n const index = Array.prototype.indexOf.call(parent.children, this.element);\n this.element.outerHTML = this.sanitize(this.render());\n this.setElement(parent.children[index]);\n return this.attach(this.element);\n }\n rebuild() {\n this.destroy();\n this.init();\n this.visible = this.conditionallyVisible(null, null);\n return this.redraw();\n }\n removeEventListeners() {\n super.removeEventListeners();\n this.tooltips.forEach(tooltip => tooltip.destroy());\n this.tooltips = [];\n }\n hasClass(element, className) {\n if (!element) {\n return;\n }\n return super.hasClass(element, this.transform('class', className));\n }\n addClass(element, className) {\n if (!element) {\n return;\n }\n return super.addClass(element, this.transform('class', className));\n }\n removeClass(element, className) {\n if (!element) {\n return;\n }\n return super.removeClass(element, this.transform('class', className));\n }\n /**\n * Determines if this component has a condition defined.\n *\n * @return {null}\n */\n hasCondition() {\n if (this._hasCondition !== null) {\n return this._hasCondition;\n }\n this._hasCondition = FormioUtils.hasCondition(this.component);\n return this._hasCondition;\n }\n /**\n * Check if this component is conditionally visible.\n *\n * @param data\n * @return {boolean}\n */\n conditionallyVisible(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n if (this.builderMode || this.previewMode || !this.hasCondition()) {\n return !this.component.hidden;\n }\n data = data || (this.root ? this.root.data : {});\n return this.checkCondition(row, data);\n }\n /**\n * Checks the condition of this component.\n *\n * TODO: Switch row and data parameters to be consistent with other methods.\n *\n * @param row - The row contextual data.\n * @param data - The global data object.\n * @return {boolean} - True if the condition applies to this component.\n */\n checkCondition(row, data) {\n return FormioUtils.checkCondition(this.component, row || this.data, data || this.rootValue, this.root ? this.root._form : {}, this);\n }\n /**\n * Check for conditionals and hide/show the element based on those conditions.\n */\n checkComponentConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {\n this.redraw();\n }\n // Check advanced conditions\n const visible = this.conditionallyVisible(data, row);\n if (this.visible !== visible) {\n this.visible = visible;\n }\n return visible;\n }\n /**\n * Checks conditions for this component and any sub components.\n * @param args\n * @return {boolean}\n */\n checkConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.checkComponentConditions(data, flags, row);\n }\n get logic() {\n return this.component.logic || [];\n }\n /**\n * Check all triggers and apply necessary actions.\n *\n * @param data\n */\n fieldLogic(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n const logics = this.logic;\n // If there aren't logic, don't go further.\n if (logics.length === 0) {\n return;\n }\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n let changed = logics.reduce((changed, logic) => {\n const result = FormioUtils.checkTrigger(newComponent, logic.trigger, row, data, this.root ? this.root._form : {}, this);\n return (result ? this.applyActions(newComponent, logic.actions, result, row, data) : false) || changed;\n }, false);\n // If component definition changed, replace and mark as changed.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n changed = true;\n const disabled = this.shouldDisabled;\n // Change disabled state if it has changed\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n }\n return changed;\n }\n isIE() {\n if (typeof window === 'undefined') {\n return false;\n }\n const userAgent = window.navigator.userAgent;\n const msie = userAgent.indexOf('MSIE ');\n if (msie > 0) {\n // IE 10 or older => return version number\n return parseInt(userAgent.substring(msie + 5, userAgent.indexOf('.', msie)), 10);\n }\n const trident = userAgent.indexOf('Trident/');\n if (trident > 0) {\n // IE 11 => return version number\n const rv = userAgent.indexOf('rv:');\n return parseInt(userAgent.substring(rv + 3, userAgent.indexOf('.', rv)), 10);\n }\n const edge = userAgent.indexOf('Edge/');\n if (edge > 0) {\n // IE 12 (aka Edge) => return version number\n return parseInt(userAgent.substring(edge + 5, userAgent.indexOf('.', edge)), 10);\n }\n // other browser\n return false;\n }\n defineActionValue(action, argsObject) {\n return this.evaluate(action.value, argsObject, 'value');\n }\n applyActions(newComponent, actions, result, row, data) {\n data = data || this.rootValue;\n row = row || this.data;\n return actions.reduce((changed, action) => {\n switch (action.type) {\n case 'property': {\n FormioUtils.setActionProperty(newComponent, action, result, row, data, this);\n const property = action.property.value;\n if (!lodash_1.default.isEqual(lodash_1.default.get(this.component, property), lodash_1.default.get(newComponent, property))) {\n changed = true;\n }\n break;\n }\n case 'value': {\n const oldValue = this.getValue();\n const newValue = this.defineActionValue(action, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n component: newComponent,\n result,\n });\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n case 'mergeComponentSchema': {\n const schema = this.evaluate(action.schemaDefinition, {\n value: lodash_1.default.clone(this.getValue()),\n data,\n row,\n component: newComponent,\n result,\n }, 'schema');\n lodash_1.default.assign(newComponent, schema);\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n changed = true;\n }\n break;\n }\n case 'customAction': {\n const oldValue = this.getValue();\n const newValue = this.evaluate(action.customAction, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n input: oldValue,\n component: newComponent,\n result,\n }, 'value');\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n }\n return changed;\n }, false);\n }\n // Deprecated\n addInputError(message, dirty, elements) {\n this.addMessages(message);\n this.setErrorClasses(elements, dirty, !!message);\n }\n // Deprecated\n removeInputError(elements) {\n this.setErrorClasses(elements, true, false);\n }\n /**\n * Add a new input error to this element.\n *\n * @param message\n * @param dirty\n */\n addMessages(messages) {\n if (!messages) {\n return;\n }\n // Standardize on array of objects for message.\n if (typeof messages === 'string') {\n messages = {\n messages,\n level: 'error',\n };\n }\n if (!Array.isArray(messages)) {\n messages = [messages];\n }\n messages = lodash_1.default.uniqBy(messages, message => message.message);\n if (this.refs.messageContainer) {\n this.setContent(this.refs.messageContainer, messages.map((message) => {\n if (message.message && typeof message.message === 'string') {\n message.message = message.message.replaceAll('<', '<').replaceAll('>', '>');\n }\n return this.renderTemplate('message', Object.assign({}, message));\n }).join(''));\n }\n }\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n this.clearErrorClasses();\n elements.forEach((element) => {\n this.setElementInvalid(this.performInputMapping(element), false);\n });\n this.setInputWidgetErrorClasses(elements, hasErrors);\n // do not set error classes for hidden components\n if (!this.visible) {\n return;\n }\n if (hasErrors) {\n // Add error classes\n elements.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), true);\n });\n if (dirty && this.options.highlightErrors) {\n this.addClass(element, this.options.componentErrorClass);\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n if (hasMessages) {\n this.addClass(element, 'has-message');\n }\n }\n setElementInvalid(element, invalid) {\n if (!element)\n return;\n if (invalid) {\n this.addClass(element, 'is-invalid');\n }\n else {\n this.removeClass(element, 'is-invalid');\n }\n element.setAttribute('aria-invalid', invalid ? 'true' : 'false');\n }\n clearOnHide() {\n // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.\n if (\n // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true\n (!this.rootPristine || this.options.server || (0, utils_1.isInsideScopingComponent)(this)) &&\n this.component.clearOnHide !== false &&\n !this.options.readOnly &&\n !this.options.showHiddenFields) {\n if (!this.visible) {\n this.deleteValue();\n }\n else if (!this.hasValue() && this.shouldAddDefaultValue) {\n // If shown, ensure the default is set.\n this.setValue(this.defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n }\n triggerRootChange(...args) {\n if (this.options.onChange) {\n this.options.onChange(...args);\n }\n else if (this.root && this.root.triggerChange) {\n this.root.triggerChange(...args);\n }\n }\n onChange(flags, fromRoot) {\n flags = flags || {};\n if (flags.modified) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n this.addClass(this.getElement(), 'formio-modified');\n }\n // If we are supposed to validate on blur, then don't trigger validation yet.\n if (this.component.validateOn === 'blur') {\n flags.noValidate = true;\n }\n if (this.component.onChange) {\n this.evaluate(this.component.onChange, {\n flags\n });\n }\n // Set the changed variable.\n const changed = {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: flags\n };\n // Emit the change.\n this.emit('componentChange', changed);\n // Do not propogate the modified flag.\n let modified = false;\n if (flags.modified) {\n modified = true;\n delete flags.modified;\n }\n // Bubble this change up to the top.\n if (!fromRoot) {\n this.triggerRootChange(flags, changed, modified);\n }\n return changed;\n }\n get wysiwygDefault() {\n return {\n quill: {\n theme: 'snow',\n placeholder: this.t(this.component.placeholder, { _userInput: true }),\n modules: {\n toolbar: [\n [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown\n [{ 'header': [1, 2, 3, 4, 5, 6, false] }],\n [{ 'font': [] }],\n ['bold', 'italic', 'underline', 'strike', { 'script': 'sub' }, { 'script': 'super' }, 'clean'],\n [{ 'color': [] }, { 'background': [] }],\n [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }, { 'align': [] }],\n ['blockquote', 'code-block'],\n ['link', 'image', 'video', 'formula', 'source']\n ]\n }\n },\n ace: {\n theme: 'ace/theme/xcode',\n maxLines: 12,\n minLines: 12,\n tabSize: 2,\n mode: 'ace/mode/javascript',\n placeholder: this.t(this.component.placeholder, { _userInput: true })\n },\n ckeditor: {\n image: {\n toolbar: [\n 'imageTextAlternative',\n '|',\n 'imageStyle:full',\n 'imageStyle:alignLeft',\n 'imageStyle:alignCenter',\n 'imageStyle:alignRight'\n ],\n styles: [\n 'full',\n 'alignLeft',\n 'alignCenter',\n 'alignRight'\n ]\n },\n extraPlugins: []\n },\n default: {}\n };\n }\n addCKE(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? {} : settings;\n settings.base64Upload = this.component.isUploadEnabled ? false : true;\n settings.mediaEmbed = { previewsInData: true };\n settings = lodash_1.default.merge(this.wysiwygDefault.ckeditor, lodash_1.default.get(this.options, 'editors.ckeditor.settings', {}), settings);\n if (this.component.isUploadEnabled) {\n settings.extraPlugins.push((0, uploadAdapter_1.getFormioUploadAdapterPlugin)(this.fileService, this));\n }\n return Formio_1.Formio.requireLibrary('ckeditor', isIEBrowser ? 'CKEDITOR' : 'ClassicEditor', lodash_1.default.get(this.options, 'editors.ckeditor.src', `${Formio_1.Formio.cdn.ckeditor}/ckeditor.js`), true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n if (isIEBrowser) {\n const editor = CKEDITOR.replace(element);\n editor.on('change', () => onChange(editor.getData()));\n return Promise.resolve(editor);\n }\n else {\n return ClassicEditor.create(element, settings).then(editor => {\n editor.model.document.on('change', () => onChange(editor.data.get()));\n return editor;\n });\n }\n });\n }\n addQuill(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? this.wysiwygDefault.quill : settings;\n settings = lodash_1.default.merge(this.wysiwygDefault.quill, lodash_1.default.get(this.options, 'editors.quill.settings', {}), settings);\n settings = Object.assign(Object.assign({}, settings), { modules: Object.assign({ table: true }, settings.modules) });\n // Lazy load the quill css.\n Formio_1.Formio.requireLibrary(`quill-css-${settings.theme}`, 'Quill', [\n { type: 'styles', src: `${Formio_1.Formio.cdn.quill}/quill.${settings.theme}.css` }\n ], true);\n // Lazy load the quill library.\n return Formio_1.Formio.requireLibrary('quill', 'Quill', lodash_1.default.get(this.options, 'editors.quill.src', `${Formio_1.Formio.cdn.quill}/quill.min.js`), true)\n .then(() => {\n return Formio_1.Formio.requireLibrary('quill-table', 'Quill', `${Formio_1.Formio.cdn.baseUrl}/quill/quill-table.js`, true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n this.quill = new Quill(element, isIEBrowser ? Object.assign(Object.assign({}, settings), { modules: {} }) : settings);\n /** This block of code adds the [source] capabilities. See https://codepen.io/anon/pen/ZyEjrQ **/\n const txtArea = document.createElement('textarea');\n txtArea.setAttribute('class', 'quill-source-code');\n this.quill.addContainer('ql-custom').appendChild(txtArea);\n const qlSource = element.parentNode.querySelector('.ql-source');\n if (qlSource) {\n this.addEventListener(qlSource, 'click', (event) => {\n event.preventDefault();\n if (txtArea.style.display === 'inherit') {\n this.quill.setContents(this.quill.clipboard.convert({ html: txtArea.value }));\n }\n txtArea.style.display = (txtArea.style.display === 'none') ? 'inherit' : 'none';\n });\n }\n /** END CODEBLOCK **/\n // Make sure to select cursor when they click on the element.\n this.addEventListener(element, 'click', () => this.quill.focus());\n // Allows users to skip toolbar items when tabbing though form\n const elm = document.querySelectorAll('.ql-formats > button');\n for (let i = 0; i < elm.length; i++) {\n elm[i].setAttribute('tabindex', '-1');\n }\n this.quill.on('text-change', () => {\n txtArea.value = this.quill.root.innerHTML;\n onChange(txtArea);\n });\n return this.quill;\n });\n });\n }\n get shouldSanitizeValue() {\n var _a;\n // Sanitize value if sanitizing for thw whole content is turned off\n return (((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitize) !== false);\n }\n addAce(element, settings, onChange) {\n if (!settings || (settings.theme === 'snow')) {\n const mode = settings ? settings.mode : '';\n settings = {};\n if (mode) {\n settings.mode = mode;\n }\n }\n settings = lodash_1.default.merge(this.wysiwygDefault.ace, lodash_1.default.get(this.options, 'editors.ace.settings', {}), settings || {});\n return Formio_1.Formio.requireLibrary('ace', 'ace', lodash_1.default.get(this.options, 'editors.ace.src', `${Formio_1.Formio.cdn.ace}/ace.js`), true)\n .then((editor) => {\n editor = editor.edit(element);\n editor.removeAllListeners('change');\n editor.setOptions(settings);\n editor.getSession().setMode(settings.mode);\n editor.on('change', () => onChange(editor.getValue()));\n if (settings.isUseWorkerDisabled) {\n editor.session.setUseWorker(false);\n }\n return editor;\n });\n }\n get tree() {\n return this.component.tree || false;\n }\n /**\n * The empty value for this component.\n *\n * @return {null}\n */\n get emptyValue() {\n return null;\n }\n /**\n * Returns if this component has a value set.\n *\n */\n hasValue(data) {\n return !lodash_1.default.isUndefined(lodash_1.default.get(data || this.data, this.key));\n }\n /**\n * Get the data value at the root level.\n *\n * @return {*}\n */\n get rootValue() {\n return this.root ? this.root.data : this.data;\n }\n get rootPristine() {\n return lodash_1.default.get(this, 'root.pristine', false);\n }\n /**\n * Get the static value of this component.\n * @return {*}\n */\n get dataValue() {\n if (!this.key ||\n (!this.visible && this.component.clearOnHide && !this.rootPristine)) {\n return this.emptyValue;\n }\n if (!this.hasValue() && this.shouldAddDefaultValue) {\n const empty = this.component.multiple ? [] : this.emptyValue;\n if (!this.rootPristine) {\n this.dataValue = empty;\n }\n return empty;\n }\n return lodash_1.default.get(this._data, this.key);\n }\n /**\n * Sets the static value of this component.\n *\n * @param value\n */\n set dataValue(value) {\n if (!this.allowData ||\n !this.key ||\n (!this.visible && this.component.clearOnHide && !this.rootPristine)) {\n return;\n }\n if ((value !== null) && (value !== undefined)) {\n value = this.hook('setDataValue', value, this.key, this._data);\n }\n if ((value === null) || (value === undefined)) {\n this.unset();\n return;\n }\n lodash_1.default.set(this._data, this.key, value);\n return;\n }\n /**\n * Splice a value from the dataValue.\n *\n * @param index\n */\n splice(index, flags = {}) {\n if (this.hasValue()) {\n const dataValue = this.dataValue || [];\n if (lodash_1.default.isArray(dataValue) && dataValue.hasOwnProperty(index)) {\n dataValue.splice(index, 1);\n this.dataValue = dataValue;\n this.triggerChange(flags);\n }\n }\n }\n unset() {\n lodash_1.default.unset(this._data, this.key);\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n getCustomDefaultValue(defaultValue) {\n if (this.component.customDefaultValue && !this.options.preview) {\n defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');\n }\n return defaultValue;\n }\n get shouldAddDefaultValue() {\n return !this.options.noDefaults || (this.component.defaultValue && !this.isEmpty(this.component.defaultValue)) || this.component.customDefaultValue;\n }\n get defaultValue() {\n let defaultValue = this.emptyValue;\n if (this.component.defaultValue) {\n defaultValue = this.component.defaultValue;\n }\n defaultValue = this.getCustomDefaultValue(defaultValue);\n const checkMask = (value) => {\n if (typeof value === 'string') {\n if (this.component.type !== 'textfield') {\n const placeholderChar = this.placeholderChar;\n value = (0, vanilla_text_mask_1.conformToMask)(value, this.defaultMask, { placeholderChar }).conformedValue;\n if (!FormioUtils.matchInputMask(value, this.defaultMask)) {\n value = '';\n }\n }\n }\n else {\n value = '';\n }\n return value;\n };\n if (this.defaultMask) {\n if (Array.isArray(defaultValue)) {\n defaultValue = defaultValue.map(checkMask);\n }\n else {\n defaultValue = checkMask(defaultValue);\n }\n }\n // Clone so that it creates a new instance.\n return lodash_1.default.cloneDeep(defaultValue);\n }\n /**\n * Get the input value of this component.\n *\n * @return {*}\n */\n getValue() {\n if (!this.hasInput || this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n const values = [];\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n if (!this.component.multiple) {\n return this.getValueAt(i);\n }\n values.push(this.getValueAt(i));\n }\n }\n if (values.length === 0 && !this.component.multiple) {\n return '';\n }\n return values;\n }\n /**\n * Get the value at a specific index.\n *\n * @param index\n * @returns {*}\n */\n getValueAt(index) {\n const input = this.performInputMapping(this.refs.input[index]);\n return input ? input.value : undefined;\n }\n /**\n * Set the value of this component.\n *\n * @param value\n * @param flags\n *\n * @return {boolean} - If the value changed.\n */\n setValue(value, flags = {}) {\n const changed = this.updateValue(value, flags);\n value = this.dataValue;\n if (!this.hasInput) {\n return changed;\n }\n const isArray = Array.isArray(value);\n const valueInput = this.refs.fileLink || this.refs.input;\n if (isArray &&\n Array.isArray(this.defaultValue) &&\n this.refs.hasOwnProperty('input') &&\n valueInput &&\n (valueInput.length !== value.length) &&\n this.visible) {\n this.redraw();\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.redraw();\n return changed;\n }\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n this.setValueAt(i, isArray ? value[i] : value, flags);\n }\n }\n return changed;\n }\n /**\n * Set the value at a specific index.\n *\n * @param index\n * @param value\n */\n setValueAt(index, value, flags = {}) {\n if (!flags.noDefault && (value === null || value === undefined) && !this.component.multiple) {\n value = this.defaultValue;\n }\n const input = this.performInputMapping(this.refs.input[index]);\n const valueMaskInput = this.refs.valueMaskInput;\n if ((valueMaskInput === null || valueMaskInput === void 0 ? void 0 : valueMaskInput.mask) && valueMaskInput.mask.textMaskInputElement) {\n valueMaskInput.mask.textMaskInputElement.update(value);\n }\n if (input.mask && input.mask.textMaskInputElement) {\n input.mask.textMaskInputElement.update(value);\n }\n else if (input.widget && input.widget.setValue) {\n input.widget.setValue(value);\n }\n else {\n input.value = value;\n }\n }\n get hasSetValue() {\n return this.hasValue() && !this.isEmpty(this.dataValue);\n }\n setDefaultValue() {\n if (this.defaultValue && this.shouldAddDefaultValue) {\n const defaultValue = (this.component.multiple && !this.dataValue.length) ? [] : this.defaultValue;\n this.setValue(defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n /**\n * Restore the value of a control.\n */\n restoreValue() {\n if (this.hasSetValue) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else {\n this.setDefaultValue();\n }\n }\n /**\n * Normalize values coming into updateValue.\n *\n * @param value\n * @return {*}\n */\n normalizeValue(value) {\n if (this.component.multiple && !Array.isArray(value)) {\n value = value ? [value] : [];\n }\n return value;\n }\n /**\n * Update a value of this component.\n *\n * @param flags\n */\n updateComponentValue(value, flags = {}) {\n let newValue = (!flags.resetValue && (value === undefined || value === null)) ? this.getValue() : value;\n newValue = this.normalizeValue(newValue, flags);\n const oldValue = this.dataValue;\n let changed = ((newValue !== undefined) ? this.hasChanged(newValue, oldValue) : false);\n if (changed) {\n this.dataValue = newValue;\n changed = this.dataValue !== oldValue;\n this.updateOnChange(flags, changed);\n }\n if (this.componentModal && flags && flags.fromSubmission) {\n this.componentModal.setValue(value);\n }\n return changed;\n }\n /**\n * Updates the value of this component plus all sub-components.\n *\n * @param args\n * @return {boolean}\n */\n updateValue(...args) {\n return this.updateComponentValue(...args);\n }\n getIcon(name, content, styles, ref = 'icon') {\n return this.renderTemplate('icon', {\n className: this.iconClass(name),\n ref,\n styles,\n content\n });\n }\n /**\n * Resets the value of this component.\n */\n resetValue() {\n this.unset();\n this.setValue(this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n /**\n * Determine if the value of this component has changed.\n *\n * @param newValue\n * @param oldValue\n * @return {boolean}\n */\n hasChanged(newValue, oldValue) {\n if (((newValue === undefined) || (newValue === null)) &&\n ((oldValue === undefined) || (oldValue === null) || this.isEmpty(oldValue))) {\n return false;\n }\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n this.allowData &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n /**\n * Update the value on change.\n *\n * @param flags\n */\n updateOnChange(flags = {}, changed = false) {\n if (!flags.noUpdateEvent && changed) {\n if (flags.fromSubmission) {\n // Reset the errors when a submission has been made and allow it to revalidate.\n this._errors = [];\n }\n this.triggerChange(flags);\n return true;\n }\n return false;\n }\n /**\n * Perform a calculated value operation.\n *\n * @param data - The global data object.\n *\n * @return {boolean} - If the value changed during calculation.\n */\n convertNumberOrBoolToString(value) {\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n return value;\n }\n doValueCalculation(dataValue, data, row) {\n var _a;\n return this.evaluate(this.component.calculateValue, {\n value: dataValue,\n data,\n row: row || this.data,\n submission: ((_a = this.root) === null || _a === void 0 ? void 0 : _a._submission) || {\n data: this.rootValue\n }\n }, 'value');\n }\n /* eslint-disable max-statements */\n calculateComponentValue(data, flags, row) {\n // Skip value calculation for the component if we don't have entire form data set or in builder mode\n if (this.builderMode || lodash_1.default.isUndefined(lodash_1.default.get(this, 'root.data'))) {\n return false;\n }\n // If no calculated value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n const { clearOnHide } = this.component;\n const shouldBeCleared = !this.visible && clearOnHide;\n const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);\n if (shouldBeCleared) {\n // remove calculated value so that the value is recalculated once component becomes visible\n if (this.hasOwnProperty('calculatedValue') && allowOverride) {\n lodash_1.default.unset(this, 'calculatedValue');\n }\n return false;\n }\n // Handle all cases when calculated values should not fire.\n if ((this.options.readOnly && !this.options.pdf && !this.component.calculateValue) ||\n !(this.component.calculateValue || this.component.calculateValueVariable) ||\n (this.options.server && !this.component.calculateServer) ||\n (flags.dataSourceInitialLoading && allowOverride)) {\n return false;\n }\n const dataValue = this.dataValue;\n // Calculate the new value.\n let calculatedValue = this.doValueCalculation(dataValue, data, row, flags);\n if (this.options.readOnly && dataValue && !calculatedValue) {\n return false;\n }\n if (lodash_1.default.isNil(calculatedValue)) {\n calculatedValue = this.emptyValue;\n }\n const changed = !lodash_1.default.isEqual(dataValue, calculatedValue);\n // Do not override calculations on server if they have calculateServer set.\n if (allowOverride) {\n // The value is considered locked if it is not empty and comes from a submission value.\n const fromSubmission = (flags.fromSubmission && this.component.persistent === true);\n if (this.isEmpty(dataValue)) {\n // Reset the calculation lock if ever the data is cleared.\n this.calculationLocked = false;\n }\n else if (this.calculationLocked || fromSubmission) {\n this.calculationLocked = true;\n return false;\n }\n const firstPass = (this.calculatedValue === undefined) || flags.resetValue;\n if (firstPass) {\n this.calculatedValue = null;\n }\n const newCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(calculatedValue));\n const previousCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(this.calculatedValue));\n const normalizedDataValue = this.normalizeValue(this.convertNumberOrBoolToString(dataValue));\n const calculationChanged = !lodash_1.default.isEqual(previousCalculatedValue, newCalculatedValue);\n const previousChanged = !lodash_1.default.isEqual(normalizedDataValue, previousCalculatedValue);\n if (calculationChanged && previousChanged && !firstPass) {\n return false;\n }\n // Check to ensure that the calculated value is different than the previously calculated value.\n if (previousCalculatedValue && previousChanged && !calculationChanged) {\n this.calculatedValue = null;\n return false;\n }\n if (flags.isReordered || !calculationChanged) {\n return false;\n }\n if (fromSubmission) {\n // If we set value from submission and it differs from calculated one, set the calculated value to prevent overriding dataValue in the next pass\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n return false;\n }\n // If this is the firstPass, and the dataValue is different than to the calculatedValue.\n if (firstPass && !this.isEmpty(dataValue) && changed && calculationChanged) {\n // Return that we have a change so it will perform another pass.\n return true;\n }\n }\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n if (changed) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n flags.triggeredComponentId = this.id;\n return this.setValue(calculatedValue, flags);\n }\n return false;\n }\n /* eslint-enable max-statements */\n /**\n * Performs calculations in this component plus any child components.\n *\n * @param args\n * @return {boolean}\n */\n calculateValue(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.calculateComponentValue(data, flags, row);\n }\n /**\n * Get this component's label text.\n *\n */\n get label() {\n return this.component.label;\n }\n /**\n * Set this component's label text and render it.\n *\n * @param value - The new label text.\n */\n set label(value) {\n this.component.label = value;\n if (this.labelElement) {\n this.labelElement.innerText = value;\n }\n }\n /**\n * Get FormioForm element at the root of this component tree.\n *\n */\n getRoot() {\n return this.root;\n }\n /**\n * Returns the invalid message, or empty string if the component is valid.\n *\n * @param data\n * @param dirty\n * @return {*}\n */\n invalidMessage(data, dirty, ignoreCondition, row) {\n if (!ignoreCondition && !this.checkCondition(row, data)) {\n return '';\n }\n // See if this is forced invalid.\n if (this.invalid) {\n return this.invalid;\n }\n // No need to check for errors if there is no input or if it is pristine.\n if (!this.hasInput || (!dirty && this.pristine)) {\n return '';\n }\n const validationScope = { errors: [] };\n (0, process_1.processOneSync)({\n component: this.component,\n data,\n row,\n path: this.path || this.component.key,\n scope: validationScope,\n instance: this,\n processors: [\n process_1.validateProcessInfo\n ]\n });\n const errors = validationScope.errors;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return lodash_1.default.map(interpolatedErrors, 'message').join('\\n\\n');\n }\n /**\n * Returns if the component is valid or not.\n *\n * @param data\n * @param dirty\n * @return {boolean}\n */\n isValid(data, dirty) {\n return !this.invalidMessage(data, dirty);\n }\n setComponentValidity(errors, dirty, silentCheck) {\n if (silentCheck) {\n return [];\n }\n const messages = errors.filter(message => !message.fromServer);\n if (errors.length && !!messages.length && (!this.isEmpty(this.defaultValue) || dirty || !this.pristine)) {\n return this.setCustomValidity(messages, dirty);\n }\n else {\n return this.setCustomValidity('');\n }\n }\n /**\n * Interpolate errors from the validation methods.\n * @param {*} errors\n * @returns\n */\n interpolateErrors(errors) {\n var _a;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return ((_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.length) ? [...interpolatedErrors, ...this.serverErrors] : interpolatedErrors;\n }\n /**\n * Show component validation errors.\n * @param {*} errors - An array of errors that have occured.\n * @param {*} data - The root submission data.\n * @param {*} row - The contextual row data.\n * @param {*} flags - The flags to perform validation.\n * @returns\n */\n showValidationErrors(errors, data, row, flags) {\n if (flags.silentCheck) {\n return [];\n }\n if (this.options.alwaysDirty) {\n flags.dirty = true;\n }\n if (flags.fromSubmission && this.hasValue(data)) {\n flags.dirty = true;\n }\n this.setDirty(flags.dirty);\n return this.setComponentValidity(errors, flags.dirty, flags.silentCheck, flags.fromSubmission);\n }\n /**\n * Perform a component validation.\n * @param {*} data - The root data you wish to use for this component.\n * @param {*} row - The contextual row data you wish to use for this component.\n * @param {*} flags - The flags to control the behavior of the validation.\n * @returns\n */\n validateComponent(data, row, flags = {}) {\n data = data || this.rootValue;\n row = row || this.data;\n const { async = false } = flags;\n if (this.shouldSkipValidation(data, row, flags)) {\n return async ? Promise.resolve([]) : [];\n }\n const processContext = {\n component: this.component,\n data,\n row,\n value: this.validationValue,\n path: this.path || this.component.key,\n instance: this,\n scope: { errors: [] },\n processors: [\n process_1.validateProcessInfo\n ]\n };\n if (async) {\n return (0, process_1.processOne)(processContext).then(() => {\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n });\n }\n (0, process_1.processOneSync)(processContext);\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n }\n /**\n * Checks the validity of this component and sets the error message if it is invalid.\n *\n * @param data\n * @param dirty\n * @param row\n * @return {boolean}\n */\n checkComponentValidity(data, dirty, row, flags = {}, allErrors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n flags.dirty = dirty || false;\n if (flags.async) {\n return this.validateComponent(data, row, flags).then((errors) => {\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);\n }\n }\n this.showValidationErrors(errors, data, row, flags);\n return errors.length === 0;\n });\n }\n else {\n const errors = this.validateComponent(data, row, flags);\n this.showValidationErrors(errors, data, row, flags);\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);\n }\n }\n return errors.length === 0;\n }\n }\n /**\n * Checks the validity of the component.\n * @param {*} data\n * @param {*} dirty\n * @param {*} row\n * @param {*} silentCheck\n * @returns\n */\n checkValidity(data, dirty, row, silentCheck, errors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n console.log('Deprecation warning: Component.checkValidity() will be deprecated in 6.x version of renderer. Use Component.validateComponent instead.');\n return this.checkComponentValidity(data, dirty, row, { silentCheck }, errors);\n }\n checkAsyncValidity(data, dirty, row, silentCheck, errors = []) {\n console.log('Deprecation warning: Component.checkAsyncValidity() will be deprecated in 6.x version of renderer. Use Component.validateComponent instead.');\n return this.checkComponentValidity(data, dirty, row, { async: true, silentCheck }, errors);\n }\n /**\n * Check the conditions, calculations, and validity of a single component and triggers an update if\n * something changed.\n *\n * @param data - The root data of the change event.\n * @param flags - The flags from this change event.\n *\n * @return boolean - If component is valid or not.\n */\n checkData(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n // Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners\n if (!flags.fromBlur) {\n this.checkRefreshOn(flags.changes, flags);\n }\n if (flags.noCheck) {\n return true;\n }\n this.checkComponentConditions(data, flags, row);\n if (this.id !== flags.triggeredComponentId) {\n this.calculateComponentValue(data, flags, row);\n }\n }\n checkModal(errors = [], dirty = false) {\n const messages = errors.filter(error => !error.fromServer);\n const isValid = errors.length === 0;\n if (!this.component.modalEdit || !this.componentModal) {\n return;\n }\n if (dirty && !isValid) {\n this.setErrorClasses([this.refs.openModal], dirty, !isValid, !!messages.length, this.refs.openModalWrapper);\n }\n else {\n this.clearErrorClasses(this.refs.openModalWrapper);\n }\n }\n get validationValue() {\n return this.dataValue;\n }\n isEmpty(value = this.dataValue) {\n const isEmptyArray = (lodash_1.default.isArray(value) && value.length === 1) ? lodash_1.default.isEqual(value[0], this.emptyValue) : false;\n return value == null || value.length === 0 || lodash_1.default.isEqual(value, this.emptyValue) || isEmptyArray;\n }\n isEqual(valueA, valueB = this.dataValue) {\n return (this.isEmpty(valueA) && this.isEmpty(valueB)) || lodash_1.default.isEqual(valueA, valueB);\n }\n /**\n * Check if a component is eligible for multiple validation\n *\n * @return {boolean}\n */\n validateMultiple() {\n return true;\n }\n clearErrorClasses(element = this.element) {\n this.removeClass(element, this.options.componentErrorClass);\n this.removeClass(element, 'alert alert-danger');\n this.removeClass(element, 'has-error');\n this.removeClass(element, 'has-message');\n }\n setInputWidgetErrorClasses(inputRefs, hasErrors) {\n if (!this.isInputComponent || !this.component.widget || !(inputRefs === null || inputRefs === void 0 ? void 0 : inputRefs.length)) {\n return;\n }\n inputRefs.forEach((input) => {\n if ((input === null || input === void 0 ? void 0 : input.widget) && input.widget.setErrorClasses) {\n input.widget.setErrorClasses(hasErrors);\n }\n });\n }\n addFocusBlurEvents(element) {\n this.addEventListener(element, 'focus', () => {\n if (this.root.focusedComponent !== this) {\n if (this.root.pendingBlur) {\n this.root.pendingBlur();\n }\n this.root.focusedComponent = this;\n this.emit('focus', this);\n }\n else if (this.root.focusedComponent === this && this.root.pendingBlur) {\n this.root.pendingBlur.cancel();\n this.root.pendingBlur = null;\n }\n });\n this.addEventListener(element, 'blur', () => {\n this.root.pendingBlur = FormioUtils.delay(() => {\n this.emit('blur', this);\n if (this.component.validateOn === 'blur') {\n this.root.triggerChange({ fromBlur: true }, {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: { fromBlur: true }\n });\n }\n this.root.focusedComponent = null;\n this.root.pendingBlur = null;\n });\n });\n }\n // eslint-disable-next-line max-statements\n setCustomValidity(messages, dirty, external) {\n const inputRefs = this.isInputComponent ? this.refs.input || [] : null;\n if (typeof messages === 'string' && messages) {\n messages = {\n level: 'error',\n message: messages,\n component: this.component,\n };\n }\n if (!Array.isArray(messages)) {\n if (messages) {\n messages = [messages];\n }\n else {\n messages = [];\n }\n }\n const errors = messages.filter(message => message.level === 'error');\n let invalidInputRefs = inputRefs;\n // Filter the invalid input refs in multiple components\n if (this.component.multiple) {\n const refsArray = Array.from(inputRefs);\n refsArray.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), false);\n });\n this.setInputWidgetErrorClasses(refsArray, false);\n invalidInputRefs = refsArray.filter((ref, index) => {\n var _a;\n return (_a = messages.some) === null || _a === void 0 ? void 0 : _a.call(messages, (msg) => {\n var _a;\n return ((_a = msg === null || msg === void 0 ? void 0 : msg.context) === null || _a === void 0 ? void 0 : _a.index) === index;\n });\n });\n }\n if (messages.length) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n this.emit('componentError', {\n instance: this,\n component: this.component,\n message: messages[0].message,\n messages,\n external: !!external,\n });\n this.addMessages(messages, dirty, invalidInputRefs);\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n }\n else if (!errors.length || (errors[0].external === !!external)) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n if (this.refs.modalMessageContainer) {\n this.empty(this.refs.modalMessageContainer);\n }\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n this.clearErrorClasses();\n }\n this._visibleErrors = messages;\n return messages;\n }\n /**\n * Determines if the value of this component is hidden from the user as if it is coming from the server, but is\n * protected.\n *\n * @return {boolean|*}\n */\n isValueHidden() {\n if (this.component.protected && this.root.editing) {\n return false;\n }\n if (!this.root || !this.root.hasOwnProperty('editing')) {\n return false;\n }\n if (!this.root || !this.root.editing) {\n return false;\n }\n return (this.component.protected || !this.component.persistent || (this.component.persistent === 'client-only'));\n }\n shouldSkipValidation(data, row, flags = {}) {\n const { validateWhenHidden = false } = this.component || {};\n const forceValidOnHidden = (!this.visible || !this.checkCondition(row, data)) && !validateWhenHidden;\n if (forceValidOnHidden) {\n // If this component is forced valid when it is hidden, then we also need to reset the errors for this component.\n this._errors = [];\n }\n const rules = [\n // Do not validate if the flags say not too.\n () => flags.noValidate,\n // Force valid if component is read-only\n () => this.options.readOnly,\n // Do not check validations if component is not an input component.\n () => !this.hasInput,\n // Check to see if we are editing and if so, check component persistence.\n () => this.isValueHidden(),\n // Force valid if component is hidden.\n () => forceValidOnHidden\n ];\n return rules.some(pred => pred());\n }\n // Maintain reverse compatibility.\n whenReady() {\n console.warn('The whenReady() method has been deprecated. Please use the dataReady property instead.');\n return this.dataReady;\n }\n get dataReady() {\n return Promise.resolve();\n }\n /**\n * Prints out the value of this component as a string value.\n */\n asString(value) {\n value = value || this.getValue();\n return (Array.isArray(value) ? value : [value]).map(lodash_1.default.toString).join(', ');\n }\n /**\n * Return if the component is disabled.\n * @return {boolean}\n */\n get disabled() {\n return this._disabled || this.parentDisabled;\n }\n /**\n * Disable this component.\n *\n * @param {boolean} disabled\n */\n set disabled(disabled) {\n this._disabled = disabled;\n }\n setDisabled(element, disabled) {\n if (!element) {\n return;\n }\n element.disabled = disabled;\n if (disabled) {\n element.setAttribute('disabled', 'disabled');\n }\n else {\n element.removeAttribute('disabled');\n }\n }\n setLoading(element, loading) {\n if (!element || (element.loading === loading)) {\n return;\n }\n element.loading = loading;\n if (!element.loader && loading) {\n element.loader = this.ce('i', {\n class: `${this.iconClass('refresh', true)} button-icon-right`\n });\n }\n if (element.loader) {\n if (loading) {\n this.appendTo(element.loader, element);\n }\n else {\n this.removeChildFrom(element.loader, element);\n }\n }\n }\n selectOptions(select, tag, options, defaultValue) {\n lodash_1.default.each(options, (option) => {\n const attrs = {\n value: option.value\n };\n if (defaultValue !== undefined && (option.value === defaultValue)) {\n attrs.selected = 'selected';\n }\n const optionElement = this.ce('option', attrs);\n optionElement.appendChild(this.text(option.label));\n select.appendChild(optionElement);\n });\n }\n setSelectValue(select, value) {\n const options = select.querySelectorAll('option');\n lodash_1.default.each(options, (option) => {\n if (option.value === value) {\n option.setAttribute('selected', 'selected');\n }\n else {\n option.removeAttribute('selected');\n }\n });\n if (select.onchange) {\n select.onchange();\n }\n if (select.onselect) {\n select.onselect();\n }\n }\n getRelativePath(path) {\n const keyPart = `.${this.key}`;\n const thisPath = this.isInputComponent ? this.path\n : this.path.slice(0).replace(keyPart, '');\n return path.replace(thisPath, '');\n }\n clear() {\n this.detach();\n this.empty(this.getElement());\n }\n append(element) {\n this.appendTo(element, this.element);\n }\n prepend(element) {\n this.prependTo(element, this.element);\n }\n removeChild(element) {\n this.removeChildFrom(element, this.element);\n }\n detachLogic() {\n this.logic.forEach(logic => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.off(event); // only applies to callbacks on this component\n }\n });\n }\n attachLogic() {\n // Do not attach logic during builder mode.\n if (this.builderMode) {\n return;\n }\n this.logic.forEach((logic) => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.on(event, (...args) => {\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n if (this.applyActions(newComponent, logic.actions, args)) {\n // If component definition changed, replace it.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n const visible = this.conditionallyVisible(null, null);\n const disabled = this.shouldDisabled;\n // Change states which won't be recalculated during redrawing\n if (this.visible !== visible) {\n this.visible = visible;\n }\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n this.redraw();\n }\n }\n }, true);\n }\n });\n }\n /**\n * Get the element information.\n */\n elementInfo() {\n const attributes = {\n name: this.options.name,\n type: this.component.inputType || 'text',\n class: 'form-control',\n lang: this.options.language\n };\n if (this.component.placeholder) {\n attributes.placeholder = this.t(this.component.placeholder, { _userInput: true });\n }\n if (this.component.tabindex) {\n attributes.tabindex = this.component.tabindex;\n }\n if (this.disabled) {\n attributes.disabled = 'disabled';\n }\n lodash_1.default.defaults(attributes, this.component.attributes);\n return {\n type: 'input',\n component: this.component,\n changeEvent: 'change',\n attr: attributes\n };\n }\n autofocus() {\n const hasAutofocus = this.component.autofocus && !this.builderMode && !this.options.preview;\n if (hasAutofocus) {\n this.on('render', () => this.focus(), true);\n }\n }\n scrollIntoView(element = this.element) {\n if (!element) {\n return;\n }\n const { left, top } = element.getBoundingClientRect();\n window.scrollTo(left + window.scrollX, top + window.scrollY);\n }\n focus(index) {\n var _a, _b;\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n if ((_a = this.refs.input) === null || _a === void 0 ? void 0 : _a.length) {\n const focusingInput = typeof index === 'number' && this.refs.input[index]\n ? this.refs.input[index]\n : this.refs.input[this.refs.input.length - 1];\n if (((_b = this.component.widget) === null || _b === void 0 ? void 0 : _b.type) === 'calendar') {\n const sibling = focusingInput.nextSibling;\n if (sibling) {\n sibling.focus();\n }\n }\n else {\n focusingInput.focus();\n }\n }\n if (this.refs.openModal) {\n this.refs.openModal.focus();\n }\n if (this.parent.refs.openModal) {\n this.parent.refs.openModal.focus();\n }\n }\n /**\n * Get `Formio` instance for working with files\n */\n get fileService() {\n if (this.options.fileService) {\n return this.options.fileService;\n }\n if (this.options.formio) {\n return this.options.formio;\n }\n if (this.root && this.root.formio) {\n return this.root.formio;\n }\n const formio = new Formio_1.Formio();\n // If a form is loaded, then make sure to set the correct formUrl.\n if (this.root && this.root._form && this.root._form._id) {\n formio.formUrl = `${formio.projectUrl}/form/${this.root._form._id}`;\n }\n return formio;\n }\n resetCaches() { }\n get previewMode() {\n return false;\n }\n}\nexports[\"default\"] = Component;\nComponent.externalLibraries = {};\nComponent.requireLibrary = function (name, property, src, polling) {\n if (!Component.externalLibraries.hasOwnProperty(name)) {\n Component.externalLibraries[name] = {};\n Component.externalLibraries[name].ready = new Promise((resolve, reject) => {\n Component.externalLibraries[name].resolve = resolve;\n Component.externalLibraries[name].reject = reject;\n });\n const callbackName = `${name}Callback`;\n if (!polling && !window[callbackName]) {\n window[callbackName] = function () {\n this.resolve();\n }.bind(Component.externalLibraries[name]);\n }\n // See if the plugin already exists.\n const plugin = lodash_1.default.get(window, property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n src = Array.isArray(src) ? src : [src];\n src.forEach((lib) => {\n let attrs = {};\n let elementType = '';\n if (typeof lib === 'string') {\n lib = {\n type: 'script',\n src: lib\n };\n }\n switch (lib.type) {\n case 'script':\n elementType = 'script';\n attrs = {\n src: lib.src,\n type: 'text/javascript',\n defer: true,\n async: true\n };\n break;\n case 'styles':\n elementType = 'link';\n attrs = {\n href: lib.src,\n rel: 'stylesheet'\n };\n break;\n }\n // Add the script to the top page.\n const script = document.createElement(elementType);\n for (const attr in attrs) {\n script.setAttribute(attr, attrs[attr]);\n }\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n // if no callback is provided, then check periodically for the script.\n if (polling) {\n setTimeout(function checkLibrary() {\n const plugin = lodash_1.default.get(window, property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n // check again after 200 ms.\n setTimeout(checkLibrary, 200);\n }\n }, 200);\n }\n }\n }\n return Component.externalLibraries[name].ready;\n};\nComponent.libraryReady = function (name) {\n if (Component.externalLibraries.hasOwnProperty(name) &&\n Component.externalLibraries[name].ready) {\n return Component.externalLibraries[name].ready;\n }\n return Promise.reject(`${name} library was not required.`);\n};\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/component/Component.js?");
|
5520
|
+
eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* globals Quill, ClassicEditor, CKEDITOR */\nconst vanilla_text_mask_1 = __webpack_require__(/*! @formio/vanilla-text-mask */ \"./node_modules/@formio/vanilla-text-mask/dist/vanillaTextMask.js\");\nconst tippy_js_1 = __importDefault(__webpack_require__(/*! tippy.js */ \"./node_modules/tippy.js/dist/tippy.esm.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ismobilejs_1 = __importDefault(__webpack_require__(/*! ismobilejs */ \"./node_modules/ismobilejs/esm/index.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst Formio_1 = __webpack_require__(/*! ../../../Formio */ \"./lib/cjs/Formio.js\");\nconst FormioUtils = __importStar(__webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Element_1 = __importDefault(__webpack_require__(/*! ../../../Element */ \"./lib/cjs/Element.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst widgets_1 = __importDefault(__webpack_require__(/*! ../../../widgets */ \"./lib/cjs/widgets/index.js\"));\nconst addons_1 = __importDefault(__webpack_require__(/*! ../../../addons */ \"./lib/cjs/addons/index.js\"));\nconst uploadAdapter_1 = __webpack_require__(/*! ../../../providers/storage/uploadAdapter */ \"./lib/cjs/providers/storage/uploadAdapter.js\");\nconst en_1 = __importDefault(__webpack_require__(/*! ../../../translations/en */ \"./lib/cjs/translations/en.js\"));\nconst Templates_1 = __importDefault(__webpack_require__(/*! ../../../templates/Templates */ \"./lib/cjs/templates/Templates.js\"));\nconst isIEBrowser = FormioUtils.getBrowserInfo().ie;\n/**\n * This is the Component class\n which all elements within the FormioForm derive from.\n */\nclass Component extends Element_1.default {\n static schema(...sources) {\n return lodash_1.default.merge({\n /**\n * Determines if this component provides an input.\n */\n input: true,\n /**\n * The data key for this component (how the data is stored in the database).\n */\n key: '',\n /**\n * The input placeholder for this component.\n */\n placeholder: '',\n /**\n * The input prefix\n */\n prefix: '',\n /**\n * The custom CSS class to provide to this component.\n */\n customClass: '',\n /**\n * The input suffix.\n */\n suffix: '',\n /**\n * If this component should allow an array of values to be captured.\n */\n multiple: false,\n /**\n * The default value of this component.\n */\n defaultValue: null,\n /**\n * If the data of this component should be protected (no GET api requests can see the data)\n */\n protected: false,\n /**\n * Validate if the value of this component should be unique within the form.\n */\n unique: false,\n /**\n * If the value of this component should be persisted within the backend api database.\n */\n persistent: true,\n /**\n * Determines if the component should be within the form, but not visible.\n */\n hidden: false,\n /**\n * If the component should be cleared when hidden.\n */\n clearOnHide: true,\n /**\n * This will refresh this component options when this field changes.\n */\n refreshOn: '',\n /**\n * This will redraw the component when this field changes.\n */\n redrawOn: '',\n /**\n * If this component should be included as a column within a submission table.\n */\n tableView: false,\n /**\n * If this component should be rendering in modal.\n */\n modalEdit: false,\n /**\n * The input label provided to this component.\n */\n label: '',\n dataGridLabel: false,\n labelPosition: 'top',\n description: '',\n errorLabel: '',\n tooltip: '',\n hideLabel: false,\n tabindex: '',\n disabled: false,\n autofocus: false,\n dbIndex: false,\n customDefaultValue: '',\n calculateValue: '',\n calculateServer: false,\n widget: null,\n /**\n * Attributes that will be assigned to the input elements of this component.\n */\n attributes: {},\n /**\n * This will perform the validation on either \"change\" or \"blur\" of the input element.\n */\n validateOn: 'change',\n /**\n * The validation criteria for this component.\n */\n validate: {\n /**\n * If this component is required.\n */\n required: false,\n /**\n * Custom JavaScript validation.\n */\n custom: '',\n /**\n * If the custom validation should remain private (only the backend will see it and execute it).\n */\n customPrivate: false,\n /**\n * If this component should implement a strict date validation if the Calendar widget is implemented.\n */\n strictDateValidation: false,\n multiple: false,\n unique: false\n },\n /**\n * The simple conditional settings for a component.\n */\n conditional: {\n show: null,\n when: null,\n eq: ''\n },\n overlay: {\n style: '',\n left: '',\n top: '',\n width: '',\n height: '',\n },\n allowCalculateOverride: false,\n encrypted: false,\n showCharCount: false,\n showWordCount: false,\n properties: {},\n allowMultipleMasks: false,\n addons: [],\n }, ...sources);\n }\n /**\n * Return the simple condition settings as part of the component.\n *\n * @return {Object}\n *\n */\n static get conditionOperatorsSettings() {\n return {\n operators: ['isEqual', 'isNotEqual', 'isEmpty', 'isNotEmpty'],\n valueComponent() {\n return {\n type: 'textfield',\n widget: {\n type: 'input'\n }\n };\n }\n };\n }\n /**\n * Return the array of possible types of component value absed on its schema.\n *\n * @param schema\n * @return {Array}\n *\n */\n static savedValueTypes(schema) {\n schema = schema || {};\n return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.any];\n }\n /**\n * Provides a table view for this component. Override if you wish to do something different than using getView\n * method of your instance.\n *\n * @param value\n * @param options\n */\n /* eslint-disable no-unused-vars */\n static tableView(value, options) { }\n /* eslint-enable no-unused-vars */\n /**\n * Initialize a new Component.\n *\n * @param {Object} component - The component JSON you wish to initialize.\n * @param {Object} options - The options for this component.\n * @param {Object} data - The global data submission object this component will belong.\n */\n /* eslint-disable max-statements */\n constructor(component, options, data) {\n super(Object.assign({\n renderMode: 'form',\n attachMode: 'full',\n noDefaults: false\n }, options || {}));\n // Restore the component id.\n if (component && component.id) {\n this.id = component.id;\n }\n /**\n * Determines if this component has a condition assigned to it.\n * @type {null}\n * @private\n */\n this._hasCondition = null;\n /**\n * References to dom elements\n */\n this.refs = {};\n // Allow global override for any component JSON.\n if (component &&\n this.options.components &&\n this.options.components[component.type]) {\n lodash_1.default.merge(component, this.options.components[component.type]);\n }\n /**\n * The data path to this specific component instance.\n *\n * @type {string}\n */\n this.path = (component === null || component === void 0 ? void 0 : component.key) || '';\n /**\n * An array of all the children components errors.\n */\n this.childErrors = [];\n /**\n * Last validation errors that have occured.\n */\n this._errors = [];\n this._visibleErrors = [];\n /**\n * The Form.io component JSON schema.\n * @type {*}\n */\n this.component = this.mergeSchema(component || {});\n // Add the id to the component.\n this.component.id = this.id;\n this.afterComponentAssign();\n // Save off the original component to be used in logic.\n this.originalComponent = (0, utils_1.fastCloneDeep)(this.component);\n /**\n * If the component has been attached\n */\n this.attached = false;\n /**\n * If the component has been rendered\n */\n this.rendered = false;\n /**\n * The data object in which this component resides.\n * @type {*}\n */\n this._data = data || {};\n /**\n * Tool tip text after processing\n * @type {string}\n */\n this.tooltip = '';\n /**\n * The row path of this component.\n * @type {number}\n */\n this.row = this.options.row;\n /**\n * Points to a flat map of child components (if applicable).\n *\n * @type {Object}\n */\n this.childComponentsMap = {};\n /**\n * Determines if this component is disabled, or not.\n *\n * @type {boolean}\n */\n this._disabled = (0, utils_1.boolValue)(this.component.disabled) ? this.component.disabled : false;\n /**\n * Points to the root component, usually the FormComponent.\n *\n * @type {Component}\n */\n this.root = this.options.root || this;\n this.localRoot = this.options.localRoot || this;\n /**\n * If this input has been input and provided value.\n *\n * @type {boolean}\n */\n this.pristine = true;\n /**\n * Points to the parent component.\n *\n * @type {Component}\n */\n this.parent = this.options.parent;\n this.options.name = this.options.name || 'data';\n this._path = '';\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n /**\n * Determines if this component is visible, or not.\n */\n this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;\n this._visible = this._parentVisible && this.conditionallyVisible(null, data);\n this._parentDisabled = false;\n /**\n * The reference attribute name for this component\n */\n this._referenceAttributeName = 'ref';\n /**\n * Used to trigger a new change in this component.\n * @type {function} - Call to trigger a change in this component.\n */\n let changes = [];\n let lastChanged = null;\n let triggerArgs = [];\n const _triggerChange = lodash_1.default.debounce((...args) => {\n if (this.root) {\n this.root.changing = false;\n }\n triggerArgs = [];\n if (!args[1] && lastChanged) {\n // Set the changed component if one isn't provided.\n args[1] = lastChanged;\n }\n if (lodash_1.default.isEmpty(args[0]) && lastChanged) {\n // Set the flags if it is empty and lastChanged exists.\n args[0] = lastChanged.flags;\n }\n lastChanged = null;\n args[3] = changes;\n const retVal = this.onChange(...args);\n changes = [];\n return retVal;\n }, 100);\n this.triggerChange = (...args) => {\n if (args[1]) {\n // Make sure that during the debounce that we always track lastChanged component, even if they\n // don't provide one later.\n lastChanged = args[1];\n changes.push(lastChanged);\n }\n if (this.root) {\n this.root.changing = true;\n }\n if (args.length) {\n triggerArgs = args;\n }\n return _triggerChange(...triggerArgs);\n };\n /**\n * Used to trigger a redraw event within this component.\n *\n * @type {Function}\n */\n this.triggerRedraw = lodash_1.default.debounce(this.redraw.bind(this), 100);\n /**\n * list of attached tooltips\n * @type {Array}\n */\n this.tooltips = [];\n /**\n * List of attached addons\n * @type {Array}\n */\n this.addons = [];\n // To force this component to be invalid.\n this.invalid = false;\n if (this.component) {\n this.type = this.component.type;\n if (this.allowData && this.key) {\n this.options.name += `[${this.key}]`;\n // If component is visible or not set to clear on hide, set the default value.\n if (this.visible || !this.component.clearOnHide) {\n if (!this.hasValue()) {\n if (this.shouldAddDefaultValue) {\n this.dataValue = this.defaultValue;\n }\n }\n else {\n // Ensure the dataValue is set.\n /* eslint-disable no-self-assign */\n this.dataValue = this.dataValue;\n /* eslint-enable no-self-assign */\n }\n }\n }\n /**\n * The element information for creating the input element.\n * @type {*}\n */\n this.info = this.elementInfo();\n }\n // Allow anyone to hook into the component creation.\n this.hook('component');\n if (!this.options.skipInit) {\n this.init();\n }\n }\n /* eslint-enable max-statements */\n get componentsMap() {\n var _a;\n if ((_a = this.localRoot) === null || _a === void 0 ? void 0 : _a.childComponentsMap) {\n return this.localRoot.childComponentsMap;\n }\n const localMap = {};\n localMap[this.path] = this;\n return localMap;\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n }\n mergeSchema(component = {}) {\n return lodash_1.default.defaultsDeep(component, this.defaultSchema);\n }\n // Allow componets to notify when ready.\n get ready() {\n return Promise.resolve(this);\n }\n get isPDFReadOnlyMode() {\n return this.parent &&\n this.parent.form &&\n (this.parent.form.display === 'pdf') &&\n this.options.readOnly;\n }\n get labelInfo() {\n const label = {};\n label.hidden = this.labelIsHidden();\n label.className = '';\n label.labelPosition = this.component.labelPosition;\n label.tooltipClass = `${this.iconClass('question-sign')} text-muted`;\n const isPDFReadOnlyMode = this.isPDFReadOnlyMode;\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required) && !isPDFReadOnlyMode) {\n label.className += ' field-required';\n }\n if (label.hidden) {\n label.className += ' control-label--hidden';\n }\n if (this.info.attr.id) {\n label.for = this.info.attr.id;\n }\n return label;\n }\n init() {\n var _a;\n this.disabled = this.shouldDisabled;\n this._visible = this.conditionallyVisible(null, null);\n if ((_a = this.component.addons) === null || _a === void 0 ? void 0 : _a.length) {\n this.component.addons.forEach((addon) => this.createAddon(addon));\n }\n }\n afterComponentAssign() {\n //implement in extended classes\n }\n createAddon(addonConfiguration) {\n var _a;\n const name = addonConfiguration.name;\n if (!name) {\n return;\n }\n const settings = ((_a = addonConfiguration.settings) === null || _a === void 0 ? void 0 : _a.data) || {};\n const Addon = addons_1.default[name.value];\n let addon = null;\n if (Addon) {\n const supportedComponents = Addon.info.supportedComponents;\n const supportsThisComponentType = !(supportedComponents === null || supportedComponents === void 0 ? void 0 : supportedComponents.length) ||\n supportedComponents.indexOf(this.component.type) !== -1;\n if (supportsThisComponentType) {\n addon = new Addon(settings, this);\n this.addons.push(addon);\n }\n else {\n console.warn(`Addon ${name.label} does not support component of type ${this.component.type}.`);\n }\n }\n return addon;\n }\n teardown() {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n delete this._currentForm;\n delete this.parent;\n delete this.root;\n delete this.triggerChange;\n delete this.triggerRedraw;\n if (this.options) {\n delete this.options.root;\n delete this.options.parent;\n delete this.options.i18next;\n }\n super.teardown();\n }\n destroy(all = false) {\n super.destroy(all);\n this.detach();\n this.addons.forEach((addon) => addon.destroy());\n if (all) {\n this.teardown();\n }\n }\n get shouldDisabled() {\n return this.options.readOnly || this.component.disabled || (this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]);\n }\n get isInputComponent() {\n return !this.component.hasOwnProperty('input') || this.component.input;\n }\n get allowData() {\n return this.hasInput;\n }\n get hasInput() {\n return this.isInputComponent || (this.refs.input && this.refs.input.length);\n }\n get defaultSchema() {\n return Component.schema();\n }\n get key() {\n return lodash_1.default.get(this.component, 'key', '');\n }\n set parentVisible(value) {\n this._parentVisible = value;\n }\n get parentVisible() {\n return this._parentVisible;\n }\n set parentDisabled(value) {\n this._parentDisabled = value;\n }\n get parentDisabled() {\n return this._parentDisabled;\n }\n shouldForceVisibility(component, visibility) {\n if (!this.options[visibility]) {\n return false;\n }\n if (!component) {\n component = this.component;\n }\n if (lodash_1.default.isArray(this.options[visibility])) {\n return this.options[visibility].includes(component.key);\n }\n return this.options[visibility][component.key];\n }\n shouldForceHide(component) {\n return this.shouldForceVisibility(component, 'hide');\n }\n shouldForceShow(component) {\n return this.shouldForceVisibility(component, 'show');\n }\n /**\n *\n * @param value {boolean}\n */\n set visible(value) {\n if (this._visible !== value) {\n // Skip if this component is set to visible and is supposed to be hidden.\n if (value && this.shouldForceHide()) {\n return;\n }\n // Skip if this component is set to hidden and is supposed to be shown.\n if (!value && this.shouldForceShow()) {\n return;\n }\n this._visible = value;\n this.clearOnHide();\n this.redraw();\n }\n }\n /**\n *\n * @returns {boolean}\n */\n get visible() {\n // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown.\n if (this.builderMode || this.previewMode || this.options.showHiddenFields) {\n return true;\n }\n if (this.shouldForceHide()) {\n return false;\n }\n if (this.shouldForceShow()) {\n return true;\n }\n return this._visible && this._parentVisible;\n }\n get currentForm() {\n return this._currentForm;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n }\n get fullMode() {\n return this.options.attachMode === 'full';\n }\n get builderMode() {\n return this.options.attachMode === 'builder';\n }\n get calculatedPath() {\n console.error('component.calculatedPath was deprecated, use component.path instead.');\n return this.path;\n }\n get labelPosition() {\n return this.component.labelPosition;\n }\n get labelWidth() {\n const width = this.component.labelWidth;\n return width >= 0 ? width : 30;\n }\n get labelMargin() {\n const margin = this.component.labelMargin;\n return margin >= 0 ? margin : 3;\n }\n get isAdvancedLabel() {\n return [\n 'left-left',\n 'left-right',\n 'right-left',\n 'right-right'\n ].includes(this.labelPosition);\n }\n get labelPositions() {\n return this.labelPosition.split('-');\n }\n get skipInEmail() {\n return false;\n }\n rightDirection(direction) {\n if (this.options.condensedMode) {\n return false;\n }\n return direction === 'right';\n }\n getLabelInfo(isCondensed = false) {\n const isRightPosition = this.rightDirection(this.labelPositions[0]);\n const isLeftPosition = this.labelPositions[0] === 'left' || isCondensed;\n const isRightAlign = this.rightDirection(this.labelPositions[1]);\n let contentMargin = '';\n if (this.component.hideLabel) {\n const margin = isCondensed ? 0 : this.labelWidth + this.labelMargin;\n contentMargin = isRightPosition ? `margin-right: ${margin}%` : '';\n contentMargin = isLeftPosition ? `margin-left: ${margin}%` : '';\n }\n const labelStyles = `\n flex: ${this.labelWidth};\n ${isRightPosition ? 'margin-left' : 'margin-right'}: ${this.labelMargin}%;\n `;\n const contentStyles = `\n flex: ${100 - this.labelWidth - this.labelMargin};\n ${contentMargin};\n ${this.component.hideLabel ? `max-width: ${100 - this.labelWidth - this.labelMargin}` : ''};\n `;\n return {\n isRightPosition,\n isRightAlign,\n labelStyles,\n contentStyles\n };\n }\n /**\n * Returns only the schema that is different from the default.\n *\n * @param schema\n * @param defaultSchema\n */\n getModifiedSchema(schema, defaultSchema, recursion) {\n const modified = {};\n if (!defaultSchema) {\n return schema;\n }\n lodash_1.default.each(schema, (val, key) => {\n if (!lodash_1.default.isArray(val) && lodash_1.default.isObject(val) && defaultSchema.hasOwnProperty(key)) {\n const subModified = this.getModifiedSchema(val, defaultSchema[key], true);\n if (!lodash_1.default.isEmpty(subModified)) {\n modified[key] = subModified;\n }\n }\n else if (lodash_1.default.isArray(val)) {\n if (val.length !== 0 && !lodash_1.default.isEqual(val, defaultSchema[key])) {\n modified[key] = val;\n }\n }\n else if ((!recursion && (key === 'type')) ||\n (!recursion && (key === 'key')) ||\n (!recursion && (key === 'label')) ||\n (!recursion && (key === 'input')) ||\n (!recursion && (key === 'tableView')) ||\n (val !== '' && !defaultSchema.hasOwnProperty(key)) ||\n (val !== '' && val !== defaultSchema[key]) ||\n (defaultSchema[key] && val !== defaultSchema[key])) {\n modified[key] = val;\n }\n });\n return modified;\n }\n /**\n * Returns the JSON schema for this component.\n */\n get schema() {\n return (0, utils_1.fastCloneDeep)(this.getModifiedSchema(lodash_1.default.omit(this.component, 'id'), this.defaultSchema));\n }\n /**\n * Returns true if component is inside DataGrid\n */\n get isInDataGrid() {\n return this.inDataGrid;\n }\n /**\n * Translate a text using the i18n system.\n *\n * @param {string} text - The i18n identifier.\n * @param {Object} params - The i18n parameters to use for translation.\n */\n t(text, params = {}, ...args) {\n if (!text) {\n return '';\n }\n // Use _userInput: true to ignore translations from defaults\n if (text in en_1.default && params._userInput) {\n return text;\n }\n params.data = params.data || this.rootValue;\n params.row = params.row || this.data;\n params.component = params.component || this.component;\n return super.t(text, params, ...args);\n }\n labelIsHidden() {\n return !this.component.label ||\n ((!this.isInDataGrid && this.component.hideLabel) ||\n (this.isInDataGrid && !this.component.dataGridLabel) ||\n this.options.floatingLabels ||\n this.options.inputsOnly) && !this.builderMode;\n }\n transform(type, value) {\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n return frameworkTemplates.hasOwnProperty('transform')\n ? frameworkTemplates.transform(type, value, this)\n : (type, value) => value;\n }\n getTemplate(names, modes) {\n modes = Array.isArray(modes) ? modes : [modes];\n names = Array.isArray(names) ? names : [names];\n if (!modes.includes('form')) {\n modes.push('form');\n }\n let result = null;\n if (this.options.templates) {\n result = this.checkTemplate(this.options.templates, names, modes);\n if (result) {\n return result;\n }\n }\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n result = this.checkTemplate(frameworkTemplates, names, modes);\n if (result) {\n return result;\n }\n // Default back to bootstrap if not defined.\n const name = names[names.length - 1];\n const templatesByName = Templates_1.default.defaultTemplates[name];\n if (!templatesByName) {\n return { template: `Unknown template: ${name}` };\n }\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode };\n }\n return { template: templatesByName.form };\n }\n checkTemplate(templates, names, modes) {\n for (const name of names) {\n const templatesByName = templates[name];\n if (templatesByName) {\n const { referenceAttributeName } = templatesByName;\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode, referenceAttributeName };\n }\n }\n }\n return null;\n }\n checkTemplateMode(templatesByName, modes) {\n for (const mode of modes) {\n const templateByMode = templatesByName[mode];\n if (templateByMode) {\n return templateByMode;\n }\n }\n return null;\n }\n getFormattedAttribute(attr) {\n return attr ? this.t(attr, { _userInput: true }).replace(/\"/g, '"') : '';\n }\n getFormattedTooltip(tooltipValue) {\n const tooltip = this.interpolate(tooltipValue || '').replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return this.getFormattedAttribute(tooltip);\n }\n isHtmlRenderMode() {\n return this.options.renderMode === 'html';\n }\n renderTemplate(name, data = {}, modeOption = '') {\n // Need to make this fall back to form if renderMode is not found similar to how we search templates.\n const mode = modeOption || this.options.renderMode || 'form';\n data.component = this.component;\n data.self = this;\n data.options = this.options;\n data.readOnly = this.options.readOnly;\n data.iconClass = this.iconClass.bind(this);\n data.size = this.size.bind(this);\n data.t = this.t.bind(this);\n data.transform = this.transform.bind(this);\n data.id = data.id || this.id;\n data.key = data.key || this.key;\n data.value = data.value || this.dataValue;\n data.disabled = this.disabled;\n data.builder = this.builderMode;\n data.render = (...args) => {\n console.warn(`Form.io 'render' template function is deprecated.\n If you need to render template (template A) inside of another template (template B),\n pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B`);\n return this.renderTemplate(...args);\n };\n data.label = data.labelInfo || this.labelInfo;\n data.tooltip = this.getFormattedTooltip(this.component.tooltip);\n // Allow more specific template names\n const names = [\n `${name}-${this.component.type}-${this.key}`,\n `${name}-${this.component.type}`,\n `${name}-${this.key}`,\n `${name}`,\n ];\n // Allow template alters.\n const { referenceAttributeName, template } = this.getTemplate(names, mode);\n if (referenceAttributeName) {\n this._referenceAttributeName = referenceAttributeName;\n }\n return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);\n }\n /**\n * Sanitize an html string.\n *\n * @param string\n * @returns {*}\n */\n sanitize(dirty, forceSanitize = false, options = {}) {\n var _a;\n if (!this.shouldSanitizeValue && !forceSanitize) {\n return dirty;\n }\n return FormioUtils.sanitize(dirty, {\n sanitizeConfig: lodash_1.default.merge(((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitizeConfig) || {}, options || {}),\n });\n }\n /**\n * Render a template string into html.\n *\n * @param template\n * @param data\n * @param actions\n *\n * @return {HTMLElement|String} - The created element or an empty string if template is not specified.\n */\n renderString(template, data) {\n if (!template) {\n return '';\n }\n // Interpolate the template and populate\n return this.interpolate(template, data);\n }\n performInputMapping(input) {\n return input;\n }\n get widget() {\n var _a;\n const settings = this.component.widget;\n if (settings && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.shadowRoot)) {\n settings.shadowRoot = this.root.shadowRoot;\n }\n const widget = settings && widgets_1.default[settings.type] ? new widgets_1.default[settings.type](settings, this.component, this) : null;\n return widget;\n }\n getBrowserLanguage() {\n const nav = window.navigator;\n const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];\n let language;\n // support for HTML 5.1 \"navigator.languages\"\n if (Array.isArray(nav.languages)) {\n for (let i = 0; i < nav.languages.length; i++) {\n language = nav.languages[i];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n }\n // support for other well known properties in browsers\n for (let i = 0; i < browserLanguagePropertyKeys.length; i++) {\n language = nav[browserLanguagePropertyKeys[i]];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n return null;\n }\n /**\n * Called before a next and previous page is triggered allowing the components\n * to perform special functions.\n *\n * @return {*}\n */\n beforePage() {\n return Promise.resolve(true);\n }\n beforeNext() {\n return this.beforePage(true);\n }\n /**\n * Called before a submission is triggered allowing the components\n * to perform special async functions.\n *\n * @return {*}\n */\n beforeSubmit() {\n return Promise.resolve(true);\n }\n /**\n * Return the submission timezone.\n *\n * @return {*}\n */\n get submissionTimezone() {\n this.options.submissionTimezone = this.options.submissionTimezone || lodash_1.default.get(this.root, 'options.submissionTimezone');\n return this.options.submissionTimezone;\n }\n get timezone() {\n return this.getTimezone(this.component);\n }\n getTimezone(settings) {\n if (settings.timezone) {\n return settings.timezone;\n }\n if (settings.displayInTimezone === 'utc') {\n return 'UTC';\n }\n const submissionTimezone = this.submissionTimezone;\n if (submissionTimezone &&\n ((settings.displayInTimezone === 'submission') ||\n ((this.options.pdf || this.options.server) && (settings.displayInTimezone === 'viewer')))) {\n return submissionTimezone;\n }\n // Return current timezone if none are provided.\n return (0, utils_1.currentTimezone)();\n }\n /**\n *\n * @param {HTMLElement} element - The containing DOM element to query for the ref value.\n * @param {object} refs - The references to load.\n * @param {string} [referenceAttributeName] - The attribute name to use for the reference.\n */\n loadRefs(element, refs, referenceAttributeName) {\n for (const ref in refs) {\n const refType = refs[ref];\n const isString = typeof refType === 'string';\n const selector = isString && refType.includes('scope')\n ? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`\n : `[${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`;\n if (isString && refType.startsWith('single')) {\n this.refs[ref] = element.querySelector(selector);\n }\n else {\n this.refs[ref] = element.querySelectorAll(selector);\n }\n }\n }\n setOpenModalElement(template) {\n this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());\n }\n getModalPreviewTemplate() {\n var _a;\n const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;\n let modalLabel;\n if (this.hasInput && ((_a = this.component.validate) === null || _a === void 0 ? void 0 : _a.required) && !this.isPDFReadOnlyMode) {\n modalLabel = { className: 'field-required' };\n }\n return this.renderTemplate('modalPreview', {\n previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'),\n messages: '',\n labelInfo: modalLabel,\n });\n }\n build(element) {\n element = element || this.element;\n this.empty(element);\n this.setContent(element, this.render());\n return this.attach(element);\n }\n get hasModalSaveButton() {\n return true;\n }\n render(children = `Unknown component: ${this.component.type}`, topLevel = false) {\n const isVisible = this.visible;\n this.rendered = true;\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n return ComponentModal_1.default.render(this, {\n visible: isVisible,\n showSaveButton: this.hasModalSaveButton,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n else {\n return this.renderTemplate('component', {\n visible: isVisible,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n }\n attachTooltips(toolTipsRefs) {\n toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach((tooltip, index) => {\n if (tooltip) {\n const tooltipAttribute = tooltip.getAttribute('data-tooltip');\n const tooltipDataTitle = tooltip.getAttribute('data-title');\n const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)\n .replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n this.tooltips[index] = (0, tippy_js_1.default)(tooltip, {\n allowHTML: true,\n trigger: 'mouseenter click focus',\n placement: 'right',\n zIndex: 10000,\n interactive: true,\n content: this.t(this.sanitize(tooltipText), { _userInput: true }),\n });\n }\n });\n }\n createComponentModal(element, modalShouldBeOpened, currentValue) {\n return new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n }\n attach(element) {\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n const openModalTemplate = this.componentModal && modalShouldBeOpened\n ? this.componentModal.openModalTemplate\n : null;\n this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue);\n this.setOpenModalElement(openModalTemplate);\n }\n this.attached = true;\n this.setElement(element);\n element.component = this;\n // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id.\n if (this.element.id) {\n this.id = this.element.id;\n this.component.id = this.id;\n }\n this.loadRefs(element, {\n messageContainer: 'single',\n tooltip: 'multiple'\n });\n this.attachTooltips(this.refs.tooltip);\n // Attach logic.\n this.attachLogic();\n this.autofocus();\n // Allow global attach.\n this.hook('attachComponent', element, this);\n // Allow attach per component type.\n const type = this.component.type;\n if (type) {\n this.hook(`attach${type.charAt(0).toUpperCase() + type.substring(1, type.length)}`, element, this);\n }\n this.restoreFocus();\n this.addons.forEach((addon) => addon.attach(element));\n return Promise.resolve();\n }\n restoreFocus() {\n var _a, _b, _c;\n const isFocused = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.path) === this.path;\n if (isFocused) {\n this.loadRefs(this.element, { input: 'multiple' });\n this.focus((_c = this.root.currentSelection) === null || _c === void 0 ? void 0 : _c.index);\n this.restoreCaretPosition();\n }\n }\n addShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || !this.root || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.addShortcut(element, shortcut);\n }\n removeShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.removeShortcut(element, shortcut);\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n // First iterate through each ref and delete the component so there are no dangling component references.\n lodash_1.default.each(this.refs, (ref) => {\n if (typeof ref === NodeList) {\n ref.forEach((elem) => {\n delete elem.component;\n });\n }\n else if (ref) {\n delete ref.component;\n }\n });\n this.refs = {};\n this.removeEventListeners();\n this.detachLogic();\n if (this.tooltip) {\n this.tooltip.destroy();\n }\n }\n checkRefresh(refreshData, changed, flags) {\n const changePath = lodash_1.default.get(changed, 'instance.path', false);\n // Don't let components change themselves.\n if (changePath && this.path === changePath) {\n return;\n }\n if (refreshData === 'data') {\n this.refresh(this.data, changed, flags);\n }\n else if ((changePath && (0, utils_1.getComponentPath)(changed.instance) === refreshData) && changed && changed.instance &&\n // Make sure the changed component is not in a different \"context\". Solves issues where refreshOn being set\n // in fields inside EditGrids could alter their state from other rows (which is bad).\n this.inContext(changed.instance)) {\n this.refresh(changed.value, changed, flags);\n }\n }\n checkRefreshOn(changes, flags = {}) {\n changes = changes || [];\n if (flags.noRefresh) {\n return;\n }\n if (!changes.length && flags.changed) {\n changes = [flags.changed];\n }\n const refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn;\n // If they wish to refresh on a value, then add that here.\n if (refreshOn) {\n if (Array.isArray(refreshOn)) {\n refreshOn.forEach(refreshData => changes.forEach(changed => this.checkRefresh(refreshData, changed, flags)));\n }\n else {\n changes.forEach(changed => this.checkRefresh(refreshOn, changed, flags));\n }\n }\n }\n /**\n * Refreshes the component with a new value.\n *\n * @param value\n */\n refresh(value) {\n if (this.hasOwnProperty('refreshOnValue')) {\n this.refreshOnChanged = !lodash_1.default.isEqual(value, this.refreshOnValue);\n }\n else {\n this.refreshOnChanged = true;\n }\n this.refreshOnValue = (0, utils_1.fastCloneDeep)(value);\n if (this.refreshOnChanged) {\n if (this.component.clearOnRefresh) {\n this.setValue(null);\n }\n this.triggerRedraw();\n }\n }\n /**\n * Checks to see if a separate component is in the \"context\" of this component. This is determined by first checking\n * if they share the same \"data\" object. It will then walk up the parent tree and compare its parents data objects\n * with the components data and returns true if they are in the same context.\n *\n * Different rows of the same EditGrid, for example, are in different contexts.\n *\n * @param component\n */\n inContext(component) {\n if (component.data === this.data) {\n return true;\n }\n let parent = this.parent;\n while (parent) {\n if (parent.data === component.data) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n get viewOnly() {\n return this.options.readOnly && this.options.viewAsHtml;\n }\n setElement(element) {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n this.element = element;\n }\n createViewOnlyElement() {\n this.setElement(this.ce('dl', {\n id: this.id\n }));\n if (this.element) {\n // Ensure you can get the component info from the element.\n this.element.component = this;\n }\n return this.element;\n }\n get defaultViewOnlyValue() {\n return '-';\n }\n /**\n * Uses the widget to determine the output string.\n *\n * @param value\n * @return {*}\n */\n getWidgetValueAsString(value, options) {\n const noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget;\n if (!value || noInputWidget) {\n if (!this.widget || !value) {\n return value;\n }\n else {\n return this.widget.getValueAsString(value);\n }\n }\n if (Array.isArray(value)) {\n const values = [];\n value.forEach((val, index) => {\n const widget = this.refs.input[index] && this.refs.input[index].widget;\n if (widget) {\n values.push(widget.getValueAsString(val, options));\n }\n });\n return values;\n }\n const widget = this.refs.input[0].widget;\n return widget.getValueAsString(value, options);\n }\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n value = this.getWidgetValueAsString(value, options);\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n if (lodash_1.default.isPlainObject(value)) {\n return JSON.stringify(value);\n }\n if (value === null || value === undefined) {\n return '';\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue);\n }\n getView(value, options) {\n if (this.component.protected) {\n return '--- PROTECTED ---';\n }\n return this.getValueAsString(value, options);\n }\n updateItems(...args) {\n this.restoreValue();\n this.onChange(...args);\n }\n /**\n * @param {*} data\n * @param {boolean} [forceUseValue=false] - if true, return 'value' property of the data\n * @return {*}\n */\n itemValue(data, forceUseValue = false) {\n if (lodash_1.default.isObject(data) && !lodash_1.default.isArray(data)) {\n if (this.valueProperty) {\n return lodash_1.default.get(data, this.valueProperty);\n }\n if (forceUseValue) {\n return data.value;\n }\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item) ? this.itemValueForHTMLMode(item) : this.itemValue(item));\n return values.join(', ');\n }\n return this.itemValue(value);\n }\n createModal(element, attr, confirm) {\n const dialog = this.ce('div', attr || {});\n this.setContent(dialog, this.renderTemplate('dialog'));\n // Add refs to dialog, not \"this\".\n dialog.refs = {};\n this.loadRefs.call(dialog, dialog, {\n dialogOverlay: 'single',\n dialogContents: 'single',\n dialogClose: 'single',\n });\n dialog.refs.dialogContents.appendChild(element);\n document.body.appendChild(dialog);\n document.body.classList.add('modal-open');\n dialog.close = () => {\n document.body.classList.remove('modal-open');\n dialog.dispatchEvent(new CustomEvent('close'));\n };\n this.addEventListener(dialog, 'close', () => this.removeChildFrom(dialog, document.body));\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n const handleCloseClick = (e) => {\n if (confirm) {\n confirm().then(() => close(e))\n .catch(() => { });\n }\n else {\n close(e);\n }\n };\n this.addEventListener(dialog.refs.dialogOverlay, 'click', handleCloseClick);\n this.addEventListener(dialog.refs.dialogClose, 'click', handleCloseClick);\n return dialog;\n }\n get optimizeRedraw() {\n if (this.options.optimizeRedraw && this.element && !this.visible) {\n this.addClass(this.element, 'formio-removed');\n return true;\n }\n return false;\n }\n /**\n * Retrieves the CSS class name of this component.\n * @returns {string} - The class name of this component.\n */\n get className() {\n let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback ` : '';\n className += `formio-component formio-component-${this.component.type} `;\n // TODO: find proper way to avoid overriding of default type-based component styles\n if (this.key && this.key !== 'form') {\n className += `formio-component-${this.key} `;\n }\n if (this.component.multiple) {\n className += 'formio-component-multiple ';\n }\n if (this.component.customClass) {\n className += this.component.customClass;\n }\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required)) {\n className += ' required';\n }\n if (this.labelIsHidden()) {\n className += ' formio-component-label-hidden';\n }\n if (!this.visible) {\n className += ' formio-hidden';\n }\n return className;\n }\n /**\n * Build the custom style from the layout values\n * @return {string} - The custom style\n */\n get customStyle() {\n let customCSS = '';\n lodash_1.default.each(this.component.style, (value, key) => {\n if (value !== '') {\n customCSS += `${key}:${value};`;\n }\n });\n return customCSS;\n }\n static get serverConditionSettings() {\n return Component.conditionOperatorsSettings;\n }\n get isMobile() {\n return (0, ismobilejs_1.default)();\n }\n /**\n * Returns the outside wrapping element of this component.\n * @returns {HTMLElement}\n */\n getElement() {\n return this.element;\n }\n /**\n * Create an evaluation context for all script executions and interpolations.\n *\n * @param additional\n * @return {*}\n */\n evalContext(additional) {\n return super.evalContext(Object.assign({\n component: this.component,\n row: this.data,\n rowIndex: this.rowIndex,\n data: this.rootValue,\n iconClass: this.iconClass.bind(this),\n // Bind the translate function to the data context of any interpolated string.\n // It is useful to translate strings in different scenarions (eg: custom edit grid templates, custom error messages etc.)\n // and desirable to be publicly available rather than calling the internal {instance.t} function in the template string.\n t: this.t.bind(this),\n submission: (this.root ? this.root._submission : {\n data: this.rootValue\n }),\n form: this.root ? this.root._form : {},\n options: this.options,\n }, additional));\n }\n /**\n * Sets the pristine flag for this component.\n *\n * @param pristine {boolean} - TRUE to make pristine, FALSE not pristine.\n */\n setPristine(pristine) {\n this.pristine = pristine;\n }\n get isPristine() {\n return this.pristine;\n }\n setDirty(dirty) {\n this.dirty = dirty;\n }\n get isDirty() {\n return this.dirty;\n }\n /**\n * Removes a value out of the data array and rebuild the rows.\n * @param {number} index - The index of the data element to remove.\n */\n removeValue(index) {\n this.splice(index);\n this.redraw();\n this.restoreValue();\n this.triggerRootChange();\n }\n iconClass(name, spinning) {\n const iconset = this.options.iconset || Templates_1.default.current.defaultIconset || 'fa';\n return Templates_1.default.current.hasOwnProperty('iconClass')\n ? Templates_1.default.current.iconClass(iconset, name, spinning)\n : this.options.iconset === 'fa' ? Templates_1.default.defaultTemplates.iconClass(iconset, name, spinning) : name;\n }\n size(size) {\n return Templates_1.default.current.hasOwnProperty('size')\n ? Templates_1.default.current.size(size)\n : size;\n }\n /**\n * The readible name for this component.\n * @returns {string} - The name of the component.\n */\n get name() {\n return this.t(this.component.label || this.component.placeholder || this.key, { _userInput: true });\n }\n get visibleErrors() {\n return this._visibleErrors;\n }\n get errors() {\n return this._errors;\n }\n /**\n * Returns the error label for this component.\n * @return {*}\n */\n get errorLabel() {\n return this.t(this.component.errorLabel\n || this.component.label\n || this.component.placeholder\n || this.key);\n }\n /**\n * Get the error message provided a certain type of error.\n * @param type\n * @return {*}\n */\n errorMessage(type) {\n return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type;\n }\n setContent(element, content, forceSanitize, sanitizeOptions) {\n if (element instanceof HTMLElement) {\n element.innerHTML = this.sanitize(content, forceSanitize, sanitizeOptions);\n return true;\n }\n return false;\n }\n restoreCaretPosition() {\n var _a, _b, _c;\n if ((_a = this.root) === null || _a === void 0 ? void 0 : _a.currentSelection) {\n if ((_b = this.refs.input) === null || _b === void 0 ? void 0 : _b.length) {\n const { selection, index } = this.root.currentSelection;\n let input = this.refs.input[index];\n const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test((i === null || i === void 0 ? void 0 : i.type) || '');\n if (input) {\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(...selection);\n }\n }\n else {\n input = this.refs.input[this.refs.input.length];\n const lastCharacter = ((_c = input.value) === null || _c === void 0 ? void 0 : _c.length) || 0;\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(lastCharacter, lastCharacter);\n }\n }\n }\n }\n }\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element || !this.element.parentNode || this.optimizeRedraw) {\n // Return a non-resolving promise.\n return Promise.resolve();\n }\n this.detach();\n this.emit('redraw');\n // Since we are going to replace the element, we need to know it's position so we can find it in the parent's children.\n const parent = this.element.parentNode;\n const index = Array.prototype.indexOf.call(parent.children, this.element);\n this.element.outerHTML = this.sanitize(this.render());\n this.setElement(parent.children[index]);\n return this.attach(this.element);\n }\n rebuild() {\n this.destroy();\n this.init();\n this.visible = this.conditionallyVisible(null, null);\n return this.redraw();\n }\n removeEventListeners() {\n super.removeEventListeners();\n this.tooltips.forEach(tooltip => tooltip.destroy());\n this.tooltips = [];\n }\n hasClass(element, className) {\n if (!element) {\n return;\n }\n return super.hasClass(element, this.transform('class', className));\n }\n addClass(element, className) {\n if (!element) {\n return;\n }\n return super.addClass(element, this.transform('class', className));\n }\n removeClass(element, className) {\n if (!element) {\n return;\n }\n return super.removeClass(element, this.transform('class', className));\n }\n /**\n * Determines if this component has a condition defined.\n *\n * @return {null}\n */\n hasCondition() {\n if (this._hasCondition !== null) {\n return this._hasCondition;\n }\n this._hasCondition = FormioUtils.hasCondition(this.component);\n return this._hasCondition;\n }\n /**\n * Check if this component is conditionally visible.\n *\n * @param data\n * @return {boolean}\n */\n conditionallyVisible(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n if (this.builderMode || this.previewMode || !this.hasCondition()) {\n return !this.component.hidden;\n }\n data = data || (this.root ? this.root.data : {});\n return this.checkCondition(row, data);\n }\n /**\n * Checks the condition of this component.\n *\n * TODO: Switch row and data parameters to be consistent with other methods.\n *\n * @param row - The row contextual data.\n * @param data - The global data object.\n * @return {boolean} - True if the condition applies to this component.\n */\n checkCondition(row, data) {\n return FormioUtils.checkCondition(this.component, row || this.data, data || this.rootValue, this.root ? this.root._form : {}, this);\n }\n /**\n * Check for conditionals and hide/show the element based on those conditions.\n */\n checkComponentConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {\n this.redraw();\n }\n // Check advanced conditions\n const visible = this.conditionallyVisible(data, row);\n if (this.visible !== visible) {\n this.visible = visible;\n }\n return visible;\n }\n /**\n * Checks conditions for this component and any sub components.\n * @param args\n * @return {boolean}\n */\n checkConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.checkComponentConditions(data, flags, row);\n }\n get logic() {\n return this.component.logic || [];\n }\n /**\n * Check all triggers and apply necessary actions.\n *\n * @param data\n */\n fieldLogic(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n const logics = this.logic;\n // If there aren't logic, don't go further.\n if (logics.length === 0) {\n return;\n }\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n let changed = logics.reduce((changed, logic) => {\n const result = FormioUtils.checkTrigger(newComponent, logic.trigger, row, data, this.root ? this.root._form : {}, this);\n return (result ? this.applyActions(newComponent, logic.actions, result, row, data) : false) || changed;\n }, false);\n // If component definition changed, replace and mark as changed.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n changed = true;\n const disabled = this.shouldDisabled;\n // Change disabled state if it has changed\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n }\n return changed;\n }\n isIE() {\n if (typeof window === 'undefined') {\n return false;\n }\n const userAgent = window.navigator.userAgent;\n const msie = userAgent.indexOf('MSIE ');\n if (msie > 0) {\n // IE 10 or older => return version number\n return parseInt(userAgent.substring(msie + 5, userAgent.indexOf('.', msie)), 10);\n }\n const trident = userAgent.indexOf('Trident/');\n if (trident > 0) {\n // IE 11 => return version number\n const rv = userAgent.indexOf('rv:');\n return parseInt(userAgent.substring(rv + 3, userAgent.indexOf('.', rv)), 10);\n }\n const edge = userAgent.indexOf('Edge/');\n if (edge > 0) {\n // IE 12 (aka Edge) => return version number\n return parseInt(userAgent.substring(edge + 5, userAgent.indexOf('.', edge)), 10);\n }\n // other browser\n return false;\n }\n defineActionValue(action, argsObject) {\n return this.evaluate(action.value, argsObject, 'value');\n }\n applyActions(newComponent, actions, result, row, data) {\n data = data || this.rootValue;\n row = row || this.data;\n return actions.reduce((changed, action) => {\n switch (action.type) {\n case 'property': {\n FormioUtils.setActionProperty(newComponent, action, result, row, data, this);\n const property = action.property.value;\n if (!lodash_1.default.isEqual(lodash_1.default.get(this.component, property), lodash_1.default.get(newComponent, property))) {\n changed = true;\n }\n break;\n }\n case 'value': {\n const oldValue = this.getValue();\n const newValue = this.defineActionValue(action, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n component: newComponent,\n result,\n });\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n case 'mergeComponentSchema': {\n const schema = this.evaluate(action.schemaDefinition, {\n value: lodash_1.default.clone(this.getValue()),\n data,\n row,\n component: newComponent,\n result,\n }, 'schema');\n lodash_1.default.assign(newComponent, schema);\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n changed = true;\n }\n break;\n }\n case 'customAction': {\n const oldValue = this.getValue();\n const newValue = this.evaluate(action.customAction, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n input: oldValue,\n component: newComponent,\n result,\n }, 'value');\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n }\n return changed;\n }, false);\n }\n // Deprecated\n addInputError(message, dirty, elements) {\n this.addMessages(message);\n this.setErrorClasses(elements, dirty, !!message);\n }\n // Deprecated\n removeInputError(elements) {\n this.setErrorClasses(elements, true, false);\n }\n /**\n * Add a new input error to this element.\n *\n * @param message\n * @param dirty\n */\n addMessages(messages) {\n if (!messages) {\n return;\n }\n // Standardize on array of objects for message.\n if (typeof messages === 'string') {\n messages = {\n messages,\n level: 'error',\n };\n }\n if (!Array.isArray(messages)) {\n messages = [messages];\n }\n messages = lodash_1.default.uniqBy(messages, message => message.message);\n if (this.refs.messageContainer) {\n this.setContent(this.refs.messageContainer, messages.map((message) => {\n if (message.message && typeof message.message === 'string') {\n message.message = message.message.replaceAll('<', '<').replaceAll('>', '>');\n }\n return this.renderTemplate('message', Object.assign({}, message));\n }).join(''));\n }\n }\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n this.clearErrorClasses();\n elements.forEach((element) => {\n this.setElementInvalid(this.performInputMapping(element), false);\n });\n this.setInputWidgetErrorClasses(elements, hasErrors);\n // do not set error classes for hidden components\n if (!this.visible) {\n return;\n }\n if (hasErrors) {\n // Add error classes\n elements.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), true);\n });\n if (dirty && this.options.highlightErrors) {\n this.addClass(element, this.options.componentErrorClass);\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n if (hasMessages) {\n this.addClass(element, 'has-message');\n }\n }\n setElementInvalid(element, invalid) {\n if (!element)\n return;\n if (invalid) {\n this.addClass(element, 'is-invalid');\n }\n else {\n this.removeClass(element, 'is-invalid');\n }\n element.setAttribute('aria-invalid', invalid ? 'true' : 'false');\n }\n clearOnHide() {\n // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.\n if (\n // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true\n (!this.rootPristine || this.options.server || (0, utils_1.isInsideScopingComponent)(this)) &&\n this.component.clearOnHide !== false &&\n !this.options.readOnly &&\n !this.options.showHiddenFields) {\n if (!this.visible) {\n this.deleteValue();\n }\n else if (!this.hasValue() && this.shouldAddDefaultValue) {\n // If shown, ensure the default is set.\n this.setValue(this.defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n }\n triggerRootChange(...args) {\n if (this.options.onChange) {\n this.options.onChange(...args);\n }\n else if (this.root && this.root.triggerChange) {\n this.root.triggerChange(...args);\n }\n }\n onChange(flags, fromRoot) {\n flags = flags || {};\n if (flags.modified) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n this.addClass(this.getElement(), 'formio-modified');\n }\n // If we are supposed to validate on blur, then don't trigger validation yet.\n if (this.component.validateOn === 'blur') {\n flags.noValidate = true;\n }\n if (this.component.onChange) {\n this.evaluate(this.component.onChange, {\n flags\n });\n }\n // Set the changed variable.\n const changed = {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: flags\n };\n // Emit the change.\n this.emit('componentChange', changed);\n // Do not propogate the modified flag.\n let modified = false;\n if (flags.modified) {\n modified = true;\n delete flags.modified;\n }\n // Bubble this change up to the top.\n if (!fromRoot) {\n this.triggerRootChange(flags, changed, modified);\n }\n return changed;\n }\n get wysiwygDefault() {\n return {\n quill: {\n theme: 'snow',\n placeholder: this.t(this.component.placeholder, { _userInput: true }),\n modules: {\n toolbar: [\n [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown\n [{ 'header': [1, 2, 3, 4, 5, 6, false] }],\n [{ 'font': [] }],\n ['bold', 'italic', 'underline', 'strike', { 'script': 'sub' }, { 'script': 'super' }, 'clean'],\n [{ 'color': [] }, { 'background': [] }],\n [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }, { 'align': [] }],\n ['blockquote', 'code-block'],\n ['link', 'image', 'video', 'formula', 'source']\n ]\n }\n },\n ace: {\n theme: 'ace/theme/xcode',\n maxLines: 12,\n minLines: 12,\n tabSize: 2,\n mode: 'ace/mode/javascript',\n placeholder: this.t(this.component.placeholder, { _userInput: true })\n },\n ckeditor: {\n image: {\n toolbar: [\n 'imageTextAlternative',\n '|',\n 'imageStyle:full',\n 'imageStyle:alignLeft',\n 'imageStyle:alignCenter',\n 'imageStyle:alignRight'\n ],\n styles: [\n 'full',\n 'alignLeft',\n 'alignCenter',\n 'alignRight'\n ]\n },\n extraPlugins: []\n },\n default: {}\n };\n }\n addCKE(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? {} : settings;\n settings.base64Upload = this.component.isUploadEnabled ? false : true;\n settings.mediaEmbed = { previewsInData: true };\n settings = lodash_1.default.merge(this.wysiwygDefault.ckeditor, lodash_1.default.get(this.options, 'editors.ckeditor.settings', {}), settings);\n if (this.component.isUploadEnabled) {\n settings.extraPlugins.push((0, uploadAdapter_1.getFormioUploadAdapterPlugin)(this.fileService, this));\n }\n return Formio_1.Formio.requireLibrary('ckeditor', isIEBrowser ? 'CKEDITOR' : 'ClassicEditor', lodash_1.default.get(this.options, 'editors.ckeditor.src', `${Formio_1.Formio.cdn.ckeditor}/ckeditor.js`), true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n if (isIEBrowser) {\n const editor = CKEDITOR.replace(element);\n editor.on('change', () => onChange(editor.getData()));\n return Promise.resolve(editor);\n }\n else {\n return ClassicEditor.create(element, settings).then(editor => {\n editor.model.document.on('change', () => onChange(editor.data.get()));\n return editor;\n });\n }\n });\n }\n addQuill(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? this.wysiwygDefault.quill : settings;\n settings = lodash_1.default.merge(this.wysiwygDefault.quill, lodash_1.default.get(this.options, 'editors.quill.settings', {}), settings);\n settings = Object.assign(Object.assign({}, settings), { modules: Object.assign({ table: true }, settings.modules) });\n // Lazy load the quill css.\n Formio_1.Formio.requireLibrary(`quill-css-${settings.theme}`, 'Quill', [\n { type: 'styles', src: `${Formio_1.Formio.cdn.quill}/quill.${settings.theme}.css` }\n ], true);\n // Lazy load the quill library.\n return Formio_1.Formio.requireLibrary('quill', 'Quill', lodash_1.default.get(this.options, 'editors.quill.src', `${Formio_1.Formio.cdn.quill}/quill.min.js`), true)\n .then(() => {\n return Formio_1.Formio.requireLibrary('quill-table', 'Quill', `${Formio_1.Formio.cdn.baseUrl}/quill/quill-table.js`, true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n this.quill = new Quill(element, isIEBrowser ? Object.assign(Object.assign({}, settings), { modules: {} }) : settings);\n /** This block of code adds the [source] capabilities. See https://codepen.io/anon/pen/ZyEjrQ **/\n const txtArea = document.createElement('textarea');\n txtArea.setAttribute('class', 'quill-source-code');\n this.quill.addContainer('ql-custom').appendChild(txtArea);\n const qlSource = element.parentNode.querySelector('.ql-source');\n if (qlSource) {\n this.addEventListener(qlSource, 'click', (event) => {\n event.preventDefault();\n if (txtArea.style.display === 'inherit') {\n this.quill.setContents(this.quill.clipboard.convert({ html: txtArea.value }));\n }\n txtArea.style.display = (txtArea.style.display === 'none') ? 'inherit' : 'none';\n });\n }\n /** END CODEBLOCK **/\n // Make sure to select cursor when they click on the element.\n this.addEventListener(element, 'click', () => this.quill.focus());\n // Allows users to skip toolbar items when tabbing though form\n const elm = document.querySelectorAll('.ql-formats > button');\n for (let i = 0; i < elm.length; i++) {\n elm[i].setAttribute('tabindex', '-1');\n }\n this.quill.on('text-change', () => {\n txtArea.value = this.quill.root.innerHTML;\n onChange(txtArea);\n });\n return this.quill;\n });\n });\n }\n get shouldSanitizeValue() {\n var _a;\n // Sanitize value if sanitizing for thw whole content is turned off\n return (((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitize) !== false);\n }\n addAce(element, settings, onChange) {\n if (!settings || (settings.theme === 'snow')) {\n const mode = settings ? settings.mode : '';\n settings = {};\n if (mode) {\n settings.mode = mode;\n }\n }\n settings = lodash_1.default.merge(this.wysiwygDefault.ace, lodash_1.default.get(this.options, 'editors.ace.settings', {}), settings || {});\n return Formio_1.Formio.requireLibrary('ace', 'ace', lodash_1.default.get(this.options, 'editors.ace.src', `${Formio_1.Formio.cdn.ace}/ace.js`), true)\n .then((editor) => {\n editor = editor.edit(element);\n editor.removeAllListeners('change');\n editor.setOptions(settings);\n editor.getSession().setMode(settings.mode);\n editor.on('change', () => onChange(editor.getValue()));\n if (settings.isUseWorkerDisabled) {\n editor.session.setUseWorker(false);\n }\n return editor;\n });\n }\n get tree() {\n return this.component.tree || false;\n }\n /**\n * The empty value for this component.\n *\n * @return {null}\n */\n get emptyValue() {\n return null;\n }\n /**\n * Returns if this component has a value set.\n *\n */\n hasValue(data) {\n return !lodash_1.default.isUndefined(lodash_1.default.get(data || this.data, this.key));\n }\n /**\n * Get the data value at the root level.\n *\n * @return {*}\n */\n get rootValue() {\n return this.root ? this.root.data : this.data;\n }\n get rootPristine() {\n return lodash_1.default.get(this, 'root.pristine', false);\n }\n /**\n * Get the static value of this component.\n * @return {*}\n */\n get dataValue() {\n if (!this.key ||\n (!this.visible && this.component.clearOnHide && !this.rootPristine)) {\n return this.emptyValue;\n }\n if (!this.hasValue() && this.shouldAddDefaultValue) {\n const empty = this.component.multiple ? [] : this.emptyValue;\n if (!this.rootPristine) {\n this.dataValue = empty;\n }\n return empty;\n }\n return lodash_1.default.get(this._data, this.key);\n }\n /**\n * Sets the static value of this component.\n *\n * @param value\n */\n set dataValue(value) {\n if (!this.allowData ||\n !this.key ||\n (!this.visible && this.component.clearOnHide && !this.rootPristine)) {\n return;\n }\n if ((value !== null) && (value !== undefined)) {\n value = this.hook('setDataValue', value, this.key, this._data);\n }\n if ((value === null) || (value === undefined)) {\n this.unset();\n return;\n }\n lodash_1.default.set(this._data, this.key, value);\n return;\n }\n /**\n * Splice a value from the dataValue.\n *\n * @param index\n */\n splice(index, flags = {}) {\n if (this.hasValue()) {\n const dataValue = this.dataValue || [];\n if (lodash_1.default.isArray(dataValue) && dataValue.hasOwnProperty(index)) {\n dataValue.splice(index, 1);\n this.dataValue = dataValue;\n this.triggerChange(flags);\n }\n }\n }\n unset() {\n lodash_1.default.unset(this._data, this.key);\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n getCustomDefaultValue(defaultValue) {\n if (this.component.customDefaultValue && !this.options.preview) {\n defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');\n }\n return defaultValue;\n }\n get shouldAddDefaultValue() {\n return !this.options.noDefaults || (this.component.defaultValue && !this.isEmpty(this.component.defaultValue)) || this.component.customDefaultValue;\n }\n get defaultValue() {\n let defaultValue = this.emptyValue;\n if (this.component.defaultValue) {\n defaultValue = this.component.defaultValue;\n }\n defaultValue = this.getCustomDefaultValue(defaultValue);\n const checkMask = (value) => {\n if (typeof value === 'string') {\n if (this.component.type !== 'textfield') {\n const placeholderChar = this.placeholderChar;\n value = (0, vanilla_text_mask_1.conformToMask)(value, this.defaultMask, { placeholderChar }).conformedValue;\n if (!FormioUtils.matchInputMask(value, this.defaultMask)) {\n value = '';\n }\n }\n }\n else {\n value = '';\n }\n return value;\n };\n if (this.defaultMask) {\n if (Array.isArray(defaultValue)) {\n defaultValue = defaultValue.map(checkMask);\n }\n else {\n defaultValue = checkMask(defaultValue);\n }\n }\n // Clone so that it creates a new instance.\n return lodash_1.default.cloneDeep(defaultValue);\n }\n /**\n * Get the input value of this component.\n *\n * @return {*}\n */\n getValue() {\n if (!this.hasInput || this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n const values = [];\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n if (!this.component.multiple) {\n return this.getValueAt(i);\n }\n values.push(this.getValueAt(i));\n }\n }\n if (values.length === 0 && !this.component.multiple) {\n return '';\n }\n return values;\n }\n /**\n * Get the value at a specific index.\n *\n * @param index\n * @returns {*}\n */\n getValueAt(index) {\n const input = this.performInputMapping(this.refs.input[index]);\n return input ? input.value : undefined;\n }\n /**\n * Set the value of this component.\n *\n * @param value\n * @param flags\n *\n * @return {boolean} - If the value changed.\n */\n setValue(value, flags = {}) {\n const changed = this.updateValue(value, flags);\n value = this.dataValue;\n if (!this.hasInput) {\n return changed;\n }\n const isArray = Array.isArray(value);\n const valueInput = this.refs.fileLink || this.refs.input;\n if (isArray &&\n Array.isArray(this.defaultValue) &&\n this.refs.hasOwnProperty('input') &&\n valueInput &&\n (valueInput.length !== value.length) &&\n this.visible) {\n this.redraw();\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.redraw();\n return changed;\n }\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n this.setValueAt(i, isArray ? value[i] : value, flags);\n }\n }\n return changed;\n }\n /**\n * Set the value at a specific index.\n *\n * @param index\n * @param value\n */\n setValueAt(index, value, flags = {}) {\n if (!flags.noDefault && (value === null || value === undefined) && !this.component.multiple) {\n value = this.defaultValue;\n }\n const input = this.performInputMapping(this.refs.input[index]);\n const valueMaskInput = this.refs.valueMaskInput;\n if ((valueMaskInput === null || valueMaskInput === void 0 ? void 0 : valueMaskInput.mask) && valueMaskInput.mask.textMaskInputElement) {\n valueMaskInput.mask.textMaskInputElement.update(value);\n }\n if (input.mask && input.mask.textMaskInputElement) {\n input.mask.textMaskInputElement.update(value);\n }\n else if (input.widget && input.widget.setValue) {\n input.widget.setValue(value);\n }\n else {\n input.value = value;\n }\n }\n get hasSetValue() {\n return this.hasValue() && !this.isEmpty(this.dataValue);\n }\n setDefaultValue() {\n if (this.defaultValue && this.shouldAddDefaultValue) {\n const defaultValue = (this.component.multiple && !this.dataValue.length) ? [] : this.defaultValue;\n this.setValue(defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n /**\n * Restore the value of a control.\n */\n restoreValue() {\n if (this.hasSetValue) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else {\n this.setDefaultValue();\n }\n }\n /**\n * Normalize values coming into updateValue.\n *\n * @param value\n * @return {*}\n */\n normalizeValue(value) {\n if (this.component.multiple && !Array.isArray(value)) {\n value = value ? [value] : [];\n }\n return value;\n }\n /**\n * Update a value of this component.\n *\n * @param flags\n */\n updateComponentValue(value, flags = {}) {\n let newValue = (!flags.resetValue && (value === undefined || value === null)) ? this.getValue() : value;\n newValue = this.normalizeValue(newValue, flags);\n const oldValue = this.dataValue;\n let changed = ((newValue !== undefined) ? this.hasChanged(newValue, oldValue) : false);\n if (changed) {\n this.dataValue = newValue;\n changed = this.dataValue !== oldValue;\n this.updateOnChange(flags, changed);\n }\n if (this.componentModal && flags && flags.fromSubmission) {\n this.componentModal.setValue(value);\n }\n return changed;\n }\n /**\n * Updates the value of this component plus all sub-components.\n *\n * @param args\n * @return {boolean}\n */\n updateValue(...args) {\n return this.updateComponentValue(...args);\n }\n getIcon(name, content, styles, ref = 'icon') {\n return this.renderTemplate('icon', {\n className: this.iconClass(name),\n ref,\n styles,\n content\n });\n }\n /**\n * Resets the value of this component.\n */\n resetValue() {\n this.unset();\n this.setValue(this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n /**\n * Determine if the value of this component has changed.\n *\n * @param newValue\n * @param oldValue\n * @return {boolean}\n */\n hasChanged(newValue, oldValue) {\n if (((newValue === undefined) || (newValue === null)) &&\n ((oldValue === undefined) || (oldValue === null) || this.isEmpty(oldValue))) {\n return false;\n }\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n this.allowData &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n /**\n * Update the value on change.\n *\n * @param flags\n */\n updateOnChange(flags = {}, changed = false) {\n if (!flags.noUpdateEvent && changed) {\n if (flags.fromSubmission) {\n // Reset the errors when a submission has been made and allow it to revalidate.\n this._errors = [];\n }\n this.triggerChange(flags);\n return true;\n }\n return false;\n }\n /**\n * Perform a calculated value operation.\n *\n * @param data - The global data object.\n *\n * @return {boolean} - If the value changed during calculation.\n */\n convertNumberOrBoolToString(value) {\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n return value;\n }\n doValueCalculation(dataValue, data, row) {\n var _a;\n return this.evaluate(this.component.calculateValue, {\n value: dataValue,\n data,\n row: row || this.data,\n submission: ((_a = this.root) === null || _a === void 0 ? void 0 : _a._submission) || {\n data: this.rootValue\n }\n }, 'value');\n }\n /* eslint-disable max-statements */\n calculateComponentValue(data, flags, row) {\n // Skip value calculation for the component if we don't have entire form data set or in builder mode\n if (this.builderMode || lodash_1.default.isUndefined(lodash_1.default.get(this, 'root.data'))) {\n return false;\n }\n // If no calculated value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n const { clearOnHide } = this.component;\n const shouldBeCleared = !this.visible && clearOnHide;\n const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);\n if (shouldBeCleared) {\n // remove calculated value so that the value is recalculated once component becomes visible\n if (this.hasOwnProperty('calculatedValue') && allowOverride) {\n lodash_1.default.unset(this, 'calculatedValue');\n }\n return false;\n }\n // Handle all cases when calculated values should not fire.\n if ((this.options.readOnly && !this.options.pdf && !this.component.calculateValue) ||\n !(this.component.calculateValue || this.component.calculateValueVariable) ||\n (this.options.server && !this.component.calculateServer) ||\n (flags.dataSourceInitialLoading && allowOverride)) {\n return false;\n }\n const dataValue = this.dataValue;\n // Calculate the new value.\n let calculatedValue = this.doValueCalculation(dataValue, data, row, flags);\n if (this.options.readOnly && dataValue && !calculatedValue) {\n return false;\n }\n if (lodash_1.default.isNil(calculatedValue)) {\n calculatedValue = this.emptyValue;\n }\n const changed = !lodash_1.default.isEqual(dataValue, calculatedValue);\n // Do not override calculations on server if they have calculateServer set.\n if (allowOverride) {\n // The value is considered locked if it is not empty and comes from a submission value.\n const fromSubmission = (flags.fromSubmission && this.component.persistent === true);\n if (this.isEmpty(dataValue)) {\n // Reset the calculation lock if ever the data is cleared.\n this.calculationLocked = false;\n }\n else if (this.calculationLocked || fromSubmission) {\n this.calculationLocked = true;\n return false;\n }\n const firstPass = (this.calculatedValue === undefined) || flags.resetValue;\n if (firstPass) {\n this.calculatedValue = null;\n }\n const newCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(calculatedValue));\n const previousCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(this.calculatedValue));\n const normalizedDataValue = this.normalizeValue(this.convertNumberOrBoolToString(dataValue));\n const calculationChanged = !lodash_1.default.isEqual(previousCalculatedValue, newCalculatedValue);\n const previousChanged = !lodash_1.default.isEqual(normalizedDataValue, previousCalculatedValue);\n if (calculationChanged && previousChanged && !firstPass) {\n return false;\n }\n // Check to ensure that the calculated value is different than the previously calculated value.\n if (previousCalculatedValue && previousChanged && !calculationChanged) {\n this.calculatedValue = null;\n return false;\n }\n if (flags.isReordered || !calculationChanged) {\n return false;\n }\n if (fromSubmission) {\n // If we set value from submission and it differs from calculated one, set the calculated value to prevent overriding dataValue in the next pass\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n return false;\n }\n // If this is the firstPass, and the dataValue is different than to the calculatedValue.\n if (firstPass && !this.isEmpty(dataValue) && changed && calculationChanged) {\n // Return that we have a change so it will perform another pass.\n return true;\n }\n }\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n if (changed) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n flags.triggeredComponentId = this.id;\n return this.setValue(calculatedValue, flags);\n }\n return false;\n }\n /* eslint-enable max-statements */\n /**\n * Performs calculations in this component plus any child components.\n *\n * @param args\n * @return {boolean}\n */\n calculateValue(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.calculateComponentValue(data, flags, row);\n }\n /**\n * Get this component's label text.\n *\n */\n get label() {\n return this.component.label;\n }\n /**\n * Set this component's label text and render it.\n *\n * @param value - The new label text.\n */\n set label(value) {\n this.component.label = value;\n if (this.labelElement) {\n this.labelElement.innerText = value;\n }\n }\n /**\n * Get FormioForm element at the root of this component tree.\n *\n */\n getRoot() {\n return this.root;\n }\n /**\n * Returns the invalid message, or empty string if the component is valid.\n *\n * @param data\n * @param dirty\n * @return {*}\n */\n invalidMessage(data, dirty, ignoreCondition, row) {\n if (!ignoreCondition && !this.checkCondition(row, data)) {\n return '';\n }\n // See if this is forced invalid.\n if (this.invalid) {\n return this.invalid;\n }\n // No need to check for errors if there is no input or if it is pristine.\n if (!this.hasInput || (!dirty && this.pristine)) {\n return '';\n }\n const validationScope = { errors: [] };\n (0, process_1.processOneSync)({\n component: this.component,\n data,\n row,\n path: this.path || this.component.key,\n scope: validationScope,\n instance: this,\n processors: [\n process_1.validateProcessInfo\n ]\n });\n const errors = validationScope.errors;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return lodash_1.default.map(interpolatedErrors, 'message').join('\\n\\n');\n }\n /**\n * Returns if the component is valid or not.\n *\n * @param data\n * @param dirty\n * @return {boolean}\n */\n isValid(data, dirty) {\n return !this.invalidMessage(data, dirty);\n }\n setComponentValidity(errors, dirty, silentCheck) {\n if (silentCheck) {\n return [];\n }\n const messages = errors.filter(message => !message.fromServer);\n if (errors.length && !!messages.length && (!this.isEmpty(this.defaultValue) || dirty || !this.pristine)) {\n return this.setCustomValidity(messages, dirty);\n }\n else {\n return this.setCustomValidity('');\n }\n }\n /**\n * Interpolate errors from the validation methods.\n * @param {*} errors\n * @returns\n */\n interpolateErrors(errors) {\n var _a;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return ((_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.length) ? [...interpolatedErrors, ...this.serverErrors] : interpolatedErrors;\n }\n /**\n * Show component validation errors.\n * @param {*} errors - An array of errors that have occured.\n * @param {*} data - The root submission data.\n * @param {*} row - The contextual row data.\n * @param {*} flags - The flags to perform validation.\n * @returns\n */\n showValidationErrors(errors, data, row, flags) {\n if (flags.silentCheck) {\n return [];\n }\n if (this.options.alwaysDirty) {\n flags.dirty = true;\n }\n if (flags.fromSubmission && this.hasValue(data)) {\n flags.dirty = true;\n }\n this.setDirty(flags.dirty);\n return this.setComponentValidity(errors, flags.dirty, flags.silentCheck, flags.fromSubmission);\n }\n /**\n * Perform a component validation.\n * @param {*} data - The root data you wish to use for this component.\n * @param {*} row - The contextual row data you wish to use for this component.\n * @param {*} flags - The flags to control the behavior of the validation.\n * @returns\n */\n validateComponent(data, row, flags = {}) {\n data = data || this.rootValue;\n row = row || this.data;\n const { async = false } = flags;\n if (this.shouldSkipValidation(data, row, flags)) {\n return async ? Promise.resolve([]) : [];\n }\n const processContext = {\n component: this.component,\n data,\n row,\n value: this.validationValue,\n path: this.path || this.component.key,\n instance: this,\n scope: { errors: [] },\n processors: [\n process_1.validateProcessInfo\n ]\n };\n if (async) {\n return (0, process_1.processOne)(processContext).then(() => {\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n });\n }\n (0, process_1.processOneSync)(processContext);\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n }\n /**\n * Checks the validity of this component and sets the error message if it is invalid.\n *\n * @param data\n * @param dirty\n * @param row\n * @return {boolean}\n */\n checkComponentValidity(data, dirty, row, flags = {}, allErrors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n flags.dirty = dirty || false;\n if (flags.async) {\n return this.validateComponent(data, row, flags).then((errors) => {\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);\n }\n }\n this.showValidationErrors(errors, data, row, flags);\n return errors.length === 0;\n });\n }\n else {\n const errors = this.validateComponent(data, row, flags);\n this.showValidationErrors(errors, data, row, flags);\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);\n }\n }\n return errors.length === 0;\n }\n }\n /**\n * Checks the validity of the component.\n * @param {*} data\n * @param {*} dirty\n * @param {*} row\n * @param {*} silentCheck\n * @returns\n */\n checkValidity(data = null, dirty = false, row = null, silentCheck = false, errors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n console.log('Deprecation warning: Component.checkValidity() will be deprecated in 6.x version of renderer. Use Component.validateComponent instead.');\n return this.checkComponentValidity(data, dirty, row, { silentCheck }, errors);\n }\n checkAsyncValidity(data, dirty, row, silentCheck, errors = []) {\n console.log('Deprecation warning: Component.checkAsyncValidity() will be deprecated in 6.x version of renderer. Use Component.validateComponent instead.');\n return this.checkComponentValidity(data, dirty, row, { async: true, silentCheck }, errors);\n }\n /**\n * Check the conditions, calculations, and validity of a single component and triggers an update if\n * something changed.\n *\n * @param data - The root data of the change event.\n * @param flags - The flags from this change event.\n *\n * @return boolean - If component is valid or not.\n */\n checkData(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n // Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners\n if (!flags.fromBlur) {\n this.checkRefreshOn(flags.changes, flags);\n }\n if (flags.noCheck) {\n return true;\n }\n this.checkComponentConditions(data, flags, row);\n if (this.id !== flags.triggeredComponentId) {\n this.calculateComponentValue(data, flags, row);\n }\n }\n checkModal(errors = [], dirty = false) {\n const messages = errors.filter(error => !error.fromServer);\n const isValid = errors.length === 0;\n if (!this.component.modalEdit || !this.componentModal) {\n return;\n }\n if (dirty && !isValid) {\n this.setErrorClasses([this.refs.openModal], dirty, !isValid, !!messages.length, this.refs.openModalWrapper);\n }\n else {\n this.clearErrorClasses(this.refs.openModalWrapper);\n }\n }\n get validationValue() {\n return this.dataValue;\n }\n isEmpty(value = this.dataValue) {\n const isEmptyArray = (lodash_1.default.isArray(value) && value.length === 1) ? lodash_1.default.isEqual(value[0], this.emptyValue) : false;\n return value == null || value.length === 0 || lodash_1.default.isEqual(value, this.emptyValue) || isEmptyArray;\n }\n isEqual(valueA, valueB = this.dataValue) {\n return (this.isEmpty(valueA) && this.isEmpty(valueB)) || lodash_1.default.isEqual(valueA, valueB);\n }\n /**\n * Check if a component is eligible for multiple validation\n *\n * @return {boolean}\n */\n validateMultiple() {\n return true;\n }\n clearErrorClasses(element = this.element) {\n this.removeClass(element, this.options.componentErrorClass);\n this.removeClass(element, 'alert alert-danger');\n this.removeClass(element, 'has-error');\n this.removeClass(element, 'has-message');\n }\n setInputWidgetErrorClasses(inputRefs, hasErrors) {\n if (!this.isInputComponent || !this.component.widget || !(inputRefs === null || inputRefs === void 0 ? void 0 : inputRefs.length)) {\n return;\n }\n inputRefs.forEach((input) => {\n if ((input === null || input === void 0 ? void 0 : input.widget) && input.widget.setErrorClasses) {\n input.widget.setErrorClasses(hasErrors);\n }\n });\n }\n addFocusBlurEvents(element) {\n this.addEventListener(element, 'focus', () => {\n if (this.root.focusedComponent !== this) {\n if (this.root.pendingBlur) {\n this.root.pendingBlur();\n }\n this.root.focusedComponent = this;\n this.emit('focus', this);\n }\n else if (this.root.focusedComponent === this && this.root.pendingBlur) {\n this.root.pendingBlur.cancel();\n this.root.pendingBlur = null;\n }\n });\n this.addEventListener(element, 'blur', () => {\n this.root.pendingBlur = FormioUtils.delay(() => {\n this.emit('blur', this);\n if (this.component.validateOn === 'blur') {\n this.root.triggerChange({ fromBlur: true }, {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: { fromBlur: true }\n });\n }\n this.root.focusedComponent = null;\n this.root.pendingBlur = null;\n });\n });\n }\n // eslint-disable-next-line max-statements\n setCustomValidity(messages, dirty, external) {\n const inputRefs = this.isInputComponent ? this.refs.input || [] : null;\n if (typeof messages === 'string' && messages) {\n messages = {\n level: 'error',\n message: messages,\n component: this.component,\n };\n }\n if (!Array.isArray(messages)) {\n if (messages) {\n messages = [messages];\n }\n else {\n messages = [];\n }\n }\n const errors = messages.filter(message => message.level === 'error');\n let invalidInputRefs = inputRefs;\n // Filter the invalid input refs in multiple components\n if (this.component.multiple) {\n const refsArray = Array.from(inputRefs);\n refsArray.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), false);\n });\n this.setInputWidgetErrorClasses(refsArray, false);\n invalidInputRefs = refsArray.filter((ref, index) => {\n var _a;\n return (_a = messages.some) === null || _a === void 0 ? void 0 : _a.call(messages, (msg) => {\n var _a;\n return ((_a = msg === null || msg === void 0 ? void 0 : msg.context) === null || _a === void 0 ? void 0 : _a.index) === index;\n });\n });\n }\n if (messages.length) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n this.emit('componentError', {\n instance: this,\n component: this.component,\n message: messages[0].message,\n messages,\n external: !!external,\n });\n this.addMessages(messages, dirty, invalidInputRefs);\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n }\n else if (!errors.length || (errors[0].external === !!external)) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n if (this.refs.modalMessageContainer) {\n this.empty(this.refs.modalMessageContainer);\n }\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n this.clearErrorClasses();\n }\n this._visibleErrors = messages;\n return messages;\n }\n /**\n * Determines if the value of this component is hidden from the user as if it is coming from the server, but is\n * protected.\n *\n * @return {boolean|*}\n */\n isValueHidden() {\n if (this.component.protected && this.root.editing) {\n return false;\n }\n if (!this.root || !this.root.hasOwnProperty('editing')) {\n return false;\n }\n if (!this.root || !this.root.editing) {\n return false;\n }\n return (this.component.protected || !this.component.persistent || (this.component.persistent === 'client-only'));\n }\n shouldSkipValidation(data, row, flags = {}) {\n const { validateWhenHidden = false } = this.component || {};\n const forceValidOnHidden = (!this.visible || !this.checkCondition(row, data)) && !validateWhenHidden;\n if (forceValidOnHidden) {\n // If this component is forced valid when it is hidden, then we also need to reset the errors for this component.\n this._errors = [];\n }\n const rules = [\n // Do not validate if the flags say not too.\n () => flags.noValidate,\n // Force valid if component is read-only\n () => this.options.readOnly,\n // Do not check validations if component is not an input component.\n () => !this.hasInput,\n // Check to see if we are editing and if so, check component persistence.\n () => this.isValueHidden(),\n // Force valid if component is hidden.\n () => forceValidOnHidden\n ];\n return rules.some(pred => pred());\n }\n // Maintain reverse compatibility.\n whenReady() {\n console.warn('The whenReady() method has been deprecated. Please use the dataReady property instead.');\n return this.dataReady;\n }\n get dataReady() {\n return Promise.resolve();\n }\n /**\n * Prints out the value of this component as a string value.\n */\n asString(value) {\n value = value || this.getValue();\n return (Array.isArray(value) ? value : [value]).map(lodash_1.default.toString).join(', ');\n }\n /**\n * Return if the component is disabled.\n * @return {boolean}\n */\n get disabled() {\n return this._disabled || this.parentDisabled;\n }\n /**\n * Disable this component.\n *\n * @param {boolean} disabled\n */\n set disabled(disabled) {\n this._disabled = disabled;\n }\n setDisabled(element, disabled) {\n if (!element) {\n return;\n }\n element.disabled = disabled;\n if (disabled) {\n element.setAttribute('disabled', 'disabled');\n }\n else {\n element.removeAttribute('disabled');\n }\n }\n setLoading(element, loading) {\n if (!element || (element.loading === loading)) {\n return;\n }\n element.loading = loading;\n if (!element.loader && loading) {\n element.loader = this.ce('i', {\n class: `${this.iconClass('refresh', true)} button-icon-right`\n });\n }\n if (element.loader) {\n if (loading) {\n this.appendTo(element.loader, element);\n }\n else {\n this.removeChildFrom(element.loader, element);\n }\n }\n }\n selectOptions(select, tag, options, defaultValue) {\n lodash_1.default.each(options, (option) => {\n const attrs = {\n value: option.value\n };\n if (defaultValue !== undefined && (option.value === defaultValue)) {\n attrs.selected = 'selected';\n }\n const optionElement = this.ce('option', attrs);\n optionElement.appendChild(this.text(option.label));\n select.appendChild(optionElement);\n });\n }\n setSelectValue(select, value) {\n const options = select.querySelectorAll('option');\n lodash_1.default.each(options, (option) => {\n if (option.value === value) {\n option.setAttribute('selected', 'selected');\n }\n else {\n option.removeAttribute('selected');\n }\n });\n if (select.onchange) {\n select.onchange();\n }\n if (select.onselect) {\n select.onselect();\n }\n }\n getRelativePath(path) {\n const keyPart = `.${this.key}`;\n const thisPath = this.isInputComponent ? this.path\n : this.path.slice(0).replace(keyPart, '');\n return path.replace(thisPath, '');\n }\n clear() {\n this.detach();\n this.empty(this.getElement());\n }\n append(element) {\n this.appendTo(element, this.element);\n }\n prepend(element) {\n this.prependTo(element, this.element);\n }\n removeChild(element) {\n this.removeChildFrom(element, this.element);\n }\n detachLogic() {\n this.logic.forEach(logic => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.off(event); // only applies to callbacks on this component\n }\n });\n }\n attachLogic() {\n // Do not attach logic during builder mode.\n if (this.builderMode) {\n return;\n }\n this.logic.forEach((logic) => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.on(event, (...args) => {\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n if (this.applyActions(newComponent, logic.actions, args)) {\n // If component definition changed, replace it.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n const visible = this.conditionallyVisible(null, null);\n const disabled = this.shouldDisabled;\n // Change states which won't be recalculated during redrawing\n if (this.visible !== visible) {\n this.visible = visible;\n }\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n this.redraw();\n }\n }\n }, true);\n }\n });\n }\n /**\n * Get the element information.\n */\n elementInfo() {\n const attributes = {\n name: this.options.name,\n type: this.component.inputType || 'text',\n class: 'form-control',\n lang: this.options.language\n };\n if (this.component.placeholder) {\n attributes.placeholder = this.t(this.component.placeholder, { _userInput: true });\n }\n if (this.component.tabindex) {\n attributes.tabindex = this.component.tabindex;\n }\n if (this.disabled) {\n attributes.disabled = 'disabled';\n }\n lodash_1.default.defaults(attributes, this.component.attributes);\n return {\n type: 'input',\n component: this.component,\n changeEvent: 'change',\n attr: attributes\n };\n }\n autofocus() {\n const hasAutofocus = this.component.autofocus && !this.builderMode && !this.options.preview;\n if (hasAutofocus) {\n this.on('render', () => this.focus(), true);\n }\n }\n scrollIntoView(element = this.element) {\n if (!element) {\n return;\n }\n const { left, top } = element.getBoundingClientRect();\n window.scrollTo(left + window.scrollX, top + window.scrollY);\n }\n focus(index = (this.refs.input.length - 1)) {\n var _a, _b;\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n if ((_a = this.refs.input) === null || _a === void 0 ? void 0 : _a.length) {\n const focusingInput = this.refs.input[index];\n if (((_b = this.component.widget) === null || _b === void 0 ? void 0 : _b.type) === 'calendar') {\n const sibling = focusingInput.nextSibling;\n if (sibling) {\n sibling.focus();\n }\n }\n else {\n focusingInput.focus();\n }\n }\n if (this.refs.openModal) {\n this.refs.openModal.focus();\n }\n if (this.parent.refs.openModal) {\n this.parent.refs.openModal.focus();\n }\n }\n /**\n * Get `Formio` instance for working with files\n */\n get fileService() {\n if (this.options.fileService) {\n return this.options.fileService;\n }\n if (this.options.formio) {\n return this.options.formio;\n }\n if (this.root && this.root.formio) {\n return this.root.formio;\n }\n const formio = new Formio_1.Formio();\n // If a form is loaded, then make sure to set the correct formUrl.\n if (this.root && this.root._form && this.root._form._id) {\n formio.formUrl = `${formio.projectUrl}/form/${this.root._form._id}`;\n }\n return formio;\n }\n resetCaches() { }\n get previewMode() {\n return false;\n }\n}\nexports[\"default\"] = Component;\nComponent.externalLibraries = {};\nComponent.requireLibrary = function (name, property, src, polling) {\n if (!Component.externalLibraries.hasOwnProperty(name)) {\n Component.externalLibraries[name] = {};\n Component.externalLibraries[name].ready = new Promise((resolve, reject) => {\n Component.externalLibraries[name].resolve = resolve;\n Component.externalLibraries[name].reject = reject;\n });\n const callbackName = `${name}Callback`;\n if (!polling && !window[callbackName]) {\n window[callbackName] = function () {\n this.resolve();\n }.bind(Component.externalLibraries[name]);\n }\n // See if the plugin already exists.\n const plugin = lodash_1.default.get(window, property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n src = Array.isArray(src) ? src : [src];\n src.forEach((lib) => {\n let attrs = {};\n let elementType = '';\n if (typeof lib === 'string') {\n lib = {\n type: 'script',\n src: lib\n };\n }\n switch (lib.type) {\n case 'script':\n elementType = 'script';\n attrs = {\n src: lib.src,\n type: 'text/javascript',\n defer: true,\n async: true\n };\n break;\n case 'styles':\n elementType = 'link';\n attrs = {\n href: lib.src,\n rel: 'stylesheet'\n };\n break;\n }\n // Add the script to the top page.\n const script = document.createElement(elementType);\n for (const attr in attrs) {\n script.setAttribute(attr, attrs[attr]);\n }\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n // if no callback is provided, then check periodically for the script.\n if (polling) {\n setTimeout(function checkLibrary() {\n const plugin = lodash_1.default.get(window, property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n // check again after 200 ms.\n setTimeout(checkLibrary, 200);\n }\n }, 200);\n }\n }\n }\n return Component.externalLibraries[name].ready;\n};\nComponent.libraryReady = function (name) {\n if (Component.externalLibraries.hasOwnProperty(name) &&\n Component.externalLibraries[name].ready) {\n return Component.externalLibraries[name].ready;\n }\n return Promise.reject(`${name} library was not required.`);\n};\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/component/Component.js?");
|
5521
5521
|
|
5522
5522
|
/***/ }),
|
5523
5523
|
|
@@ -5704,7 +5704,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5704
5704
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5705
5705
|
|
5706
5706
|
"use strict";
|
5707
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Components_1 = __importDefault(__webpack_require__(/*! ../../Components */ \"./lib/cjs/components/Components.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nclass NestedComponent extends Field_1.default {\n static schema(...extend) {\n return Field_1.default.schema({\n tree: false,\n lazyLoad: false,\n }, ...extend);\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.type = 'components';\n this._collapsed = !!this.component.collapsed;\n }\n get defaultSchema() {\n return NestedComponent.schema();\n }\n get schema() {\n const schema = super.schema;\n const components = lodash_1.default.uniqBy(this.getComponents(), 'component.key');\n schema.components = lodash_1.default.map(components, 'schema');\n return schema;\n }\n get collapsed() {\n return this._collapsed;\n }\n collapse(value) {\n const promise = this.redraw();\n if (!value) {\n this.checkValidity(this.data, !this.pristine);\n }\n return promise;\n }\n set collapsed(value) {\n this._collapsed = value;\n this.collapse(value);\n }\n set visible(value) {\n // DO NOT CALL super here. There is an issue where clearOnHide was getting triggered with\n // subcomponents because the \"parentVisible\" flag was set to false when it should really be\n // set to true.\n const visibilityChanged = this._visible !== value;\n this._visible = value;\n const isVisible = this.visible;\n const forceShow = this.shouldForceShow();\n const forceHide = this.shouldForceHide();\n this.components.forEach(component => {\n // Set the parent visibility first since we may have nested components within nested components\n // and they need to be able to determine their visibility based on the parent visibility.\n component.parentVisible = isVisible;\n const conditionallyVisible = component.conditionallyVisible();\n if (forceShow || conditionallyVisible) {\n component.visible = true;\n }\n else if (forceHide || !isVisible || !conditionallyVisible) {\n component.visible = false;\n }\n // If hiding a nested component, clear all errors below.\n if (!component.visible) {\n component.error = '';\n }\n });\n if (visibilityChanged) {\n this.clearOnHide();\n this.redraw();\n }\n }\n get visible() {\n return super.visible;\n }\n set parentVisible(value) {\n super.parentVisible = value;\n this.components.forEach(component => component.parentVisible = this.visible);\n }\n get parentVisible() {\n return super.parentVisible;\n }\n get disabled() {\n return super.disabled;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n this.components.forEach((component) => component.parentDisabled = disabled);\n }\n set parentDisabled(value) {\n super.parentDisabled = value;\n this.components.forEach(component => {\n component.parentDisabled = this.disabled;\n });\n }\n get parentDisabled() {\n return super.parentDisabled;\n }\n get ready() {\n return Promise.all(this.getComponents().map(component => component.ready));\n }\n get currentForm() {\n return super.currentForm;\n }\n set currentForm(instance) {\n super.currentForm = instance;\n this.getComponents().forEach(component => {\n component.currentForm = instance;\n });\n }\n get rowIndex() {\n return this._rowIndex;\n }\n set rowIndex(value) {\n this._rowIndex = value;\n this.eachComponent((component) => {\n component.rowIndex = value;\n });\n }\n componentContext() {\n return this._data;\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n this.eachComponent((component) => {\n component.data = this.componentContext(component);\n });\n }\n getComponents() {\n return this.components || [];\n }\n /**\n * Perform a deep iteration over every component, including those\n * within other container based components.\n *\n * @param {function} fn - Called for every component.\n */\n everyComponent(fn, options) {\n const components = this.getComponents();\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n hasComponent(component) {\n let result = false;\n this.everyComponent((comp) => {\n if (comp === component) {\n result = true;\n return false;\n }\n });\n return result;\n }\n flattenComponents() {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n });\n return result;\n }\n /**\n * Perform an iteration over each component within this container component.\n *\n * @param {function} fn - Called for each component\n */\n eachComponent(fn) {\n lodash_1.default.each(this.getComponents(), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n /**\n * Returns a component provided a key. This performs a deep search within the\n * component tree.\n *\n * @param {string} key - The key of the component to retrieve.\n * @param {function} [fn] - Called with the component once found.\n * @param {string} [originalPath] - The original path to the component.\n * @return {Component} - The component that is located.\n */\n getComponent(path, fn, originalPath) {\n originalPath = originalPath || (0, utils_1.getStringFromComponentPath)(path);\n if (this.componentsMap.hasOwnProperty(originalPath)) {\n if (fn) {\n return fn(this.componentsMap[originalPath]);\n }\n else {\n return this.componentsMap[originalPath];\n }\n }\n path = (0, utils_1.getArrayFromComponentPath)(path);\n const pathStr = originalPath;\n const newPath = lodash_1.default.clone(path);\n let key = newPath.shift();\n const remainingPath = newPath;\n let comp = null;\n let possibleComp = null;\n if (lodash_1.default.isNumber(key)) {\n key = remainingPath.shift();\n }\n if (!lodash_1.default.isString(key)) {\n return comp;\n }\n this.everyComponent((component, components) => {\n const matchPath = component.hasInput && component.path ? pathStr.includes(component.path) : true;\n if (component.component.key === key) {\n possibleComp = component;\n if (matchPath) {\n comp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn, originalPath);\n }\n else if (fn) {\n fn(component, components);\n }\n return false;\n }\n }\n });\n if (!comp) {\n comp = possibleComp;\n }\n return comp;\n }\n /**\n * Return a component provided the Id of the component.\n *\n * @param {string} id - The Id of the component.\n * @param {function} fn - Called with the component once it is retrieved.\n * @return {Object} - The component retrieved.\n */\n getComponentById(id, fn) {\n let comp = null;\n this.everyComponent((component, components) => {\n if (component.id === id) {\n comp = component;\n if (fn) {\n fn(component, components);\n }\n return false;\n }\n });\n return comp;\n }\n /**\n * Create a new component and add it to the components array.\n *\n * @param component\n * @param data\n */\n createComponent(component, options, data, before, replacedComp) {\n if (!component) {\n return;\n }\n options = options || this.options;\n data = data || this.data;\n options.parent = this;\n options.parentVisible = this.visible;\n options.root = (options === null || options === void 0 ? void 0 : options.root) || this.root || this;\n options.localRoot = this.localRoot;\n options.skipInit = true;\n if (!(options.display === 'pdf' && this.builderMode)) {\n component.id = (0, utils_1.getRandomComponentId)();\n }\n const comp = Components_1.default.create(component, options, data, true);\n comp.init();\n if (component.internal) {\n return comp;\n }\n if (before) {\n const index = lodash_1.default.findIndex(this.components, { id: before.id });\n if (index !== -1) {\n this.components.splice(index, 0, comp);\n }\n else {\n this.components.push(comp);\n }\n }\n else if (replacedComp) {\n const index = lodash_1.default.findIndex(this.components, { id: replacedComp.id });\n if (index !== -1) {\n this.components[index] = comp;\n }\n else {\n this.components.push(comp);\n }\n }\n else {\n this.components.push(comp);\n }\n return comp;\n }\n getContainer() {\n return this.element;\n }\n get componentComponents() {\n return this.component.components || [];\n }\n get nestedKey() {\n return `nested-${this.key}`;\n }\n get templateName() {\n return 'container';\n }\n init() {\n this.components = this.components || [];\n this.addComponents();\n return super.init();\n }\n /**\n *\n * @param element\n * @param data\n */\n addComponents(data, options) {\n data = data || this.data;\n this.components = this.components || [];\n options = options || this.options;\n if (options.components) {\n this.components = options.components;\n }\n else {\n const components = this.hook('addComponents', this.componentComponents, this) || [];\n components.forEach((component) => this.addComponent(component, data));\n }\n }\n /**\n * Add a new component to the components array.\n *\n * @param {Object} component - The component JSON schema to add.\n * @param {Object} data - The submission data object to house the data for this component.\n * @param {HTMLElement} before - A DOM element to insert this element before.\n * @return {Component} - The created component instance.\n */\n addComponent(component, data, before, noAdd) {\n data = data || this.data;\n this.components = this.components || [];\n component = this.hook('addComponent', component, data, before, noAdd);\n const comp = this.createComponent(component, this.options, data, before ? before : null);\n if (noAdd) {\n return comp;\n }\n return comp;\n }\n beforeFocus() {\n if (this.parent && 'beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n }\n render(children) {\n // If already rendering, don't re-render.\n return super.render(children || this.renderTemplate(this.templateName, {\n children: !this.visible ? '' : this.renderComponents(),\n nestedKey: this.nestedKey,\n collapsed: this.options.pdf ? false : this.collapsed,\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n return this.renderTemplate('components', {\n children,\n components,\n });\n }\n attach(element) {\n const superPromise = super.attach(element);\n this.loadRefs(element, {\n header: 'single',\n collapsed: this.collapsed,\n [this.nestedKey]: 'single',\n });\n let childPromise = Promise.resolve();\n if (this.refs[this.nestedKey]) {\n childPromise = this.attachComponents(this.refs[this.nestedKey]);\n }\n if (!this.visible) {\n this.attachComponentsLogic();\n }\n if (this.component.collapsible && this.refs.header) {\n this.addEventListener(this.refs.header, 'click', () => {\n this.collapsed = !this.collapsed;\n });\n this.addEventListener(this.refs.header, 'keydown', (e) => {\n if (e.keyCode === 13 || e.keyCode === 32) {\n e.preventDefault();\n this.collapsed = !this.collapsed;\n }\n });\n }\n return Promise.all([\n superPromise,\n childPromise,\n ]);\n }\n attachComponentsLogic(components) {\n components = components || this.components;\n lodash_1.default.each(components, (comp) => {\n comp.attachLogic();\n if (lodash_1.default.isFunction(comp.attachComponentsLogic)) {\n comp.attachComponentsLogic();\n }\n });\n }\n attachComponents(element, components, container) {\n components = components || this.components;\n container = container || this.component.components;\n element = this.hook('attachComponents', element, components, container, this);\n if (!element) {\n // Return a non-resolving promise.\n return (new Promise(() => { }));\n }\n let index = 0;\n const promises = [];\n Array.prototype.slice.call(element.children).forEach(child => {\n if (!child.getAttribute('data-noattach') && components[index]) {\n promises.push(components[index].attach(child));\n index++;\n }\n });\n return Promise.all(promises);\n }\n /**\n * Remove a component from the components array and from the children object\n *\n * @param {Component} component - The component to remove from the components.\n * @param {Array<Component>} components - An array of components to remove this component from.\n */\n removeComponent(component, components, all = false) {\n components = components || this.components;\n component.destroy(all);\n lodash_1.default.remove(components, { id: component.id });\n if (this.componentsMap[component.path]) {\n delete this.componentsMap[component.path];\n }\n }\n /**\n * Removes a component provided the API key of that component.\n *\n * @param {string} key - The API key of the component to remove.\n * @param {function} fn - Called once the component is removed.\n * @return {null}\n */\n removeComponentByKey(key, fn) {\n const comp = this.getComponent(key, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n /**\n * Removes a component provided the Id of the component.\n *\n * @param {string} id - The Id of the component to remove.\n * @param {function} fn - Called when the component is removed.\n * @return {null}\n */\n removeComponentById(id, fn) {\n const comp = this.getComponentById(id, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n updateValue(value, flags = {}) {\n return this.components.reduce((changed, comp) => {\n return comp.updateValue(null, flags) || changed;\n }, super.updateValue(value, flags));\n }\n shouldSkipValidation(data, row, flags) {\n // Nested components with no input should not be validated.\n if (!this.component.input) {\n return true;\n }\n else {\n return super.shouldSkipValidation(data, row, flags);\n }\n }\n checkData(data, flags, row, components) {\n if (this.builderMode) {\n return true;\n }\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n components = components && lodash_1.default.isArray(components) ? components : this.getComponents();\n super.checkData(data, Object.assign({}, flags), row);\n components.forEach((comp) => comp.checkData(data, Object.assign({}, flags), row));\n }\n checkConditions(data, flags, row) {\n // check conditions of parent component first, because it may influence on visibility of it's children\n const check = super.checkConditions(data, flags, row);\n //row data of parent component not always corresponds to row of nested components, use comp.data as row data for children instead\n this.getComponents().forEach(comp => comp.checkConditions(data, flags, comp.data));\n return check;\n }\n clearOnHide(show) {\n super.clearOnHide(show);\n if (this.component.clearOnHide) {\n if (this.allowData && !this.hasValue() && !(this.options.server && !this.visible)) {\n this.dataValue = this.defaultValue;\n }\n if (this.hasValue()) {\n this.restoreComponentsContext();\n }\n }\n this.getComponents().forEach(component => component.clearOnHide(show));\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => component.data = this.dataValue);\n }\n /**\n * Allow components to hook into the next page trigger to perform their own logic.\n *\n * @return {*}\n */\n beforePage(next) {\n return Promise.all(this.getComponents().map((comp) => comp.beforePage(next)));\n }\n /**\n * Allow components to hook into the submission to provide their own async data.\n *\n * @return {*}\n */\n beforeSubmit() {\n return Promise.allSettled(this.getComponents().map((comp) => comp.beforeSubmit()));\n }\n calculateValue(data, flags, row) {\n // Do not iterate into children and calculateValues if this nested component is conditionally hidden.\n if (!this.conditionallyVisible()) {\n return false;\n }\n return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));\n }\n isLastPage() {\n return this.pages.length - 1 === this.page;\n }\n isValid(data, dirty) {\n return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));\n }\n validationProcessor({ scope, data, row, instance }, flags) {\n const { dirty } = flags;\n if (!instance) {\n return;\n }\n instance.checkComponentValidity(data, dirty, row, flags, scope.errors);\n if (instance.processOwnValidation) {\n scope.noRecurse = true;\n }\n }\n /**\n * Perform a validation on all child components of this nested component.\n * @param {*} components\n * @param {*} data\n * @param {*} flags\n * @returns\n */\n validateComponents(components, data, flags = {}) {\n components = components || this.component.components;\n data = data || this.rootValue;\n const { async, dirty, process } = flags;\n const validationProcessorProcess = (context) => this.validationProcessor(context, flags);\n const checkModalProcessorProcess = ({ instance, component, components }) => {\n // If we just validated the last component, and there are errors from our parent, then we need to show a model of those errors.\n if (instance &&\n instance.parent &&\n (component === components[components.length - 1]) &&\n instance.parent.componentModal) {\n instance.parent.checkModal(instance.parent.childErrors, dirty);\n }\n };\n const processorContext = {\n process: process || 'unknown',\n components,\n instances: this.componentsMap,\n data: data,\n scope: { errors: [] },\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n },\n {\n process: checkModalProcessorProcess,\n processSync: checkModalProcessorProcess\n }\n ]\n };\n return async ? (0, process_1.process)(processorContext).then((scope) => scope.errors) : (0, process_1.processSync)(processorContext).errors;\n }\n /**\n * Validate a nested component with data, or its own internal data.\n * @param {*} data\n * @param {*} flags\n * @returns\n */\n validate(data, flags = {}) {\n data = data || this.rootValue;\n return this.validateComponents(this.getComponents().map((component) => component.component), data, flags);\n }\n checkComponentValidity(data, dirty, row, flags = {}, allErrors = []) {\n this.childErrors = [];\n return super.checkComponentValidity(data, dirty, row, flags, allErrors);\n }\n checkValidity(data, dirty, row, silentCheck, childErrors = []) {\n console.log('Deprecation warning: Component.checkValidity() will be deprecated in 6.x version of renderer. Use \"validate\" method instead.');\n childErrors.push(...this.validate(data, { dirty, silentCheck }));\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck }, childErrors) && childErrors.length === 0;\n }\n checkAsyncValidity(data, dirty, row, silentCheck) {\n console.log('Deprecation warning: Component.checkAsyncValidity() will be deprecated in 6.x version of renderer.');\n return this.ready.then(() => {\n return this.validate(data, { dirty, silentCheck, async: true }).then((childErrors) => {\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck, async: true }, childErrors).then((valid) => {\n return valid && childErrors.length === 0;\n });\n });\n });\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n this.getComponents().forEach((comp) => comp.setPristine(pristine));\n }\n get isPristine() {\n return this.pristine && this.getComponents().every((c) => c.isPristine);\n }\n get isDirty() {\n return this.dirty && this.getComponents().every((c) => c.isDirty);\n }\n detach() {\n this.components.forEach(component => {\n component.detach();\n });\n super.detach();\n }\n clear() {\n this.components.forEach(component => {\n component.clear();\n });\n super.clear();\n }\n destroy(all = false) {\n this.destroyComponents(all);\n super.destroy(all);\n }\n destroyComponents(all = false) {\n const components = this.getComponents().slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n this.components = [];\n }\n get visibleErrors() {\n return this.getComponents().reduce((errors, comp) => errors.concat(comp.visibleErrors || []), super.visibleErrors);\n }\n get errors() {\n const thisErrors = super.errors;\n return this.getComponents()\n .reduce((errors, comp) => errors.concat(comp.errors || []), thisErrors)\n .filter(err => err.level !== 'hidden');\n }\n getValue() {\n return this.data;\n }\n resetValue() {\n super.resetValue();\n this.getComponents().forEach((comp) => comp.resetValue());\n this.setPristine(true);\n }\n get dataReady() {\n return Promise.all(this.getComponents().map((component) => component.dataReady));\n }\n setNestedValue(component, value, flags = {}) {\n component._data = this.componentContext(component);\n if (component.type === 'button') {\n return false;\n }\n if (component.type === 'components') {\n if (component.tree && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n return component.setValue(value, flags);\n }\n else if (value && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {\n flags.noValidate = !flags.dirty;\n flags.resetValue = true;\n return component.setValue(component.defaultValue, flags);\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n return false;\n }\n return this.getComponents().reduce((changed, component) => {\n return this.setNestedValue(component, value, flags, changed) || changed;\n }, false);\n }\n get lazyLoad() {\n var _a;\n return (_a = this.component.lazyLoad) !== null && _a !== void 0 ? _a : false;\n }\n}\nexports[\"default\"] = NestedComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nested/NestedComponent.js?");
|
5707
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Components_1 = __importDefault(__webpack_require__(/*! ../../Components */ \"./lib/cjs/components/Components.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nclass NestedComponent extends Field_1.default {\n static schema(...extend) {\n return Field_1.default.schema({\n tree: false,\n lazyLoad: false,\n }, ...extend);\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.type = 'components';\n this._collapsed = !!this.component.collapsed;\n }\n get defaultSchema() {\n return NestedComponent.schema();\n }\n get schema() {\n const schema = super.schema;\n const components = lodash_1.default.uniqBy(this.getComponents(), 'component.key');\n schema.components = lodash_1.default.map(components, 'schema');\n return schema;\n }\n get collapsed() {\n return this._collapsed;\n }\n collapse(value) {\n const promise = this.redraw();\n if (!value) {\n this.checkValidity(this.data, !this.pristine);\n }\n return promise;\n }\n set collapsed(value) {\n this._collapsed = value;\n this.collapse(value);\n }\n set visible(value) {\n // DO NOT CALL super here. There is an issue where clearOnHide was getting triggered with\n // subcomponents because the \"parentVisible\" flag was set to false when it should really be\n // set to true.\n const visibilityChanged = this._visible !== value;\n this._visible = value;\n const isVisible = this.visible;\n const forceShow = this.shouldForceShow();\n const forceHide = this.shouldForceHide();\n this.components.forEach(component => {\n // Set the parent visibility first since we may have nested components within nested components\n // and they need to be able to determine their visibility based on the parent visibility.\n component.parentVisible = isVisible;\n const conditionallyVisible = component.conditionallyVisible();\n if (forceShow || conditionallyVisible) {\n component.visible = true;\n }\n else if (forceHide || !isVisible || !conditionallyVisible) {\n component.visible = false;\n }\n // If hiding a nested component, clear all errors below.\n if (!component.visible) {\n component.error = '';\n }\n });\n if (visibilityChanged) {\n this.clearOnHide();\n this.redraw();\n }\n }\n get visible() {\n return super.visible;\n }\n set parentVisible(value) {\n super.parentVisible = value;\n this.components.forEach(component => component.parentVisible = this.visible);\n }\n get parentVisible() {\n return super.parentVisible;\n }\n get disabled() {\n return super.disabled;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n this.components.forEach((component) => component.parentDisabled = disabled);\n }\n set parentDisabled(value) {\n super.parentDisabled = value;\n this.components.forEach(component => {\n component.parentDisabled = this.disabled;\n });\n }\n get parentDisabled() {\n return super.parentDisabled;\n }\n get ready() {\n return Promise.all(this.getComponents().map(component => component.ready));\n }\n get currentForm() {\n return super.currentForm;\n }\n set currentForm(instance) {\n super.currentForm = instance;\n this.getComponents().forEach(component => {\n component.currentForm = instance;\n });\n }\n get rowIndex() {\n return this._rowIndex;\n }\n set rowIndex(value) {\n this._rowIndex = value;\n this.eachComponent((component) => {\n component.rowIndex = value;\n });\n }\n componentContext() {\n return this._data;\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n this.eachComponent((component) => {\n component.data = this.componentContext(component);\n });\n }\n getComponents() {\n return this.components || [];\n }\n /**\n * Perform a deep iteration over every component, including those\n * within other container based components.\n *\n * @param {function} fn - Called for every component.\n */\n everyComponent(fn, options = {}) {\n const components = this.getComponents();\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n hasComponent(component) {\n let result = false;\n this.everyComponent((comp) => {\n if (comp === component) {\n result = true;\n return false;\n }\n });\n return result;\n }\n flattenComponents() {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n });\n return result;\n }\n /**\n * Perform an iteration over each component within this container component.\n *\n * @param {function} fn - Called for each component\n */\n eachComponent(fn) {\n lodash_1.default.each(this.getComponents(), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n /**\n * Returns a component provided a key. This performs a deep search within the\n * component tree.\n *\n * @param {string} key - The key of the component to retrieve.\n * @param {function} [fn] - Called with the component once found.\n * @param {string} [originalPath] - The original path to the component.\n * @return {Component} - The component that is located.\n */\n getComponent(path, fn, originalPath) {\n originalPath = originalPath || (0, utils_1.getStringFromComponentPath)(path);\n if (this.componentsMap.hasOwnProperty(originalPath)) {\n if (fn) {\n return fn(this.componentsMap[originalPath]);\n }\n else {\n return this.componentsMap[originalPath];\n }\n }\n path = (0, utils_1.getArrayFromComponentPath)(path);\n const pathStr = originalPath;\n const newPath = lodash_1.default.clone(path);\n let key = newPath.shift();\n const remainingPath = newPath;\n let comp = null;\n let possibleComp = null;\n if (lodash_1.default.isNumber(key)) {\n key = remainingPath.shift();\n }\n if (!lodash_1.default.isString(key)) {\n return comp;\n }\n this.everyComponent((component, components) => {\n const matchPath = component.hasInput && component.path ? pathStr.includes(component.path) : true;\n if (component.component.key === key) {\n possibleComp = component;\n if (matchPath) {\n comp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn, originalPath);\n }\n else if (fn) {\n fn(component, components);\n }\n return false;\n }\n }\n });\n if (!comp) {\n comp = possibleComp;\n }\n return comp;\n }\n /**\n * Return a component provided the Id of the component.\n *\n * @param {string} id - The Id of the component.\n * @param {function} fn - Called with the component once it is retrieved.\n * @return {Object} - The component retrieved.\n */\n getComponentById(id, fn = null) {\n let comp = null;\n this.everyComponent((component, components) => {\n if (component.id === id) {\n comp = component;\n if (fn) {\n fn(component, components);\n }\n return false;\n }\n });\n return comp;\n }\n /**\n * Create a new component and add it to the components array.\n *\n * @param component\n * @param data\n */\n createComponent(component, options, data, before, replacedComp) {\n if (!component) {\n return;\n }\n options = options || this.options;\n data = data || this.data;\n options.parent = this;\n options.parentVisible = this.visible;\n options.root = (options === null || options === void 0 ? void 0 : options.root) || this.root || this;\n options.localRoot = this.localRoot;\n options.skipInit = true;\n if (!(options.display === 'pdf' && this.builderMode)) {\n component.id = (0, utils_1.getRandomComponentId)();\n }\n const comp = Components_1.default.create(component, options, data, true);\n comp.init();\n if (component.internal) {\n return comp;\n }\n if (before) {\n const index = lodash_1.default.findIndex(this.components, { id: before.id });\n if (index !== -1) {\n this.components.splice(index, 0, comp);\n }\n else {\n this.components.push(comp);\n }\n }\n else if (replacedComp) {\n const index = lodash_1.default.findIndex(this.components, { id: replacedComp.id });\n if (index !== -1) {\n this.components[index] = comp;\n }\n else {\n this.components.push(comp);\n }\n }\n else {\n this.components.push(comp);\n }\n return comp;\n }\n getContainer() {\n return this.element;\n }\n get componentComponents() {\n return this.component.components || [];\n }\n get nestedKey() {\n return `nested-${this.key}`;\n }\n get templateName() {\n return 'container';\n }\n init() {\n this.components = this.components || [];\n this.addComponents();\n return super.init();\n }\n /**\n *\n * @param element\n * @param data\n */\n addComponents(data, options) {\n data = data || this.data;\n this.components = this.components || [];\n options = options || this.options;\n if (options.components) {\n this.components = options.components;\n }\n else {\n const components = this.hook('addComponents', this.componentComponents, this) || [];\n components.forEach((component) => this.addComponent(component, data));\n }\n }\n /**\n * Add a new component to the components array.\n *\n * @param {Object} component - The component JSON schema to add.\n * @param {Object} data - The submission data object to house the data for this component.\n * @param {HTMLElement} before - A DOM element to insert this element before.\n * @return {Component} - The created component instance.\n */\n addComponent(component, data = null, before = null, noAdd = false) {\n data = data || this.data;\n this.components = this.components || [];\n component = this.hook('addComponent', component, data, before, noAdd);\n const comp = this.createComponent(component, this.options, data, before ? before : null);\n if (noAdd) {\n return comp;\n }\n return comp;\n }\n beforeFocus() {\n if (this.parent && 'beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n }\n render(children) {\n // If already rendering, don't re-render.\n return super.render(children || this.renderTemplate(this.templateName, {\n children: !this.visible ? '' : this.renderComponents(),\n nestedKey: this.nestedKey,\n collapsed: this.options.pdf ? false : this.collapsed,\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n return this.renderTemplate('components', {\n children,\n components,\n });\n }\n attach(element) {\n const superPromise = super.attach(element);\n this.loadRefs(element, {\n header: 'single',\n collapsed: this.collapsed,\n [this.nestedKey]: 'single',\n });\n let childPromise = Promise.resolve();\n if (this.refs[this.nestedKey]) {\n childPromise = this.attachComponents(this.refs[this.nestedKey]);\n }\n if (!this.visible) {\n this.attachComponentsLogic();\n }\n if (this.component.collapsible && this.refs.header) {\n this.addEventListener(this.refs.header, 'click', () => {\n this.collapsed = !this.collapsed;\n });\n this.addEventListener(this.refs.header, 'keydown', (e) => {\n if (e.keyCode === 13 || e.keyCode === 32) {\n e.preventDefault();\n this.collapsed = !this.collapsed;\n }\n });\n }\n return Promise.all([\n superPromise,\n childPromise,\n ]);\n }\n attachComponentsLogic(components) {\n components = components || this.components;\n lodash_1.default.each(components, (comp) => {\n comp.attachLogic();\n if (lodash_1.default.isFunction(comp.attachComponentsLogic)) {\n comp.attachComponentsLogic();\n }\n });\n }\n attachComponents(element, components, container) {\n components = components || this.components;\n container = container || this.component.components;\n element = this.hook('attachComponents', element, components, container, this);\n if (!element) {\n // Return a non-resolving promise.\n return (new Promise(() => { }));\n }\n let index = 0;\n const promises = [];\n Array.prototype.slice.call(element.children).forEach(child => {\n if (!child.getAttribute('data-noattach') && components[index]) {\n promises.push(components[index].attach(child));\n index++;\n }\n });\n return Promise.all(promises);\n }\n /**\n * Remove a component from the components array and from the children object\n *\n * @param {Component} component - The component to remove from the components.\n * @param {Array<Component>} components - An array of components to remove this component from.\n */\n removeComponent(component, components, all = false) {\n components = components || this.components;\n component.destroy(all);\n lodash_1.default.remove(components, { id: component.id });\n if (this.componentsMap[component.path]) {\n delete this.componentsMap[component.path];\n }\n }\n /**\n * Removes a component provided the API key of that component.\n *\n * @param {string} key - The API key of the component to remove.\n * @param {function} fn - Called once the component is removed.\n * @return {null}\n */\n removeComponentByKey(key, fn = null) {\n const comp = this.getComponent(key, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n /**\n * Removes a component provided the Id of the component.\n *\n * @param {string} id - The Id of the component to remove.\n * @param {function} fn - Called when the component is removed.\n * @return {null}\n */\n removeComponentById(id, fn = null) {\n const comp = this.getComponentById(id, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n updateValue(value, flags = {}) {\n return this.components.reduce((changed, comp) => {\n return comp.updateValue(null, flags) || changed;\n }, super.updateValue(value, flags));\n }\n shouldSkipValidation(data, row, flags) {\n // Nested components with no input should not be validated.\n if (!this.component.input) {\n return true;\n }\n else {\n return super.shouldSkipValidation(data, row, flags);\n }\n }\n checkData(data, flags, row, components) {\n if (this.builderMode) {\n return true;\n }\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n components = components && lodash_1.default.isArray(components) ? components : this.getComponents();\n super.checkData(data, Object.assign({}, flags), row);\n components.forEach((comp) => comp.checkData(data, Object.assign({}, flags), row));\n }\n checkConditions(data, flags, row) {\n // check conditions of parent component first, because it may influence on visibility of it's children\n const check = super.checkConditions(data, flags, row);\n //row data of parent component not always corresponds to row of nested components, use comp.data as row data for children instead\n this.getComponents().forEach(comp => comp.checkConditions(data, flags, comp.data));\n return check;\n }\n clearOnHide(show) {\n super.clearOnHide(show);\n if (this.component.clearOnHide) {\n if (this.allowData && !this.hasValue() && !(this.options.server && !this.visible)) {\n this.dataValue = this.defaultValue;\n }\n if (this.hasValue()) {\n this.restoreComponentsContext();\n }\n }\n this.getComponents().forEach(component => component.clearOnHide(show));\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => component.data = this.dataValue);\n }\n /**\n * Allow components to hook into the next page trigger to perform their own logic.\n *\n * @return {*}\n */\n beforePage(next) {\n return Promise.all(this.getComponents().map((comp) => comp.beforePage(next)));\n }\n /**\n * Allow components to hook into the submission to provide their own async data.\n *\n * @return {*}\n */\n beforeSubmit() {\n return Promise.allSettled(this.getComponents().map((comp) => comp.beforeSubmit()));\n }\n calculateValue(data, flags, row) {\n // Do not iterate into children and calculateValues if this nested component is conditionally hidden.\n if (!this.conditionallyVisible()) {\n return false;\n }\n return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));\n }\n isLastPage() {\n return this.pages.length - 1 === this.page;\n }\n isValid(data, dirty) {\n return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));\n }\n validationProcessor({ scope, data, row, instance }, flags) {\n const { dirty } = flags;\n if (!instance) {\n return;\n }\n instance.checkComponentValidity(data, dirty, row, flags, scope.errors);\n if (instance.processOwnValidation) {\n scope.noRecurse = true;\n }\n }\n /**\n * Perform a validation on all child components of this nested component.\n * @param {*} components\n * @param {*} data\n * @param {*} flags\n * @returns\n */\n validateComponents(components, data, flags = {}) {\n components = components || this.component.components;\n data = data || this.rootValue;\n const { async, dirty, process } = flags;\n const validationProcessorProcess = (context) => this.validationProcessor(context, flags);\n const checkModalProcessorProcess = ({ instance, component, components }) => {\n // If we just validated the last component, and there are errors from our parent, then we need to show a model of those errors.\n if (instance &&\n instance.parent &&\n (component === components[components.length - 1]) &&\n instance.parent.componentModal) {\n instance.parent.checkModal(instance.parent.childErrors, dirty);\n }\n };\n const processorContext = {\n process: process || 'unknown',\n components,\n instances: this.componentsMap,\n data: data,\n scope: { errors: [] },\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n },\n {\n process: checkModalProcessorProcess,\n processSync: checkModalProcessorProcess\n }\n ]\n };\n return async ? (0, process_1.process)(processorContext).then((scope) => scope.errors) : (0, process_1.processSync)(processorContext).errors;\n }\n /**\n * Validate a nested component with data, or its own internal data.\n * @param {*} data\n * @param {*} flags\n * @returns\n */\n validate(data, flags = {}) {\n data = data || this.rootValue;\n return this.validateComponents(this.getComponents().map((component) => component.component), data, flags);\n }\n checkComponentValidity(data, dirty, row, flags = {}, allErrors = []) {\n this.childErrors = [];\n return super.checkComponentValidity(data, dirty, row, flags, allErrors);\n }\n checkValidity(data, dirty, row, silentCheck, childErrors = []) {\n console.log('Deprecation warning: Component.checkValidity() will be deprecated in 6.x version of renderer. Use \"validate\" method instead.');\n childErrors.push(...this.validate(data, { dirty, silentCheck }));\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck }, childErrors) && childErrors.length === 0;\n }\n checkAsyncValidity(data, dirty, row, silentCheck) {\n console.log('Deprecation warning: Component.checkAsyncValidity() will be deprecated in 6.x version of renderer.');\n return this.ready.then(() => {\n return this.validate(data, { dirty, silentCheck, async: true }).then((childErrors) => {\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck, async: true }, childErrors).then((valid) => {\n return valid && childErrors.length === 0;\n });\n });\n });\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n this.getComponents().forEach((comp) => comp.setPristine(pristine));\n }\n get isPristine() {\n return this.pristine && this.getComponents().every((c) => c.isPristine);\n }\n get isDirty() {\n return this.dirty && this.getComponents().every((c) => c.isDirty);\n }\n detach() {\n this.components.forEach(component => {\n component.detach();\n });\n super.detach();\n }\n clear() {\n this.components.forEach(component => {\n component.clear();\n });\n super.clear();\n }\n destroy(all = false) {\n this.destroyComponents(all);\n super.destroy(all);\n }\n destroyComponents(all = false) {\n const components = this.getComponents().slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n this.components = [];\n }\n get visibleErrors() {\n return this.getComponents().reduce((errors, comp) => errors.concat(comp.visibleErrors || []), super.visibleErrors);\n }\n get errors() {\n const thisErrors = super.errors;\n return this.getComponents()\n .reduce((errors, comp) => errors.concat(comp.errors || []), thisErrors)\n .filter(err => err.level !== 'hidden');\n }\n getValue() {\n return this.data;\n }\n resetValue() {\n super.resetValue();\n this.getComponents().forEach((comp) => comp.resetValue());\n this.setPristine(true);\n }\n get dataReady() {\n return Promise.all(this.getComponents().map((component) => component.dataReady));\n }\n setNestedValue(component, value, flags = {}) {\n component._data = this.componentContext(component);\n if (component.type === 'button') {\n return false;\n }\n if (component.type === 'components') {\n if (component.tree && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n return component.setValue(value, flags);\n }\n else if (value && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {\n flags.noValidate = !flags.dirty;\n flags.resetValue = true;\n return component.setValue(component.defaultValue, flags);\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n return false;\n }\n return this.getComponents().reduce((changed, component) => {\n return this.setNestedValue(component, value, flags, changed) || changed;\n }, false);\n }\n get lazyLoad() {\n var _a;\n return (_a = this.component.lazyLoad) !== null && _a !== void 0 ? _a : false;\n }\n}\nexports[\"default\"] = NestedComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nested/NestedComponent.js?");
|
5708
5708
|
|
5709
5709
|
/***/ }),
|
5710
5710
|
|
@@ -5715,7 +5715,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5715
5715
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5716
5716
|
|
5717
5717
|
"use strict";
|
5718
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst NestedDataComponent_1 = __importDefault(__webpack_require__(/*! ../nesteddata/NestedDataComponent */ \"./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js\"));\nclass NestedArrayComponent extends NestedDataComponent_1.default {\n static schema(...extend) {\n return NestedDataComponent_1.default.schema({\n disableAddingRemovingRows: false\n }, ...extend);\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.array];\n }\n componentContext(component) {\n return this.iteratableRows[component.rowIndex].data;\n }\n get iteratableRows() {\n throw new Error('Getter #iteratableRows() is not implemented');\n }\n get rowIndex() {\n return super.rowIndex;\n }\n set rowIndex(value) {\n this._rowIndex = value;\n }\n init() {\n super.init();\n this.prevHasAddButton = this.hasAddButton();\n }\n checkAddButtonChanged() {\n const isAddButton = this.hasAddButton();\n if (isAddButton !== this.prevHasAddButton) {\n this.prevHasAddButton = isAddButton;\n this.redraw();\n }\n }\n checkData(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n this.checkAddButtonChanged();\n return this.processRows('checkData', data, flags, Component_1.default.prototype.checkData.call(this, data, flags, row));\n }\n processRows(method, data, opts, defaultValue, silentCheck) {\n return this.iteratableRows.reduce((valid, row, rowIndex) => {\n if (!(opts === null || opts === void 0 ? void 0 : opts.rowIndex) || (opts === null || opts === void 0 ? void 0 : opts.rowIndex) === rowIndex) {\n return this.processRow(method, data, opts, row.data, row.components, silentCheck) && valid;\n }\n else {\n return valid;\n }\n }, defaultValue);\n }\n validate(data, flags = {}) {\n data = data || this.data;\n return this.validateComponents([this.component], data, flags);\n }\n checkRow(...args) {\n console.log('Deprecation Warning: checkRow method has been replaced with processRow');\n return this.processRow.call(this, ...args);\n }\n processRow(method, data, opts, row, components, silentCheck) {\n if (opts === null || opts === void 0 ? void 0 : opts.isolateRow) {\n silentCheck = true;\n opts.noRefresh = true;\n }\n const valid = lodash_1.default.reduce(components, (valid, component) => component[method](data, opts, row, silentCheck) && valid, true);\n if (opts === null || opts === void 0 ? void 0 : opts.noRefresh) {\n delete opts.noRefresh;\n }\n return valid;\n }\n hasAddButton() {\n const maxLength = lodash_1.default.get(this.component, 'validate.maxLength');\n const conditionalAddButton = lodash_1.default.get(this.component, 'conditionalAddButton');\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n !this.options.preview &&\n (!maxLength || (this.iteratableRows.length < maxLength)) &&\n (!conditionalAddButton || this.evaluate(conditionalAddButton, {\n value: this.dataValue,\n }, 'show'));\n }\n getComponent(path, fn, originalPath) {\n originalPath = originalPath || (0, utils_1.getStringFromComponentPath)(path);\n if (this.componentsMap.hasOwnProperty(originalPath)) {\n if (fn) {\n return fn(this.componentsMap[originalPath]);\n }\n else {\n return this.componentsMap[originalPath];\n }\n }\n path = Array.isArray(path) ? path : [path];\n let key = path.shift();\n const remainingPath = path;\n let result = [];\n let possibleComp = null;\n let comp = null;\n let rowIndex = null;\n if (lodash_1.default.isNumber(key)) {\n rowIndex = key;\n key = remainingPath.shift();\n }\n if (!lodash_1.default.isString(key)) {\n return result;\n }\n this.everyComponent((component, components) => {\n if (component.component.key === key) {\n possibleComp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn, originalPath);\n }\n else if (fn) {\n fn(component, components);\n }\n result = rowIndex !== null ? comp : result.concat(comp || possibleComp);\n }\n }, rowIndex);\n if ((!result || result.length === 0) && possibleComp) {\n result = rowIndex !== null ? possibleComp : [possibleComp];\n }\n return result;\n }\n everyComponent(fn, rowIndex, options) {\n if (lodash_1.default.isObject(rowIndex)) {\n options = rowIndex;\n rowIndex = null;\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n return;\n }\n const components = this.getComponents(rowIndex);\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n getValueAsString(value, options) {\n var _a;\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <thead>\n <tr>\n `);\n (_a = this.component.components) === null || _a === void 0 ? void 0 : _a.forEach((component) => {\n const label = component.label || component.key;\n result += `<th style=\"padding: 5px 10px;\">${label}</th>`;\n });\n result += (`\n </tr>\n </thead>\n <tbody>\n `);\n this.iteratableRows.forEach(({ components }) => {\n result += '<tr>';\n lodash_1.default.each(components, (component) => {\n result += '<td style=\"padding:5px 10px;\">';\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += component.getView(component.dataValue, options);\n }\n result += '</td>';\n });\n result += '</tr>';\n });\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (!value || !value.length) {\n return '';\n }\n return super.getValueAsString(value, options);\n }\n getComponents(rowIndex) {\n if (rowIndex !== undefined && rowIndex !== null) {\n if (!this.iteratableRows[rowIndex]) {\n return [];\n }\n return this.iteratableRows[rowIndex].components;\n }\n return super.getComponents();\n }\n}\nexports[\"default\"] = NestedArrayComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js?");
|
5718
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst NestedDataComponent_1 = __importDefault(__webpack_require__(/*! ../nesteddata/NestedDataComponent */ \"./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js\"));\nclass NestedArrayComponent extends NestedDataComponent_1.default {\n static schema(...extend) {\n return NestedDataComponent_1.default.schema({\n disableAddingRemovingRows: false\n }, ...extend);\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.array];\n }\n componentContext(component) {\n return this.iteratableRows[component.rowIndex].data;\n }\n get iteratableRows() {\n throw new Error('Getter #iteratableRows() is not implemented');\n }\n get rowIndex() {\n return super.rowIndex;\n }\n set rowIndex(value) {\n this._rowIndex = value;\n }\n init() {\n super.init();\n this.prevHasAddButton = this.hasAddButton();\n }\n checkAddButtonChanged() {\n const isAddButton = this.hasAddButton();\n if (isAddButton !== this.prevHasAddButton) {\n this.prevHasAddButton = isAddButton;\n this.redraw();\n }\n }\n checkData(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n this.checkAddButtonChanged();\n return this.processRows('checkData', data, flags, Component_1.default.prototype.checkData.call(this, data, flags, row));\n }\n processRows(method, data, opts, defaultValue, silentCheck) {\n return this.iteratableRows.reduce((valid, row, rowIndex) => {\n if (!(opts === null || opts === void 0 ? void 0 : opts.rowIndex) || (opts === null || opts === void 0 ? void 0 : opts.rowIndex) === rowIndex) {\n return this.processRow(method, data, opts, row.data, row.components, silentCheck) && valid;\n }\n else {\n return valid;\n }\n }, defaultValue);\n }\n validate(data, flags = {}) {\n data = data || this.data;\n return this.validateComponents([this.component], data, flags);\n }\n checkRow(...args) {\n console.log('Deprecation Warning: checkRow method has been replaced with processRow');\n return this.processRow.call(this, ...args);\n }\n processRow(method, data, opts, row, components, silentCheck) {\n if (opts === null || opts === void 0 ? void 0 : opts.isolateRow) {\n silentCheck = true;\n opts.noRefresh = true;\n }\n const valid = lodash_1.default.reduce(components, (valid, component) => component[method](data, opts, row, silentCheck) && valid, true);\n if (opts === null || opts === void 0 ? void 0 : opts.noRefresh) {\n delete opts.noRefresh;\n }\n return valid;\n }\n hasAddButton() {\n const maxLength = lodash_1.default.get(this.component, 'validate.maxLength');\n const conditionalAddButton = lodash_1.default.get(this.component, 'conditionalAddButton');\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n !this.options.preview &&\n (!maxLength || (this.iteratableRows.length < maxLength)) &&\n (!conditionalAddButton || this.evaluate(conditionalAddButton, {\n value: this.dataValue,\n }, 'show'));\n }\n getComponent(path, fn, originalPath) {\n originalPath = originalPath || (0, utils_1.getStringFromComponentPath)(path);\n if (this.componentsMap.hasOwnProperty(originalPath)) {\n if (fn) {\n return fn(this.componentsMap[originalPath]);\n }\n else {\n return this.componentsMap[originalPath];\n }\n }\n path = Array.isArray(path) ? path : [path];\n let key = path.shift();\n const remainingPath = path;\n let result = [];\n let possibleComp = null;\n let comp = null;\n let rowIndex = null;\n if (lodash_1.default.isNumber(key)) {\n rowIndex = key;\n key = remainingPath.shift();\n }\n if (!lodash_1.default.isString(key)) {\n return result;\n }\n this.everyComponent((component, components) => {\n if (component.component.key === key) {\n possibleComp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn, originalPath);\n }\n else if (fn) {\n fn(component, components);\n }\n result = rowIndex !== null ? comp : result.concat(comp || possibleComp);\n }\n }, rowIndex);\n if ((!result || result.length === 0) && possibleComp) {\n result = rowIndex !== null ? possibleComp : [possibleComp];\n }\n return result;\n }\n everyComponent(fn, rowIndex, options = {}) {\n if (lodash_1.default.isObject(rowIndex)) {\n options = rowIndex;\n rowIndex = null;\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n return;\n }\n const components = this.getComponents(rowIndex);\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n getValueAsString(value, options) {\n var _a;\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <thead>\n <tr>\n `);\n (_a = this.component.components) === null || _a === void 0 ? void 0 : _a.forEach((component) => {\n const label = component.label || component.key;\n result += `<th style=\"padding: 5px 10px;\">${label}</th>`;\n });\n result += (`\n </tr>\n </thead>\n <tbody>\n `);\n this.iteratableRows.forEach(({ components }) => {\n result += '<tr>';\n lodash_1.default.each(components, (component) => {\n result += '<td style=\"padding:5px 10px;\">';\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += component.getView(component.dataValue, options);\n }\n result += '</td>';\n });\n result += '</tr>';\n });\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (!value || !value.length) {\n return '';\n }\n return super.getValueAsString(value, options);\n }\n getComponents(rowIndex) {\n if (rowIndex !== undefined && rowIndex !== null) {\n if (!this.iteratableRows[rowIndex]) {\n return [];\n }\n return this.iteratableRows[rowIndex].components;\n }\n return super.getComponents();\n }\n}\nexports[\"default\"] = NestedArrayComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js?");
|
5719
5719
|
|
5720
5720
|
/***/ }),
|
5721
5721
|
|
@@ -5726,7 +5726,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5726
5726
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5727
5727
|
|
5728
5728
|
"use strict";
|
5729
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst NestedComponent_1 = __importDefault(__webpack_require__(/*! ../nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nclass NestedDataComponent extends NestedComponent_1.default {\n hasChanged(newValue, oldValue) {\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n static savedValueTypes(schema) {\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.object];\n }\n get allowData() {\n return true;\n }\n get emptyValue() {\n return {};\n }\n componentContext() {\n return this.dataValue;\n }\n getValueAsString(value, options) {\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n if (options === null || options === void 0 ? void 0 : options.modalPreview) {\n delete options.modalPreview;\n return this.getDataValueAsTable(value, options);\n }\n return '[Complex Data]';\n }\n getDataValueAsTable(value, options) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n const htmlTagRegExp = new RegExp('<(.*?)>');\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n const componentValue = component.getView(component.dataValue, options);\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.component && component.component.inputFormat === 'html' && htmlTagRegExp.test(componentValue)\n ? componentValue\n : `<input type=\"text\" value=\"${componentValue.replace(/\"/g, '"')}\" readonly/>`}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n everyComponent(fn, options) {\n if (options === null || options === void 0 ? void 0 : options.email) {\n if (options.fromRoot) {\n delete options.fromRoot;\n }\n else {\n return;\n }\n }\n return super.everyComponent(fn, options);\n }\n /**\n * Get the value of this component.\n *\n * @returns {*}\n */\n getValue() {\n return this.dataValue;\n }\n updateValue(value, flags = {}) {\n // Intentionally skip over nested component updateValue method to keep\n // recursive update from occurring with sub components.\n return Component_1.default.prototype.updateValue.call(this, value, flags);\n }\n setValue(value, flags = {}) {\n let changed = false;\n const hasValue = this.hasValue();\n if (hasValue && lodash_1.default.isEmpty(this.dataValue)) {\n flags.noValidate = true;\n }\n if (!value || !lodash_1.default.isObject(value) || !hasValue) {\n changed = true;\n this.dataValue = this.defaultValue;\n }\n changed = super.setValue(value, flags) || changed;\n this.updateOnChange(flags, changed);\n return changed;\n }\n}\nexports[\"default\"] = NestedDataComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js?");
|
5729
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst NestedComponent_1 = __importDefault(__webpack_require__(/*! ../nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nclass NestedDataComponent extends NestedComponent_1.default {\n hasChanged(newValue, oldValue) {\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n static savedValueTypes(schema) {\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.object];\n }\n get allowData() {\n return true;\n }\n get emptyValue() {\n return {};\n }\n componentContext() {\n return this.dataValue;\n }\n getValueAsString(value, options) {\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n if (options === null || options === void 0 ? void 0 : options.modalPreview) {\n delete options.modalPreview;\n return this.getDataValueAsTable(value, options);\n }\n return '[Complex Data]';\n }\n getDataValueAsTable(value, options) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n const htmlTagRegExp = new RegExp('<(.*?)>');\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n const componentValue = component.getView(component.dataValue, options);\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.component && component.component.inputFormat === 'html' && htmlTagRegExp.test(componentValue)\n ? componentValue\n : `<input type=\"text\" value=\"${componentValue.replace(/\"/g, '"')}\" readonly/>`}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n everyComponent(fn, options = {}) {\n if (options === null || options === void 0 ? void 0 : options.email) {\n if (options.fromRoot) {\n delete options.fromRoot;\n }\n else {\n return;\n }\n }\n return super.everyComponent(fn, options);\n }\n /**\n * Get the value of this component.\n *\n * @returns {*}\n */\n getValue() {\n return this.dataValue;\n }\n updateValue(value, flags = {}) {\n // Intentionally skip over nested component updateValue method to keep\n // recursive update from occurring with sub components.\n return Component_1.default.prototype.updateValue.call(this, value, flags);\n }\n setValue(value, flags = {}) {\n let changed = false;\n const hasValue = this.hasValue();\n if (hasValue && lodash_1.default.isEmpty(this.dataValue)) {\n flags.noValidate = true;\n }\n if (!value || !lodash_1.default.isObject(value) || !hasValue) {\n changed = true;\n this.dataValue = this.defaultValue;\n }\n changed = super.setValue(value, flags) || changed;\n this.updateOnChange(flags, changed);\n return changed;\n }\n}\nexports[\"default\"] = NestedDataComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nesteddata/NestedDataComponent.js?");
|
5730
5730
|
|
5731
5731
|
/***/ }),
|
5732
5732
|
|
@@ -6650,7 +6650,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6650
6650
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
6651
6651
|
|
6652
6652
|
"use strict";
|
6653
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass HTMLComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'HTML',\n type: 'htmlelement',\n tag: 'p',\n attrs: [],\n content: '',\n input: false,\n persistent: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'HTML Element',\n group: 'layout',\n icon: 'code',\n weight: 0,\n documentation: '/userguide/form-building/layout-components#html-element',\n showPreview: false,\n schema: HTMLComponent.schema()\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return HTMLComponent.schema();\n }\n get content() {\n if (this.builderMode) {\n return this.component.content;\n }\n // i18n returns error exactly with word 'select', spaces will be trimmed\n if (this.component.content.replace(/(<(\\/?[^>]+)>)/g, '').trim() === 'select') {\n return ` ${this.component.content} `;\n }\n const submission = lodash_1.default.get(this.root, 'submission', {});\n const content = this.component.content ? this.interpolate(this.sanitize(this.component.content, this.shouldSanitizeValue), {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n }) : '';\n return content;\n }\n get singleTags() {\n return ['br', 'img', 'hr'];\n }\n checkRefreshOn(changed) {\n super.checkRefreshOn(changed);\n if (!this.builderMode && this.component.refreshOnChange && this.element &&\n !lodash_1.default.isUndefined(changed) && ((lodash_1.default.isBoolean(changed) && changed) || !lodash_1.default.isEmpty(changed)) &&\n this.conditionallyVisible(this.data, this.row)) {\n this.setContent(this.element, this.renderContent());\n }\n }\n renderContent() {\n const submission = lodash_1.default.get(this.root, 'submission', {});\n return this.renderTemplate('html', {\n component: this.component,\n tag: this.component.tag,\n attrs: (this.component.attrs || []).map((attr) => {\n return {\n attr: attr.attr,\n value: this.interpolate(attr.value, {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n })\n };\n }),\n content: this.content,\n singleTags: this.singleTags,\n });\n }\n render() {\n return super.render(this.renderContent());\n }\n get dataReady() {\n var _a;\n return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submissionReady) || Promise.resolve();\n }\n attach(element) {\n this.loadRefs(element, { html: 'single' });\n this.dataReady.then(() => {\n if (this.
|
6653
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass HTMLComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'HTML',\n type: 'htmlelement',\n tag: 'p',\n attrs: [],\n content: '',\n input: false,\n persistent: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'HTML Element',\n group: 'layout',\n icon: 'code',\n weight: 0,\n documentation: '/userguide/form-building/layout-components#html-element',\n showPreview: false,\n schema: HTMLComponent.schema()\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return HTMLComponent.schema();\n }\n get content() {\n if (this.builderMode) {\n return this.component.content;\n }\n // i18n returns error exactly with word 'select', spaces will be trimmed\n if (this.component.content.replace(/(<(\\/?[^>]+)>)/g, '').trim() === 'select') {\n return ` ${this.component.content} `;\n }\n const submission = lodash_1.default.get(this.root, 'submission', {});\n const content = this.component.content ? this.interpolate(this.sanitize(this.component.content, this.shouldSanitizeValue), {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n }) : '';\n return content;\n }\n get singleTags() {\n return ['br', 'img', 'hr'];\n }\n checkRefreshOn(changed) {\n super.checkRefreshOn(changed);\n if (!this.builderMode && this.component.refreshOnChange && this.element &&\n !lodash_1.default.isUndefined(changed) && ((lodash_1.default.isBoolean(changed) && changed) || !lodash_1.default.isEmpty(changed)) &&\n this.conditionallyVisible(this.data, this.row)) {\n this.setContent(this.element, this.renderContent());\n }\n }\n renderContent() {\n const submission = lodash_1.default.get(this.root, 'submission', {});\n return this.renderTemplate('html', {\n component: this.component,\n tag: this.component.tag,\n attrs: (this.component.attrs || []).map((attr) => {\n return {\n attr: attr.attr,\n value: this.interpolate(attr.value, {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n })\n };\n }),\n content: this.content,\n singleTags: this.singleTags,\n });\n }\n render() {\n return super.render(this.renderContent());\n }\n get dataReady() {\n var _a;\n return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submissionReady) || Promise.resolve();\n }\n attach(element) {\n this.loadRefs(element, { html: 'single' });\n this.dataReady.then(() => {\n if (this.refs.html) {\n this.setContent(this.refs.html, this.content);\n }\n });\n return super.attach(element);\n }\n}\nexports[\"default\"] = HTMLComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/html/HTML.js?");
|
6654
6654
|
|
6655
6655
|
/***/ }),
|
6656
6656
|
|
@@ -6980,7 +6980,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6980
6980
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
6981
6981
|
|
6982
6982
|
"use strict";
|
6983
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst ChoicesWrapper_1 = __importDefault(__webpack_require__(/*! ../../utils/ChoicesWrapper */ \"./lib/cjs/utils/ChoicesWrapper.js\"));\nclass SelectComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'select',\n label: 'Select',\n key: 'select',\n idPath: 'id',\n data: {\n values: [{ label: '', value: '' }],\n json: '',\n url: '',\n resource: '',\n custom: ''\n },\n clearOnRefresh: false,\n limit: 100,\n valueProperty: '',\n lazyLoad: true,\n filter: '',\n searchEnabled: true,\n searchDebounce: 0.3,\n searchField: '',\n minSearch: 0,\n readOnlyValue: false,\n selectFields: '',\n selectThreshold: 0.3,\n uniqueOptions: false,\n tableView: true,\n fuseOptions: {\n include: 'score',\n threshold: 0.3,\n },\n indexeddb: {\n filter: {}\n },\n customOptions: {},\n useExactSearch: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Select',\n group: 'basic',\n icon: 'th-list',\n weight: 70,\n documentation: '/userguide/form-building/form-components#select',\n schema: SelectComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return SelectComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const valueComp = Object.assign(Object.assign({}, classComp), { type: 'select' });\n if ((0, utils_1.isSelectResourceWithObjectValue)(classComp)) {\n valueComp.reference = false;\n valueComp.onSetItems = `\n var templateKeys = utils.getItemTemplateKeys(component.template) || [];\n items = _.map(items || [], i => {\n var item = {};\n _.each(templateKeys, k => _.set(item, k, _.get(i, k)));\n return item;\n })\n `;\n }\n return valueComp;\n } });\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType, reference } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (reference) {\n return [object];\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n // Keep track of the select options.\n this.selectOptions = [];\n if (this.itemsFromUrl) {\n this.isFromSearch = false;\n this.searchServerCount = null;\n this.defaultServerCount = null;\n this.isScrollLoading = false;\n this.searchDownloadedResources = [];\n this.defaultDownloadedResources = [];\n }\n // If this component has been activated.//\n this.activated = false;\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.shouldPositionDropdown = this.hasDataGridAncestor();\n if (this.isHtmlRenderMode()) {\n this.activate();\n }\n // Get the template keys for this select component.\n this.getTemplateKeys();\n }\n get dataReady() {\n // If the root submission has been set, and we are still not attached, then assume\n // that our data is ready.\n if (this.root &&\n this.root.submissionSet &&\n !this.attached) {\n return Promise.resolve();\n }\n return this.itemsLoaded;\n }\n get defaultSchema() {\n return SelectComponent.schema();\n }\n get emptyValue() {\n if (this.component.multiple) {\n return [];\n }\n // if select has JSON data source type, we are defining if empty value would be an object or a string by checking JSON's first item\n if (this.component.dataSrc === 'json' && this.component.data.json) {\n const firstItem = this.component.data.json[0];\n let firstValue;\n if (this.valueProperty) {\n firstValue = lodash_1.default.get(firstItem, this.valueProperty);\n }\n else {\n firstValue = firstItem;\n }\n if (firstValue && typeof firstValue === 'string') {\n return '';\n }\n else {\n return {};\n }\n }\n if (this.valueProperty) {\n return '';\n }\n return {};\n }\n get valueProperty() {\n if (this.component.valueProperty) {\n return this.component.valueProperty;\n }\n // Force values datasource to use values without actually setting it on the component settings.\n if (this.component.dataSrc === 'values') {\n return 'value';\n }\n return '';\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'select';\n info.changeEvent = 'change';\n return info;\n }\n get isSelectResource() {\n return this.component.dataSrc === 'resource';\n }\n get itemsFromUrl() {\n return this.isSelectResource || this.isSelectURL;\n }\n get isInfiniteScrollProvided() {\n return this.itemsFromUrl;\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.parentDisabled;\n }\n get shouldInitialLoad() {\n if (this.component.widget === 'html5' &&\n this.isEntireObjectDisplay() &&\n this.component.searchField &&\n this.dataValue) {\n return false;\n }\n return super.shouldLoad;\n }\n get selectData() {\n return this.component.selectData || super.selectData;\n }\n isEntireObjectDisplay() {\n return this.component.dataSrc === 'resource' && this.valueProperty === 'data';\n }\n selectValueAndLabel(data) {\n const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : data, value)\n };\n }\n itemTemplate(data, value) {\n if (!lodash_1.default.isNumber(data) && lodash_1.default.isEmpty(data)) {\n return '';\n }\n // If they wish to show the value in read only mode, then just return the itemValue here.\n if (this.options.readOnly && this.component.readOnlyValue) {\n return this.itemValue(data);\n }\n // Perform a fast interpretation if we should not use the template.\n if (data && !this.component.template) {\n const itemLabel = data.label || data;\n const value = (typeof itemLabel === 'string') ? this.t(itemLabel, { _userInput: true }) : itemLabel;\n return this.sanitize(value, this.shouldSanitizeValue);\n }\n if (this.component.multiple && lodash_1.default.isArray(this.dataValue) ? this.dataValue.find((val) => value === val) : (this.dataValue === value)) {\n const selectData = this.selectData;\n if (selectData) {\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n if (!this.templateData || !this.templateData[templateValue]) {\n this.getOptionTemplate(data, value);\n }\n if (this.component.multiple) {\n if (selectData[templateValue]) {\n data = selectData[templateValue];\n }\n }\n else {\n data = selectData;\n }\n }\n }\n if (typeof data === 'string' || typeof data === 'number') {\n return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue);\n }\n if (Array.isArray(data)) {\n return data.map((val) => {\n if (typeof val === 'string' || typeof val === 'number') {\n return this.sanitize(this.t(val, { _userInput: true }), this.shouldSanitizeValue);\n }\n return val;\n });\n }\n if (data.data) {\n // checking additional fields in the template for the selected Entire Object option\n const hasNestedFields = /item\\.data\\.\\w*/g.test(this.component.template);\n data.data = this.isEntireObjectDisplay() && lodash_1.default.isObject(data.data) && !hasNestedFields\n ? JSON.stringify(data.data)\n : data.data;\n }\n return super.itemTemplate(data, value);\n }\n /**\n * Adds an option to the select dropdown.\n *\n * @param value\n * @param label\n */\n addOption(value, label, attrs = {}, id = (0, utils_1.getRandomComponentId)()) {\n if (lodash_1.default.isNil(label))\n return;\n const idPath = this.component.idPath\n ? this.component.idPath.split('.').reduceRight((obj, key) => ({ [key]: obj }), id)\n : {};\n const option = Object.assign({ value: this.getOptionValue(value), label }, idPath);\n const skipOption = this.component.uniqueOptions\n ? !!this.selectOptions.find((selectOption) => lodash_1.default.isEqual(selectOption.value, option.value))\n : false;\n if (skipOption) {\n return;\n }\n if (value) {\n this.selectOptions.push(option);\n }\n if (this.refs.selectContainer && (this.component.widget === 'html5')) {\n // Replace an empty Object value to an empty String.\n if (option.value && lodash_1.default.isObject(option.value) && lodash_1.default.isEmpty(option.value)) {\n option.value = '';\n }\n // Add element to option so we can reference it later.\n const div = document.createElement('div');\n div.innerHTML = this.sanitize(this.renderTemplate('selectOption', {\n selected: lodash_1.default.isEqual(this.getOptionValue(this.dataValue), option.value),\n option,\n attrs,\n id,\n useId: (this.valueProperty === '' || this.isEntireObjectDisplay()) && lodash_1.default.isObject(value) && id,\n }), this.shouldSanitizeValue).trim();\n option.element = div.firstChild;\n this.refs.selectContainer.appendChild(option.element);\n }\n }\n addValueOptions(items) {\n items = items || [];\n let added = false;\n let data = this.dataValue;\n // preset submission value with value property before request.\n if (this.options.pdf && !items.length && this.component.dataSrc === 'url' && this.valueProperty) {\n data = Array.isArray(data)\n ? data.map(item => lodash_1.default.set({}, this.valueProperty, item))\n : lodash_1.default.set({}, this.valueProperty, data);\n }\n if (!this.selectOptions.length) {\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(data) && this.component.multiple ? data : [data];\n added = this.addCurrentChoices(currentChoices, items);\n if (!added && !this.component.multiple) {\n this.addPlaceholder();\n }\n }\n return added;\n }\n disableInfiniteScroll() {\n if (!this.downloadedResources) {\n return;\n }\n this.downloadedResources.serverCount = this.downloadedResources.length;\n this.serverCount = this.downloadedResources.length;\n }\n /* eslint-disable max-statements */\n setItems(items, fromSearch) {\n var _a, _b;\n this.selectItems = items;\n // If the items is a string, then parse as JSON.\n if (typeof items == 'string') {\n try {\n items = JSON.parse(items);\n }\n catch (err) {\n console.warn(err.message);\n items = [];\n }\n }\n // Allow js processing (needed for form builder)\n if (this.component.onSetItems) {\n const newItems = typeof this.component.onSetItems === 'function'\n ? this.component.onSetItems(this, items)\n : this.evaluate(this.component.onSetItems, { items: items }, 'items');\n if (newItems) {\n items = newItems;\n }\n }\n if (!this.choices && this.refs.selectContainer) {\n this.empty(this.refs.selectContainer);\n }\n // If they provided select values, then we need to get them instead.\n if (this.component.selectValues) {\n items = lodash_1.default.get(items, this.component.selectValues, items) || [];\n }\n let areItemsEqual;\n if (this.itemsFromUrl) {\n areItemsEqual = this.isSelectURL ? lodash_1.default.isEqual(items, this.downloadedResources) : false;\n const areItemsEnded = this.component.limit > items.length;\n const areItemsDownloaded = areItemsEqual\n && this.downloadedResources\n && this.downloadedResources.length === items.length;\n if (areItemsEnded) {\n this.disableInfiniteScroll();\n }\n else if (areItemsDownloaded) {\n this.selectOptions = [];\n }\n else {\n this.serverCount = items.serverCount;\n }\n }\n if (this.isScrollLoading && items) {\n if (!areItemsEqual) {\n this.downloadedResources = this.downloadedResources\n ? this.downloadedResources.concat(items)\n : items;\n }\n this.downloadedResources.serverCount = items.serverCount || this.downloadedResources.serverCount;\n }\n else {\n this.downloadedResources = items || [];\n this.selectOptions = [];\n // If there is new select option with same id as already selected, set the new one\n if (!lodash_1.default.isEmpty(this.dataValue) && this.component.idPath) {\n const selectedOptionId = lodash_1.default.get(this.dataValue, this.component.idPath, null);\n const newOptionWithSameId = !lodash_1.default.isNil(selectedOptionId) && items.find(item => {\n const itemId = lodash_1.default.get(item, this.component.idPath);\n return itemId === selectedOptionId;\n });\n if (newOptionWithSameId) {\n this.setValue(newOptionWithSameId);\n }\n }\n }\n // Add the value options.\n if (!fromSearch) {\n this.addValueOptions(items);\n }\n if (this.component.widget === 'html5' && !this.component.placeholder) {\n this.addOption(null, '');\n }\n // Iterate through each of the items.\n lodash_1.default.each(items, (item, index) => {\n // preventing references of the components inside the form to the parent form when building forms\n if (this.root && this.root.options.editForm && this.root.options.editForm._id && this.root.options.editForm._id === item._id)\n return;\n const itemValueAndLabel = this.selectValueAndLabel(item);\n this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, lodash_1.default.get(item, this.component.idPath, String(index)));\n });\n if (this.choices) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n else if (this.loading) {\n // Re-attach select input.\n // this.appendTo(this.refs.input[0], this.selectContainer);\n }\n // We are no longer loading.\n this.isScrollLoading = false;\n this.loading = false;\n const searching = fromSearch && ((_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.isFocussed);\n if (!searching) {\n // If a value is provided, then select it.\n if (!this.isEmpty() || this.isRemoveButtonPressed) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else if (this.shouldAddDefaultValue && !this.options.readOnly) {\n // If a default value is provided then select it.\n const defaultValue = this.defaultValue;\n if (!this.isEmpty(defaultValue)) {\n this.setValue(defaultValue);\n }\n }\n }\n // Say we are done loading the items.\n this.itemsLoadedResolve();\n }\n getSingleItemValueForHTMLMode(data) {\n var _a;\n const option = (_a = this.selectOptions) === null || _a === void 0 ? void 0 : _a.find(({ value }) => lodash_1.default.isEqual(value, data));\n if (option) {\n return option.label || data;\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (!this.isHtmlRenderMode()) {\n return super.itemValueForHTMLMode(value);\n }\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item)\n ? this.itemValueForHTMLMode(item)\n : this.getSingleItemValueForHTMLMode(item));\n return values.join(', ');\n }\n return this.getSingleItemValueForHTMLMode(value);\n }\n /* eslint-enable max-statements */\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n get loadingError() {\n return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError;\n }\n loadItems(url, search, headers, options, method, body) {\n options = options || {};\n // See if we should load items or not.\n if (!this.shouldLoad || (!this.itemsFromUrl && this.options.readOnly)) {\n this.isScrollLoading = false;\n this.loading = false;\n this.itemsLoadedResolve();\n return;\n }\n // See if they have not met the minimum search requirements.\n const minSearch = parseInt(this.component.minSearch, 10);\n if (this.component.searchField &&\n (minSearch > 0) &&\n (!search || (search.length < minSearch))) {\n // Set empty items.\n return this.setItems([]);\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n const query = this.component.disableLimit ? {} : {\n limit,\n skip,\n };\n // Allow for url interpolation.\n url = this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n });\n // Add search capability.\n if (this.component.searchField && search) {\n const searchValue = Array.isArray(search)\n ? search.join(',')\n : typeof search === 'object'\n ? JSON.stringify(search)\n : search;\n query[this.component.searchField] = this.component.searchField.endsWith('__regex')\n ? lodash_1.default.escapeRegExp(searchValue)\n : searchValue;\n }\n // If they wish to return only some fields.\n if (this.component.selectFields) {\n query.select = this.component.selectFields;\n }\n // Add sort capability\n if (this.component.sort) {\n query.sort = this.component.sort;\n }\n if (!lodash_1.default.isEmpty(query)) {\n // Add the query string.\n url += (!url.includes('?') ? '?' : '&') + Formio_1.Formio.serialize(query, (item) => this.interpolate(item));\n }\n // Add filter capability\n if (this.component.filter) {\n url += (!url.includes('?') ? '?' : '&') + this.interpolate(this.component.filter);\n }\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response, !!search);\n })\n .catch((err) => {\n if (this.itemsFromUrl) {\n this.setItems([]);\n this.disableInfiniteScroll();\n }\n this.isScrollLoading = false;\n this.handleLoadingError(err);\n });\n }\n handleLoadingError(err) {\n this.loading = false;\n if (err.networkError) {\n this.networkError = true;\n }\n this.itemsLoadedResolve();\n this.emit('componentError', {\n component: this.component,\n message: err.toString(),\n });\n console.warn(`Unable to load resources for ${this.key}`);\n }\n /**\n * Get the request headers for this select dropdown.\n */\n get requestHeaders() {\n // Create the headers object.\n const headers = new Formio_1.Formio.Headers();\n // Add custom headers to the url.\n if (this.component.data && this.component.data.headers) {\n try {\n lodash_1.default.each(this.component.data.headers, (header) => {\n if (header.key) {\n headers.set(header.key, this.interpolate(header.value));\n }\n });\n }\n catch (err) {\n console.warn(err.message);\n }\n }\n return headers;\n }\n getCustomItems() {\n const customItems = this.evaluate(this.component.data.custom, {\n values: []\n }, 'values');\n this.asyncValues = (0, utils_1.isPromise)(customItems);\n return customItems;\n }\n asyncCustomValues() {\n if (!lodash_1.default.isBoolean(this.asyncValues)) {\n this.getCustomItems();\n }\n return this.asyncValues;\n }\n updateCustomItems(forceUpdate) {\n if (this.asyncCustomValues()) {\n if (!forceUpdate && !this.active) {\n this.itemsLoadedResolve();\n return;\n }\n this.loading = true;\n this.getCustomItems()\n .then(items => {\n this.loading = false;\n this.setItems(items || []);\n })\n .catch(err => {\n this.handleLoadingError(err);\n });\n }\n else {\n this.setItems(this.getCustomItems() || []);\n }\n }\n isEmpty(value = this.dataValue) {\n return super.isEmpty(value) || value === undefined;\n }\n refresh(value, { instance }) {\n if (this.component.clearOnRefresh && (instance && !instance.pristine)) {\n this.setValue(this.emptyValue);\n }\n this.updateItems(null, true);\n }\n get additionalResourcesAvailable() {\n return lodash_1.default.isNil(this.serverCount) || (this.serverCount > this.downloadedResources.length);\n }\n get serverCount() {\n if (this.isFromSearch) {\n return this.searchServerCount;\n }\n return this.defaultServerCount;\n }\n set serverCount(value) {\n if (this.isFromSearch) {\n this.searchServerCount = value;\n }\n else {\n this.defaultServerCount = value;\n }\n }\n get downloadedResources() {\n if (this.isFromSearch) {\n return this.searchDownloadedResources;\n }\n return this.defaultDownloadedResources;\n }\n set downloadedResources(value) {\n if (this.isFromSearch) {\n this.searchDownloadedResources = value;\n }\n else {\n this.defaultDownloadedResources = value;\n }\n }\n addPlaceholder() {\n if (!this.component.placeholder) {\n return;\n }\n this.addOption('', this.component.placeholder, { placeholder: true });\n }\n /**\n * Activate this select control.\n */\n activate() {\n if (this.loading || !this.active) {\n this.setLoadingItem();\n }\n if (this.active) {\n return;\n }\n this.activated = true;\n this.triggerUpdate();\n }\n setLoadingItem(addToCurrentList = false) {\n if (this.choices) {\n if (addToCurrentList) {\n this.choices.setChoices([{\n value: `${this.id}-loading`,\n label: 'Loading...',\n disabled: true,\n }], 'value', 'label');\n }\n else {\n this.choices.setChoices([{\n value: '',\n label: `<i class=\"${this.iconClass('refresh')}\" style=\"font-size:1.3em;\"></i>`,\n disabled: true,\n }], 'value', 'label', true);\n }\n }\n else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') {\n this.addOption('', this.t('loading...'));\n }\n }\n get active() {\n return !this.component.lazyLoad || this.activated;\n }\n render() {\n const info = this.inputInfo;\n info.attr = info.attr || {};\n info.multiple = this.component.multiple;\n return super.render(this.wrapElement(this.renderTemplate('select', {\n input: info,\n selectOptions: '',\n index: null,\n })));\n }\n wrapElement(element) {\n return this.component.addResource && !this.options.readOnly\n ? (this.renderTemplate('resourceAdd', {\n element\n }))\n : element;\n }\n choicesOptions() {\n const useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true;\n const placeholderValue = this.t(this.component.placeholder, { _userInput: true });\n let customOptions = this.component.customOptions || {};\n if (typeof customOptions == 'string') {\n try {\n customOptions = JSON.parse(customOptions);\n }\n catch (err) {\n console.warn(err.message);\n customOptions = {};\n }\n }\n const commonFuseOptions = {\n maxPatternLength: 1000,\n distance: 1000,\n };\n return Object.assign({ removeItemButton: this.component.disabled ? false : lodash_1.default.get(this.component, 'removeItemButton', true), itemSelectText: '', classNames: {\n containerOuter: 'choices form-group formio-choices',\n containerInner: this.transform('class', 'form-control ui fluid selection dropdown')\n }, addItemText: false, allowHTML: true, placeholder: !!this.component.placeholder, placeholderValue: placeholderValue, noResultsText: this.t('No results found'), noChoicesText: this.t('No choices to choose from'), searchPlaceholderValue: this.t('Type to search'), shouldSort: false, position: (this.component.dropdown || 'auto'), searchEnabled: useSearch, searchChoices: !this.component.searchField, searchFields: lodash_1.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch\n ? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false }, customOptions);\n }\n /* eslint-disable max-statements */\n attach(element) {\n var _a, _b, _c;\n const superAttach = super.attach(element);\n this.loadRefs(element, {\n selectContainer: 'single',\n addResource: 'single',\n autocompleteInput: 'single'\n });\n //enable autocomplete for select\n const autocompleteInput = this.refs.autocompleteInput;\n if (autocompleteInput) {\n this.addEventListener(autocompleteInput, 'change', (event) => {\n this.setValue(event.target.value);\n });\n }\n const input = this.refs.selectContainer;\n if (!input) {\n return;\n }\n this.addEventListener(input, this.inputInfo.changeEvent, () => this.updateValue(null, {\n modified: true\n }));\n this.attachRefreshOnBlur();\n if (this.component.widget === 'html5') {\n this.addFocusBlurEvents(input);\n this.triggerUpdate(null, true);\n if (this.visible) {\n this.setItems(this.selectItems || []);\n }\n this.focusableElement = input;\n if (this.component.dataSrc === 'custom') {\n this.addEventListener(input, 'focus', () => this.updateCustomItems());\n }\n this.addEventListener(input, 'keydown', (event) => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n this.setValue(this.emptyValue);\n }\n });\n return;\n }\n const tabIndex = input.tabIndex;\n this.addPlaceholder();\n if (this.i18next) {\n input.setAttribute('dir', this.i18next.dir());\n }\n if ((_c = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.containerOuter) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.parentNode) {\n this.choices.destroy();\n }\n const choicesOptions = this.choicesOptions();\n if (ChoicesWrapper_1.default) {\n this.choices = new ChoicesWrapper_1.default(input, choicesOptions);\n if (this.selectOptions && this.selectOptions.length) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n if (this.component.multiple) {\n this.focusableElement = this.choices.input.element;\n }\n else {\n this.focusableElement = this.choices.containerInner.element;\n this.choices.containerOuter.element.setAttribute('tabIndex', '-1');\n this.addEventListener(this.choices.containerOuter.element, 'focus', () => this.focusableElement.focus());\n }\n Input_1.default.prototype.addFocusBlurEvents.call(this, this.focusableElement);\n if (this.itemsFromUrl && !this.component.noRefreshOnScroll) {\n this.scrollList = this.choices.choiceList.element;\n this.addEventListener(this.scrollList, 'scroll', () => this.onScroll());\n }\n if (choicesOptions.removeItemButton) {\n this.addEventListener(input, 'removeItem', () => {\n this.isRemoveButtonPressed = true;\n });\n }\n }\n if (window && this.choices && this.shouldPositionDropdown) {\n this.addEventListener(window.document, 'scroll', () => {\n this.positionDropdown(true);\n }, false, true);\n }\n this.focusableElement.setAttribute('tabIndex', tabIndex);\n // If a search field is provided, then add an event listener to update items on search.\n if (this.component.searchField) {\n // Make sure to clear the search when no value is provided.\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.addEventListener(this.choices.input.element, 'input', (event) => {\n this.isFromSearch = !!event.target.value;\n if (!event.target.value) {\n this.triggerUpdate();\n }\n else {\n this.serverCount = null;\n this.downloadedResources = [];\n }\n });\n }\n this.addEventListener(input, 'choice', () => {\n if (this.component.multiple && this.component.dataSrc === 'resource' && this.isFromSearch) {\n this.triggerUpdate();\n }\n this.isFromSearch = false;\n });\n // avoid spamming the resource/url endpoint when we have server side filtering enabled.\n const debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ?\n (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000\n : 0;\n const updateComponent = (evt) => {\n this.triggerUpdate(evt.detail.value);\n };\n this.addEventListener(input, 'search', lodash_1.default.debounce((e) => {\n updateComponent(e);\n this.positionDropdown();\n }, debounceTimeout));\n this.addEventListener(input, 'stopSearch', () => this.triggerUpdate());\n this.addEventListener(input, 'hideDropdown', () => {\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.choices.input.element.value = '';\n }\n this.updateItems(null, true);\n });\n }\n this.addEventListener(input, 'showDropdown', () => {\n this.update();\n this.positionDropdown();\n });\n if (this.shouldPositionDropdown) {\n this.addEventListener(input, 'highlightChoice', () => {\n this.positionDropdown();\n });\n }\n if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\n this.addEventListener(input, 'removeItem', () => {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\n });\n }\n // Add value options.\n this.addValueOptions();\n this.setChoicesValue(this.dataValue);\n if (this.isSelectResource && this.refs.addResource) {\n this.addEventListener(this.refs.addResource, 'click', (event) => {\n event.preventDefault();\n const formioForm = this.ce('div');\n const dialog = this.createModal(formioForm);\n const projectUrl = lodash_1.default.get(this.root, 'formio.projectUrl', Formio_1.Formio.getProjectUrl());\n const formUrl = `${projectUrl}/form/${this.component.data.resource}`;\n new Form_1.default(formioForm, formUrl, {}).ready\n .then((form) => {\n form.on('submit', (submission) => {\n // If valueProperty is set, replace the submission with the corresponding value\n let value = this.valueProperty ? lodash_1.default.get(submission, this.valueProperty) : submission;\n if (this.component.multiple) {\n value = [...this.dataValue, value];\n }\n this.setValue(value);\n this.triggerUpdate();\n dialog.close();\n });\n });\n });\n }\n // Force the disabled state with getters and setters.\n this.disabled = this.shouldDisabled;\n this.triggerUpdate();\n return superAttach;\n }\n setDropdownPosition() {\n var _a, _b, _c, _d;\n const dropdown = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.dropdown) === null || _b === void 0 ? void 0 : _b.element;\n const container = (_d = (_c = this.choices) === null || _c === void 0 ? void 0 : _c.containerOuter) === null || _d === void 0 ? void 0 : _d.element;\n if (!dropdown || !container) {\n return;\n }\n const containerPosition = container.getBoundingClientRect();\n const isFlipped = container.classList.contains('is-flipped');\n lodash_1.default.assign(dropdown.style, {\n top: `${isFlipped ? containerPosition.top - dropdown.offsetHeight : containerPosition.top + containerPosition.height}px`,\n left: `${containerPosition.left}px`,\n width: `${containerPosition.width}px`,\n position: 'fixed',\n bottom: 'unset',\n right: 'unset',\n });\n }\n hasDataGridAncestor(comp) {\n comp = comp || this;\n if (comp.inDataGrid || comp.type === 'datagrid') {\n return true;\n }\n else if (comp.parent) {\n return this.hasDataGridAncestor(comp.parent);\n }\n else {\n return false;\n }\n }\n positionDropdown(scroll) {\n var _a;\n if (!this.shouldPositionDropdown || !this.choices || (!((_a = this.choices.dropdown) === null || _a === void 0 ? void 0 : _a.isActive) && scroll)) {\n return;\n }\n this.setDropdownPosition();\n this.itemsLoaded.then(() => {\n this.setDropdownPosition();\n });\n }\n get isLoadingAvailable() {\n return !this.isScrollLoading && this.additionalResourcesAvailable;\n }\n onScroll() {\n if (this.isLoadingAvailable) {\n this.isScrollLoading = true;\n this.setLoadingItem(true);\n this.triggerUpdate(this.choices.input.element.value);\n }\n }\n attachRefreshOnBlur() {\n if (this.component.refreshOnBlur) {\n this.on('blur', (instance) => {\n this.checkRefreshOn([{ instance, value: instance.dataValue }], { fromBlur: true });\n });\n }\n }\n addPlaceholderItem(placeholderValue) {\n const items = this.choices._store.activeItems;\n if (!items.length) {\n this.choices._addItem({\n value: '',\n label: placeholderValue,\n choiceId: 0,\n groupId: -1,\n customProperties: null,\n placeholder: true,\n keyCode: null\n });\n }\n }\n /* eslint-enable max-statements */\n update() {\n if (this.component.dataSrc === 'custom') {\n this.updateCustomItems();\n }\n // Activate the control.\n this.activate();\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.setDisabled(this.choices.containerInner.element, true);\n this.focusableElement.removeAttribute('tabIndex');\n this.choices.disable();\n }\n else {\n this.setDisabled(this.choices.containerInner.element, false);\n this.focusableElement.setAttribute('tabIndex', this.component.tabindex || 0);\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n set visible(value) {\n // If we go from hidden to visible, trigger a refresh.\n if (value && (!this._visible !== !value)) {\n this.triggerUpdate();\n }\n super.visible = value;\n }\n get visible() {\n return super.visible;\n }\n /**\n * @param {*} value\n * @param {Array} items\n */\n addCurrentChoices(values, items, keyValue) {\n if (!values) {\n return false;\n }\n const notFoundValuesToAdd = [];\n const added = values.reduce((defaultAdded, value) => {\n if (!value || lodash_1.default.isEmpty(value)) {\n return defaultAdded;\n }\n let found = false;\n // Make sure that `items` and `this.selectOptions` points\n // to the same reference. Because `this.selectOptions` is\n // internal property and all items are populated by\n // `this.addOption` method, we assume that items has\n // 'label' and 'value' properties. This assumption allows\n // us to read correct value from the item.\n const isSelectOptions = items === this.selectOptions;\n if (items && items.length) {\n lodash_1.default.each(items, (choice) => {\n if (choice._id && value._id && (choice._id === value._id)) {\n found = true;\n return false;\n }\n const itemValue = keyValue ? choice.value : this.itemValue(choice, isSelectOptions);\n found |= lodash_1.default.isEqual(itemValue, value);\n return found ? false : true;\n });\n }\n // Add the default option if no item is found.\n if (!found) {\n notFoundValuesToAdd.push(this.selectValueAndLabel(value));\n return true;\n }\n return found || defaultAdded;\n }, false);\n if (notFoundValuesToAdd.length) {\n if (this.choices) {\n this.choices.setChoices(notFoundValuesToAdd, 'value', 'label');\n }\n notFoundValuesToAdd.map(notFoundValue => {\n this.addOption(notFoundValue.value, notFoundValue.label);\n });\n }\n return added;\n }\n getValueAsString(data, options) {\n return (this.component.multiple && Array.isArray(data))\n ? data.map((v) => this.asString(v, options)).join(', ')\n : this.asString(data, options);\n }\n getValue() {\n // If the widget isn't active.\n if (this.viewOnly || this.loading\n || (!this.component.lazyLoad && !this.selectOptions.length)\n || !this.element) {\n return this.dataValue;\n }\n let value = this.emptyValue;\n if (this.choices) {\n value = this.choices.getValue(true);\n // Make sure we don't get the placeholder\n if (!this.component.multiple &&\n this.component.placeholder &&\n (value === this.t(this.component.placeholder, { _userInput: true }))) {\n value = this.emptyValue;\n }\n }\n else if (this.refs.selectContainer) {\n value = this.refs.selectContainer.value;\n if (this.valueProperty === '' || this.isEntireObjectDisplay()) {\n if (value === '') {\n return {};\n }\n const option = this.selectOptions[value] ||\n this.selectOptions.find(option => option.id === value);\n if (option && lodash_1.default.isObject(option.value)) {\n value = option.value;\n }\n }\n }\n else {\n value = this.dataValue;\n }\n // Choices will return undefined if nothing is selected. We really want '' to be empty.\n if (value === undefined || value === null) {\n value = '';\n }\n return value;\n }\n redraw() {\n const done = super.redraw();\n this.triggerUpdate();\n return done;\n }\n normalizeSingleValue(value, retainObject) {\n var _a;\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n // Check to see if we need to save off the template data into our metadata.\n if (retainObject) {\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n const shouldSaveData = !valueIsObject || this.component.reference;\n if (templateValue && shouldSaveData && (this.templateData && this.templateData[templateValue]) && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submission)) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n let templateData = this.templateData[templateValue];\n if (this.component.multiple) {\n templateData = {};\n const dataValue = this.dataValue;\n if (dataValue && lodash_1.default.isArray(dataValue) && dataValue.length) {\n dataValue.forEach((dataValueItem) => {\n const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;\n templateData[dataValueItemValue] = this.templateData[dataValueItemValue];\n });\n }\n templateData[value] = this.templateData[value];\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, templateData);\n }\n }\n const dataType = this.component.dataType || 'auto';\n const normalize = {\n value,\n number() {\n const numberValue = Number(this.value);\n const isEquivalent = value.toString() === numberValue.toString();\n if (!Number.isNaN(numberValue) && Number.isFinite(numberValue) && value !== '' && isEquivalent) {\n this.value = numberValue;\n }\n return this;\n },\n boolean() {\n if (lodash_1.default.isString(this.value)\n && (this.value.toLowerCase() === 'true'\n || this.value.toLowerCase() === 'false')) {\n this.value = (this.value.toLowerCase() === 'true');\n }\n return this;\n },\n string() {\n this.value = String(this.value);\n return this;\n },\n object() {\n return this;\n },\n auto() {\n if (lodash_1.default.isObject(this.value)) {\n this.value = this.object().value;\n }\n else {\n this.value = this.string().number().boolean().value;\n }\n return this;\n }\n };\n try {\n return normalize[dataType]().value;\n }\n catch (err) {\n console.warn('Failed to normalize value', err);\n return value;\n }\n }\n /**\n * Normalize values coming into updateValue.\n *\n * @param value\n * @return {*}\n */\n normalizeValue(value) {\n if (this.component.multiple && Array.isArray(value)) {\n return value.map((singleValue) => this.normalizeSingleValue(singleValue, true));\n }\n return super.normalizeValue(this.normalizeSingleValue(value, true));\n }\n setValue(value, flags = {}) {\n const previousValue = this.dataValue;\n if (this.component.widget === 'html5' && (lodash_1.default.isEqual(value, previousValue) || lodash_1.default.isEqual(previousValue, {}) && lodash_1.default.isEqual(flags, {})) && !flags.fromSubmission) {\n return false;\n }\n const changed = this.updateValue(value, flags);\n value = this.dataValue;\n const hasPreviousValue = !this.isEmpty(previousValue);\n const hasValue = !this.isEmpty(value);\n // Undo typing when searching to set the value.\n if (this.component.multiple && Array.isArray(value)) {\n value = value.map(value => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return value.toString();\n }\n return value;\n });\n }\n else {\n if (typeof value === 'boolean' || typeof value === 'number') {\n value = value.toString();\n }\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.itemsLoaded.then(() => {\n this.redraw();\n });\n return changed;\n }\n // Do not set the value if we are loading... that will happen after it is done.\n if (this.loading) {\n return changed;\n }\n // Determine if we need to perform an initial lazyLoad api call if searchField is provided.\n if (this.isInitApiCallNeeded(hasValue)) {\n this.loading = true;\n this.lazyLoadInit = true;\n const searchProperty = this.component.searchField || this.component.valueProperty;\n this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);\n return changed;\n }\n // Add the value options.\n this.itemsLoaded.then(() => {\n this.addValueOptions();\n this.setChoicesValue(value, hasPreviousValue, flags);\n });\n return changed;\n }\n isInitApiCallNeeded(hasValue) {\n return this.component.lazyLoad &&\n !this.lazyLoadInit &&\n !this.active &&\n !this.selectOptions.length &&\n hasValue &&\n this.shouldInitialLoad &&\n this.visible && (this.component.searchField || this.component.valueProperty);\n }\n setChoicesValue(value, hasPreviousValue, flags = {}) {\n const hasValue = !this.isEmpty(value) || flags.fromSubmission;\n hasPreviousValue = (hasPreviousValue === undefined) ? true : hasPreviousValue;\n if (this.choices) {\n // Now set the value.\n if (hasValue) {\n this.choices.removeActiveItems();\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(value) && this.component.multiple ? value : [value];\n if (!this.addCurrentChoices(currentChoices, this.selectOptions, true)) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n this.choices.setChoiceByValue(currentChoices);\n }\n else if (hasPreviousValue || flags.resetValue) {\n this.choices.removeActiveItems();\n }\n }\n else {\n if (hasValue) {\n const values = Array.isArray(value) ? value : [value];\n if (!lodash_1.default.isEqual(this.dataValue, this.defaultValue) && this.selectOptions.length < 2\n || (this.selectData && flags.fromSubmission)) {\n const { value, label } = this.selectValueAndLabel(this.dataValue);\n this.addOption(value, label);\n }\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n lodash_1.default.each(values, (val) => {\n if (selectOption.value === '') {\n selectOption.value = {};\n }\n if (lodash_1.default.isEqual(val, selectOption.value) && selectOption.element) {\n selectOption.element.selected = true;\n selectOption.element.setAttribute('selected', 'selected');\n return false;\n }\n });\n });\n }\n else {\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n if (selectOption.element) {\n selectOption.element.selected = false;\n selectOption.element.removeAttribute('selected');\n }\n });\n }\n }\n }\n get itemsLoaded() {\n return this._itemsLoaded || Promise.resolve();\n }\n set itemsLoaded(promise) {\n this._itemsLoaded = promise;\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.getOptionsValues();\n if (values) {\n if (lodash_1.default.isObject(value)) {\n const compareComplexValues = (optionValue) => {\n const normalizedOptionValue = this.normalizeSingleValue(optionValue, true);\n if (!lodash_1.default.isObject(normalizedOptionValue)) {\n return false;\n }\n try {\n return (JSON.stringify(normalizedOptionValue) === JSON.stringify(value));\n }\n catch (err) {\n console.warn.error('Error while comparing items', err);\n return false;\n }\n };\n return values.findIndex((optionValue) => compareComplexValues(optionValue)) !== -1;\n }\n return values.findIndex((optionValue) => this.normalizeSingleValue(optionValue) === value) !== -1;\n }\n return false;\n }\n /**\n * Performs required transformations on the initial value to use in selectOptions\n * @param {*} value\n */\n getOptionValue(value) {\n return lodash_1.default.isObject(value) && this.isEntireObjectDisplay()\n ? this.normalizeSingleValue(value)\n : lodash_1.default.isObject(value) && (this.valueProperty || this.component.key !== 'resource')\n ? value\n : lodash_1.default.isObject(value) && !this.valueProperty\n ? this.interpolate(this.component.template, { item: value }).replace(/<\\/?[^>]+(>|$)/g, '')\n : lodash_1.default.isNull(value)\n ? this.emptyValue\n : String(this.normalizeSingleValue(value));\n }\n /**\n * If component has static values (values, json) or custom values, returns an array of them\n * @returns {Array<*>|undefined}\n */\n getOptionsValues() {\n let rawItems = [];\n switch (this.component.dataSrc) {\n case 'values':\n rawItems = this.component.data.values;\n break;\n case 'json':\n rawItems = this.component.data.json;\n break;\n case 'custom':\n rawItems = this.getCustomItems();\n break;\n }\n if (typeof rawItems === 'string') {\n try {\n rawItems = JSON.parse(rawItems);\n }\n catch (err) {\n console.warn(err.message);\n rawItems = [];\n }\n }\n if (!Array.isArray(rawItems)) {\n return;\n }\n return rawItems.map((item) => this.getOptionValue(this.itemValue(item)));\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue('', {\n noUpdateEvent: true\n });\n this.unset();\n }\n /**\n * Check if a component is eligible for multiple validation\n *\n * @return {boolean}\n */\n validateMultiple() {\n // Select component will contain one input when flagged as multiple.\n return false;\n }\n /**\n * Output this select dropdown as a string value.\n * @return {*}\n */\n isBooleanOrNumber(value) {\n return typeof value === 'number' || typeof value === 'boolean';\n }\n getNormalizedValues() {\n if (!this.component || !this.component.data || !this.component.data.values) {\n return;\n }\n return this.component.data.values.map(value => ({ label: value.label, value: String(this.normalizeSingleValue(value.value)) }));\n }\n asString(value, options = {}) {\n var _a;\n value = value !== null && value !== void 0 ? value : this.getValue();\n //need to convert values to strings to be able to compare values with available options that are strings\n const convertToString = (data, valueProperty) => {\n if (valueProperty) {\n if (Array.isArray(data)) {\n data.forEach((item) => item[valueProperty] = item[valueProperty].toString());\n }\n else {\n data[valueProperty] = data[valueProperty].toString();\n }\n return data;\n }\n if (this.isBooleanOrNumber(data)) {\n data = data.toString();\n }\n if (Array.isArray(data) && data.some(item => this.isBooleanOrNumber(item))) {\n data = data.map(item => {\n if (this.isBooleanOrNumber(item)) {\n item = item.toString();\n }\n });\n }\n return data;\n };\n value = convertToString(value);\n if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {\n const { items, valueProperty, } = this.component.dataSrc === 'values'\n ? {\n items: convertToString(this.getNormalizedValues(), 'value'),\n valueProperty: 'value',\n }\n : {\n items: convertToString(this.getCustomItems(), this.valueProperty),\n valueProperty: this.valueProperty,\n };\n const getFromValues = () => {\n const initialValue = lodash_1.default.find(items, [valueProperty, value]);\n const values = this.defaultSchema.data.values || [];\n return lodash_1.default.isEqual(initialValue, values[0]) ? '-' : initialValue;\n };\n value = (this.component.multiple && Array.isArray(value))\n ? lodash_1.default.filter(items, (item) => value.includes(item.value))\n : valueProperty\n ? (_a = getFromValues()) !== null && _a !== void 0 ? _a : { value, label: value }\n : value;\n }\n if (lodash_1.default.isString(value)) {\n return value;\n }\n const getTemplateValue = (v) => {\n const itemTemplate = this.itemTemplate(v);\n return options.csv && itemTemplate\n ? (0, utils_1.unescapeHTML)(itemTemplate)\n : itemTemplate;\n };\n if (Array.isArray(value)) {\n const items = [];\n value.forEach(item => items.push(getTemplateValue(item)));\n if (this.component.dataSrc === 'resource' && items.length > 0) {\n return items.join(', ');\n }\n else if (items.length > 0) {\n return items.join('<br />');\n }\n else {\n return '-';\n }\n }\n if (this.isEntireObjectDisplay() && lodash_1.default.isObject(value)) {\n return JSON.stringify(value);\n }\n return !lodash_1.default.isNil(value)\n ? getTemplateValue(value)\n : '-';\n }\n detach() {\n var _a, _b;\n this.off('blur');\n if (this.choices) {\n if ((_b = (_a = this.choices.containerOuter) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.parentNode) {\n this.choices.destroy();\n }\n this.choices = null;\n }\n super.detach();\n }\n focus() {\n if (this.focusableElement) {\n super.focus.call(this);\n this.focusableElement.focus();\n }\n }\n setErrorClasses(elements, dirty, hasError, hasMessages, element = this.element) {\n super.setErrorClasses(elements, dirty, hasError, hasMessages, element);\n if (this.choices) {\n super.setErrorClasses([this.choices.containerInner.element], dirty, hasError, hasMessages, element);\n }\n else {\n super.setErrorClasses([this.refs.selectContainer], dirty, hasError, hasMessages, element);\n }\n }\n}\nexports[\"default\"] = SelectComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/select/Select.js?");
|
6983
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst ChoicesWrapper_1 = __importDefault(__webpack_require__(/*! ../../utils/ChoicesWrapper */ \"./lib/cjs/utils/ChoicesWrapper.js\"));\nclass SelectComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'select',\n label: 'Select',\n key: 'select',\n idPath: 'id',\n data: {\n values: [{ label: '', value: '' }],\n json: '',\n url: '',\n resource: '',\n custom: ''\n },\n clearOnRefresh: false,\n limit: 100,\n valueProperty: '',\n lazyLoad: true,\n filter: '',\n searchEnabled: true,\n searchDebounce: 0.3,\n searchField: '',\n minSearch: 0,\n readOnlyValue: false,\n selectFields: '',\n selectThreshold: 0.3,\n uniqueOptions: false,\n tableView: true,\n fuseOptions: {\n include: 'score',\n threshold: 0.3,\n },\n indexeddb: {\n filter: {}\n },\n customOptions: {},\n useExactSearch: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Select',\n group: 'basic',\n icon: 'th-list',\n weight: 70,\n documentation: '/userguide/form-building/form-components#select',\n schema: SelectComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return SelectComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const valueComp = Object.assign(Object.assign({}, classComp), { type: 'select' });\n if ((0, utils_1.isSelectResourceWithObjectValue)(classComp)) {\n valueComp.reference = false;\n valueComp.onSetItems = `\n var templateKeys = utils.getItemTemplateKeys(component.template) || [];\n items = _.map(items || [], i => {\n var item = {};\n _.each(templateKeys, k => _.set(item, k, _.get(i, k)));\n return item;\n })\n `;\n }\n return valueComp;\n } });\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType, reference } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (reference) {\n return [object];\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n // Keep track of the select options.\n this.selectOptions = [];\n if (this.itemsFromUrl) {\n this.isFromSearch = false;\n this.searchServerCount = null;\n this.defaultServerCount = null;\n this.isScrollLoading = false;\n this.searchDownloadedResources = [];\n this.defaultDownloadedResources = [];\n }\n // If this component has been activated.//\n this.activated = false;\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.shouldPositionDropdown = this.hasDataGridAncestor();\n if (this.isHtmlRenderMode()) {\n this.activate();\n }\n // Get the template keys for this select component.\n this.getTemplateKeys();\n }\n get dataReady() {\n // If the root submission has been set, and we are still not attached, then assume\n // that our data is ready.\n if (this.root &&\n this.root.submissionSet &&\n !this.attached) {\n return Promise.resolve();\n }\n return this.itemsLoaded;\n }\n get defaultSchema() {\n return SelectComponent.schema();\n }\n get emptyValue() {\n if (this.component.multiple) {\n return [];\n }\n // if select has JSON data source type, we are defining if empty value would be an object or a string by checking JSON's first item\n if (this.component.dataSrc === 'json' && this.component.data.json) {\n const firstItem = this.component.data.json[0];\n let firstValue;\n if (this.valueProperty) {\n firstValue = lodash_1.default.get(firstItem, this.valueProperty);\n }\n else {\n firstValue = firstItem;\n }\n if (firstValue && typeof firstValue === 'string') {\n return '';\n }\n else {\n return {};\n }\n }\n if (this.valueProperty) {\n return '';\n }\n return {};\n }\n get valueProperty() {\n if (this.component.valueProperty) {\n return this.component.valueProperty;\n }\n // Force values datasource to use values without actually setting it on the component settings.\n if (this.component.dataSrc === 'values') {\n return 'value';\n }\n return '';\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'select';\n info.changeEvent = 'change';\n return info;\n }\n get isSelectResource() {\n return this.component.dataSrc === 'resource';\n }\n get itemsFromUrl() {\n return this.isSelectResource || this.isSelectURL;\n }\n get isInfiniteScrollProvided() {\n return this.itemsFromUrl;\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.parentDisabled;\n }\n get shouldInitialLoad() {\n if (this.component.widget === 'html5' &&\n this.isEntireObjectDisplay() &&\n this.component.searchField &&\n this.dataValue) {\n return false;\n }\n return super.shouldLoad;\n }\n get selectMetadata() {\n return super.selectData;\n }\n get selectData() {\n return this.component.selectData || this.selectMetadata;\n }\n isEntireObjectDisplay() {\n return this.component.dataSrc === 'resource' && this.valueProperty === 'data';\n }\n selectValueAndLabel(data) {\n const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : data, value)\n };\n }\n itemTemplate(data, value) {\n if (!lodash_1.default.isNumber(data) && lodash_1.default.isEmpty(data)) {\n return '';\n }\n // If they wish to show the value in read only mode, then just return the itemValue here.\n if (this.options.readOnly && this.component.readOnlyValue) {\n return this.itemValue(data);\n }\n // Perform a fast interpretation if we should not use the template.\n if (data && !this.component.template) {\n const itemLabel = data.label || data;\n const value = (typeof itemLabel === 'string') ? this.t(itemLabel, { _userInput: true }) : itemLabel;\n return this.sanitize(value, this.shouldSanitizeValue);\n }\n if (this.component.multiple && lodash_1.default.isArray(this.dataValue) ? this.dataValue.find((val) => value === val) : (this.dataValue === value)) {\n const selectData = this.selectData;\n if (selectData) {\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n if (!this.templateData || !this.templateData[templateValue]) {\n this.getOptionTemplate(data, value);\n }\n if (this.component.multiple) {\n if (selectData[templateValue]) {\n data = selectData[templateValue];\n }\n }\n else {\n data = selectData;\n }\n }\n }\n if (typeof data === 'string' || typeof data === 'number') {\n return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue);\n }\n if (Array.isArray(data)) {\n return data.map((val) => {\n if (typeof val === 'string' || typeof val === 'number') {\n return this.sanitize(this.t(val, { _userInput: true }), this.shouldSanitizeValue);\n }\n return val;\n });\n }\n if (data.data) {\n // checking additional fields in the template for the selected Entire Object option\n const hasNestedFields = /item\\.data\\.\\w*/g.test(this.component.template);\n data.data = this.isEntireObjectDisplay() && lodash_1.default.isObject(data.data) && !hasNestedFields\n ? JSON.stringify(data.data)\n : data.data;\n }\n return super.itemTemplate(data, value);\n }\n /**\n * Adds an option to the select dropdown.\n *\n * @param value\n * @param label\n */\n addOption(value, label, attrs = {}, id = (0, utils_1.getRandomComponentId)()) {\n if (lodash_1.default.isNil(label))\n return;\n const idPath = this.component.idPath\n ? this.component.idPath.split('.').reduceRight((obj, key) => ({ [key]: obj }), id)\n : {};\n const option = Object.assign({ value: this.getOptionValue(value), label }, idPath);\n const skipOption = this.component.uniqueOptions\n ? !!this.selectOptions.find((selectOption) => lodash_1.default.isEqual(selectOption.value, option.value))\n : false;\n if (skipOption) {\n return;\n }\n if (value) {\n this.selectOptions.push(option);\n }\n if (this.refs.selectContainer && (this.component.widget === 'html5')) {\n // Replace an empty Object value to an empty String.\n if (option.value && lodash_1.default.isObject(option.value) && lodash_1.default.isEmpty(option.value)) {\n option.value = '';\n }\n // Add element to option so we can reference it later.\n const div = document.createElement('div');\n div.innerHTML = this.sanitize(this.renderTemplate('selectOption', {\n selected: lodash_1.default.isEqual(this.getOptionValue(this.dataValue), option.value),\n option,\n attrs,\n id,\n useId: (this.valueProperty === '' || this.isEntireObjectDisplay()) && lodash_1.default.isObject(value) && id,\n }), this.shouldSanitizeValue).trim();\n option.element = div.firstChild;\n this.refs.selectContainer.appendChild(option.element);\n }\n }\n addValueOptions(items) {\n items = items || [];\n let added = false;\n let data = this.dataValue;\n // preset submission value with value property before request.\n if (this.options.pdf && !items.length && this.component.dataSrc === 'url' && this.valueProperty) {\n data = Array.isArray(data)\n ? data.map(item => lodash_1.default.set({}, this.valueProperty, item))\n : lodash_1.default.set({}, this.valueProperty, data);\n }\n if (!this.selectOptions.length) {\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(data) && this.component.multiple ? data : [data];\n added = this.addCurrentChoices(currentChoices, items);\n if (!added && !this.component.multiple) {\n this.addPlaceholder();\n }\n }\n return added;\n }\n disableInfiniteScroll() {\n if (!this.downloadedResources) {\n return;\n }\n this.downloadedResources.serverCount = this.downloadedResources.length;\n this.serverCount = this.downloadedResources.length;\n }\n /* eslint-disable max-statements */\n setItems(items, fromSearch) {\n var _a, _b;\n this.selectItems = items;\n // If the items is a string, then parse as JSON.\n if (typeof items == 'string') {\n try {\n items = JSON.parse(items);\n }\n catch (err) {\n console.warn(err.message);\n items = [];\n }\n }\n // Allow js processing (needed for form builder)\n if (this.component.onSetItems) {\n const newItems = typeof this.component.onSetItems === 'function'\n ? this.component.onSetItems(this, items)\n : this.evaluate(this.component.onSetItems, { items: items }, 'items');\n if (newItems) {\n items = newItems;\n }\n }\n if (!this.choices && this.refs.selectContainer) {\n this.empty(this.refs.selectContainer);\n }\n // If they provided select values, then we need to get them instead.\n if (this.component.selectValues) {\n items = lodash_1.default.get(items, this.component.selectValues, items) || [];\n }\n let areItemsEqual;\n if (this.itemsFromUrl) {\n areItemsEqual = this.isSelectURL ? lodash_1.default.isEqual(items, this.downloadedResources) : false;\n const areItemsEnded = this.component.limit > items.length;\n const areItemsDownloaded = areItemsEqual\n && this.downloadedResources\n && this.downloadedResources.length === items.length;\n if (areItemsEnded) {\n this.disableInfiniteScroll();\n }\n else if (areItemsDownloaded) {\n this.selectOptions = [];\n }\n else {\n this.serverCount = items.serverCount;\n }\n }\n if (this.isScrollLoading && items) {\n if (!areItemsEqual) {\n this.downloadedResources = this.downloadedResources\n ? this.downloadedResources.concat(items)\n : items;\n }\n this.downloadedResources.serverCount = items.serverCount || this.downloadedResources.serverCount;\n }\n else {\n this.downloadedResources = items || [];\n this.selectOptions = [];\n // If there is new select option with same id as already selected, set the new one\n if (!lodash_1.default.isEmpty(this.dataValue) && this.component.idPath) {\n const selectedOptionId = lodash_1.default.get(this.dataValue, this.component.idPath, null);\n const newOptionWithSameId = !lodash_1.default.isNil(selectedOptionId) && items.find(item => {\n const itemId = lodash_1.default.get(item, this.component.idPath);\n return itemId === selectedOptionId;\n });\n if (newOptionWithSameId) {\n this.setValue(newOptionWithSameId);\n }\n }\n }\n // Add the value options.\n if (!fromSearch) {\n this.addValueOptions(items);\n }\n if (this.component.widget === 'html5' && !this.component.placeholder) {\n this.addOption(null, '');\n }\n // Iterate through each of the items.\n lodash_1.default.each(items, (item, index) => {\n // preventing references of the components inside the form to the parent form when building forms\n if (this.root && this.root.options.editForm && this.root.options.editForm._id && this.root.options.editForm._id === item._id)\n return;\n const itemValueAndLabel = this.selectValueAndLabel(item);\n this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, lodash_1.default.get(item, this.component.idPath, String(index)));\n });\n if (this.choices) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n else if (this.loading) {\n // Re-attach select input.\n // this.appendTo(this.refs.input[0], this.selectContainer);\n }\n // We are no longer loading.\n this.isScrollLoading = false;\n this.loading = false;\n const searching = fromSearch && ((_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.isFocussed);\n if (!searching) {\n // If a value is provided, then select it.\n if (!this.isEmpty() || this.isRemoveButtonPressed) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else if (this.shouldAddDefaultValue && !this.options.readOnly) {\n // If a default value is provided then select it.\n const defaultValue = this.defaultValue;\n if (!this.isEmpty(defaultValue)) {\n this.setValue(defaultValue);\n }\n }\n }\n // Say we are done loading the items.\n this.itemsLoadedResolve();\n }\n getSingleItemValueForHTMLMode(data) {\n var _a;\n const option = (_a = this.selectOptions) === null || _a === void 0 ? void 0 : _a.find(({ value }) => lodash_1.default.isEqual(value, data));\n if (option) {\n return option.label || data;\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (!this.isHtmlRenderMode()) {\n return super.itemValueForHTMLMode(value);\n }\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item)\n ? this.itemValueForHTMLMode(item)\n : this.getSingleItemValueForHTMLMode(item));\n return values.join(', ');\n }\n return this.getSingleItemValueForHTMLMode(value);\n }\n /* eslint-enable max-statements */\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n get loadingError() {\n return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError;\n }\n loadItems(url, search, headers, options, method, body) {\n options = options || {};\n // See if we should load items or not.\n if (!this.shouldLoad || (!this.itemsFromUrl && this.options.readOnly)) {\n this.isScrollLoading = false;\n this.loading = false;\n this.itemsLoadedResolve();\n return;\n }\n // See if they have not met the minimum search requirements.\n const minSearch = parseInt(this.component.minSearch, 10);\n if (this.component.searchField &&\n (minSearch > 0) &&\n (!search || (search.length < minSearch))) {\n // Set empty items.\n return this.setItems([]);\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n const query = this.component.disableLimit ? {} : {\n limit,\n skip,\n };\n // Allow for url interpolation.\n url = this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n });\n // Add search capability.\n if (this.component.searchField && search) {\n const searchValue = Array.isArray(search)\n ? search.join(',')\n : typeof search === 'object'\n ? JSON.stringify(search)\n : search;\n query[this.component.searchField] = this.component.searchField.endsWith('__regex')\n ? lodash_1.default.escapeRegExp(searchValue)\n : searchValue;\n }\n // If they wish to return only some fields.\n if (this.component.selectFields) {\n query.select = this.component.selectFields;\n }\n // Add sort capability\n if (this.component.sort) {\n query.sort = this.component.sort;\n }\n if (!lodash_1.default.isEmpty(query)) {\n // Add the query string.\n url += (!url.includes('?') ? '?' : '&') + Formio_1.Formio.serialize(query, (item) => this.interpolate(item));\n }\n // Add filter capability\n if (this.component.filter) {\n url += (!url.includes('?') ? '?' : '&') + this.interpolate(this.component.filter);\n }\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response, !!search);\n })\n .catch((err) => {\n if (this.itemsFromUrl) {\n this.setItems([]);\n this.disableInfiniteScroll();\n }\n this.isScrollLoading = false;\n this.handleLoadingError(err);\n });\n }\n handleLoadingError(err) {\n this.loading = false;\n if (err.networkError) {\n this.networkError = true;\n }\n this.itemsLoadedResolve();\n this.emit('componentError', {\n component: this.component,\n message: err.toString(),\n });\n console.warn(`Unable to load resources for ${this.key}`);\n }\n /**\n * Get the request headers for this select dropdown.\n */\n get requestHeaders() {\n // Create the headers object.\n const headers = new Formio_1.Formio.Headers();\n // Add custom headers to the url.\n if (this.component.data && this.component.data.headers) {\n try {\n lodash_1.default.each(this.component.data.headers, (header) => {\n if (header.key) {\n headers.set(header.key, this.interpolate(header.value));\n }\n });\n }\n catch (err) {\n console.warn(err.message);\n }\n }\n return headers;\n }\n getCustomItems() {\n const customItems = this.evaluate(this.component.data.custom, {\n values: []\n }, 'values');\n this.asyncValues = (0, utils_1.isPromise)(customItems);\n return customItems;\n }\n asyncCustomValues() {\n if (!lodash_1.default.isBoolean(this.asyncValues)) {\n this.getCustomItems();\n }\n return this.asyncValues;\n }\n updateCustomItems(forceUpdate) {\n if (this.asyncCustomValues()) {\n if (!forceUpdate && !this.active) {\n this.itemsLoadedResolve();\n return;\n }\n this.loading = true;\n this.getCustomItems()\n .then(items => {\n this.loading = false;\n this.setItems(items || []);\n })\n .catch(err => {\n this.handleLoadingError(err);\n });\n }\n else {\n this.setItems(this.getCustomItems() || []);\n }\n }\n isEmpty(value = this.dataValue) {\n return super.isEmpty(value) || value === undefined;\n }\n refresh(value, { instance }) {\n if (this.component.clearOnRefresh && (instance && !instance.pristine)) {\n this.setValue(this.emptyValue);\n }\n this.updateItems(null, true);\n }\n get additionalResourcesAvailable() {\n return lodash_1.default.isNil(this.serverCount) || (this.serverCount > this.downloadedResources.length);\n }\n get serverCount() {\n if (this.isFromSearch) {\n return this.searchServerCount;\n }\n return this.defaultServerCount;\n }\n set serverCount(value) {\n if (this.isFromSearch) {\n this.searchServerCount = value;\n }\n else {\n this.defaultServerCount = value;\n }\n }\n get downloadedResources() {\n if (this.isFromSearch) {\n return this.searchDownloadedResources;\n }\n return this.defaultDownloadedResources;\n }\n set downloadedResources(value) {\n if (this.isFromSearch) {\n this.searchDownloadedResources = value;\n }\n else {\n this.defaultDownloadedResources = value;\n }\n }\n addPlaceholder() {\n if (!this.component.placeholder) {\n return;\n }\n this.addOption('', this.component.placeholder, { placeholder: true });\n }\n /**\n * Activate this select control.\n */\n activate() {\n if (this.loading || !this.active) {\n this.setLoadingItem();\n }\n if (this.active) {\n return;\n }\n this.activated = true;\n this.triggerUpdate();\n }\n setLoadingItem(addToCurrentList = false) {\n if (this.choices) {\n if (addToCurrentList) {\n this.choices.setChoices([{\n value: `${this.id}-loading`,\n label: 'Loading...',\n disabled: true,\n }], 'value', 'label');\n }\n else {\n this.choices.setChoices([{\n value: '',\n label: `<i class=\"${this.iconClass('refresh')}\" style=\"font-size:1.3em;\"></i>`,\n disabled: true,\n }], 'value', 'label', true);\n }\n }\n else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') {\n this.addOption('', this.t('loading...'));\n }\n }\n get active() {\n return !this.component.lazyLoad || this.activated;\n }\n render() {\n const info = this.inputInfo;\n info.attr = info.attr || {};\n info.multiple = this.component.multiple;\n return super.render(this.wrapElement(this.renderTemplate('select', {\n input: info,\n selectOptions: '',\n index: null,\n })));\n }\n wrapElement(element) {\n return this.component.addResource && !this.options.readOnly\n ? (this.renderTemplate('resourceAdd', {\n element\n }))\n : element;\n }\n choicesOptions() {\n const useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true;\n const placeholderValue = this.t(this.component.placeholder, { _userInput: true });\n let customOptions = this.component.customOptions || {};\n if (typeof customOptions == 'string') {\n try {\n customOptions = JSON.parse(customOptions);\n }\n catch (err) {\n console.warn(err.message);\n customOptions = {};\n }\n }\n const commonFuseOptions = {\n maxPatternLength: 1000,\n distance: 1000,\n };\n return Object.assign({ removeItemButton: this.component.disabled ? false : lodash_1.default.get(this.component, 'removeItemButton', true), itemSelectText: '', classNames: {\n containerOuter: 'choices form-group formio-choices',\n containerInner: this.transform('class', 'form-control ui fluid selection dropdown')\n }, addItemText: false, allowHTML: true, placeholder: !!this.component.placeholder, placeholderValue: placeholderValue, noResultsText: this.t('No results found'), noChoicesText: this.t('No choices to choose from'), searchPlaceholderValue: this.t('Type to search'), shouldSort: false, position: (this.component.dropdown || 'auto'), searchEnabled: useSearch, searchChoices: !this.component.searchField, searchFields: lodash_1.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch\n ? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false }, customOptions);\n }\n /* eslint-disable max-statements */\n attach(element) {\n var _a, _b, _c;\n const superAttach = super.attach(element);\n this.loadRefs(element, {\n selectContainer: 'single',\n addResource: 'single',\n autocompleteInput: 'single'\n });\n //enable autocomplete for select\n const autocompleteInput = this.refs.autocompleteInput;\n if (autocompleteInput) {\n this.addEventListener(autocompleteInput, 'change', (event) => {\n this.setValue(event.target.value);\n });\n }\n const input = this.refs.selectContainer;\n if (!input) {\n return;\n }\n this.addEventListener(input, this.inputInfo.changeEvent, () => this.updateValue(null, {\n modified: true\n }));\n this.attachRefreshOnBlur();\n if (this.component.widget === 'html5') {\n this.addFocusBlurEvents(input);\n this.triggerUpdate(null, true);\n if (this.visible) {\n this.setItems(this.selectItems || []);\n }\n this.focusableElement = input;\n if (this.component.dataSrc === 'custom') {\n this.addEventListener(input, 'focus', () => this.updateCustomItems());\n }\n this.addEventListener(input, 'keydown', (event) => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n this.setValue(this.emptyValue);\n }\n });\n return;\n }\n const tabIndex = input.tabIndex;\n this.addPlaceholder();\n if (this.i18next) {\n input.setAttribute('dir', this.i18next.dir());\n }\n if ((_c = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.containerOuter) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.parentNode) {\n this.choices.destroy();\n }\n const choicesOptions = this.choicesOptions();\n if (ChoicesWrapper_1.default) {\n this.choices = new ChoicesWrapper_1.default(input, choicesOptions);\n if (this.selectOptions && this.selectOptions.length) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n if (this.component.multiple) {\n this.focusableElement = this.choices.input.element;\n }\n else {\n this.focusableElement = this.choices.containerInner.element;\n this.choices.containerOuter.element.setAttribute('tabIndex', '-1');\n this.addEventListener(this.choices.containerOuter.element, 'focus', () => this.focusableElement.focus());\n }\n Input_1.default.prototype.addFocusBlurEvents.call(this, this.focusableElement);\n if (this.itemsFromUrl && !this.component.noRefreshOnScroll) {\n this.scrollList = this.choices.choiceList.element;\n this.addEventListener(this.scrollList, 'scroll', () => this.onScroll());\n }\n if (choicesOptions.removeItemButton) {\n this.addEventListener(input, 'removeItem', () => {\n this.isRemoveButtonPressed = true;\n });\n }\n }\n if (window && this.choices && this.shouldPositionDropdown) {\n this.addEventListener(window.document, 'scroll', () => {\n this.positionDropdown(true);\n }, false, true);\n }\n this.focusableElement.setAttribute('tabIndex', tabIndex);\n // If a search field is provided, then add an event listener to update items on search.\n if (this.component.searchField) {\n // Make sure to clear the search when no value is provided.\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.addEventListener(this.choices.input.element, 'input', (event) => {\n this.isFromSearch = !!event.target.value;\n if (!event.target.value) {\n this.triggerUpdate();\n }\n else {\n this.serverCount = null;\n this.downloadedResources = [];\n }\n });\n }\n this.addEventListener(input, 'choice', () => {\n if (this.component.multiple && this.component.dataSrc === 'resource' && this.isFromSearch) {\n this.triggerUpdate();\n }\n this.isFromSearch = false;\n });\n // avoid spamming the resource/url endpoint when we have server side filtering enabled.\n const debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ?\n (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000\n : 0;\n const updateComponent = (evt) => {\n this.triggerUpdate(evt.detail.value);\n };\n this.addEventListener(input, 'search', lodash_1.default.debounce((e) => {\n updateComponent(e);\n this.positionDropdown();\n }, debounceTimeout));\n this.addEventListener(input, 'stopSearch', () => this.triggerUpdate());\n this.addEventListener(input, 'hideDropdown', () => {\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.choices.input.element.value = '';\n }\n this.updateItems(null, true);\n });\n }\n this.addEventListener(input, 'showDropdown', () => {\n this.update();\n this.positionDropdown();\n });\n if (this.shouldPositionDropdown) {\n this.addEventListener(input, 'highlightChoice', () => {\n this.positionDropdown();\n });\n }\n if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\n this.addEventListener(input, 'removeItem', () => {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\n });\n }\n // Add value options.\n this.addValueOptions();\n this.setChoicesValue(this.dataValue);\n if (this.isSelectResource && this.refs.addResource) {\n this.addEventListener(this.refs.addResource, 'click', (event) => {\n event.preventDefault();\n const formioForm = this.ce('div');\n const dialog = this.createModal(formioForm);\n const projectUrl = lodash_1.default.get(this.root, 'formio.projectUrl', Formio_1.Formio.getProjectUrl());\n const formUrl = `${projectUrl}/form/${this.component.data.resource}`;\n new Form_1.default(formioForm, formUrl, {}).ready\n .then((form) => {\n form.on('submit', (submission) => {\n // If valueProperty is set, replace the submission with the corresponding value\n let value = this.valueProperty ? lodash_1.default.get(submission, this.valueProperty) : submission;\n if (this.component.multiple) {\n value = [...this.dataValue, value];\n }\n this.setValue(value);\n this.triggerUpdate();\n dialog.close();\n });\n });\n });\n }\n // Force the disabled state with getters and setters.\n this.disabled = this.shouldDisabled;\n this.triggerUpdate();\n return superAttach;\n }\n setDropdownPosition() {\n var _a, _b, _c, _d;\n const dropdown = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.dropdown) === null || _b === void 0 ? void 0 : _b.element;\n const container = (_d = (_c = this.choices) === null || _c === void 0 ? void 0 : _c.containerOuter) === null || _d === void 0 ? void 0 : _d.element;\n if (!dropdown || !container) {\n return;\n }\n const containerPosition = container.getBoundingClientRect();\n const isFlipped = container.classList.contains('is-flipped');\n lodash_1.default.assign(dropdown.style, {\n top: `${isFlipped ? containerPosition.top - dropdown.offsetHeight : containerPosition.top + containerPosition.height}px`,\n left: `${containerPosition.left}px`,\n width: `${containerPosition.width}px`,\n position: 'fixed',\n bottom: 'unset',\n right: 'unset',\n });\n }\n hasDataGridAncestor(comp) {\n comp = comp || this;\n if (comp.inDataGrid || comp.type === 'datagrid') {\n return true;\n }\n else if (comp.parent) {\n return this.hasDataGridAncestor(comp.parent);\n }\n else {\n return false;\n }\n }\n positionDropdown(scroll) {\n var _a;\n if (!this.shouldPositionDropdown || !this.choices || (!((_a = this.choices.dropdown) === null || _a === void 0 ? void 0 : _a.isActive) && scroll)) {\n return;\n }\n this.setDropdownPosition();\n this.itemsLoaded.then(() => {\n this.setDropdownPosition();\n });\n }\n get isLoadingAvailable() {\n return !this.isScrollLoading && this.additionalResourcesAvailable;\n }\n onScroll() {\n if (this.isLoadingAvailable) {\n this.isScrollLoading = true;\n this.setLoadingItem(true);\n this.triggerUpdate(this.choices.input.element.value);\n }\n }\n attachRefreshOnBlur() {\n if (this.component.refreshOnBlur) {\n this.on('blur', (instance) => {\n this.checkRefreshOn([{ instance, value: instance.dataValue }], { fromBlur: true });\n });\n }\n }\n addPlaceholderItem(placeholderValue) {\n const items = this.choices._store.activeItems;\n if (!items.length) {\n this.choices._addItem({\n value: '',\n label: placeholderValue,\n choiceId: 0,\n groupId: -1,\n customProperties: null,\n placeholder: true,\n keyCode: null\n });\n }\n }\n /* eslint-enable max-statements */\n update() {\n if (this.component.dataSrc === 'custom') {\n this.updateCustomItems();\n }\n // Activate the control.\n this.activate();\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.setDisabled(this.choices.containerInner.element, true);\n this.focusableElement.removeAttribute('tabIndex');\n this.choices.disable();\n }\n else {\n this.setDisabled(this.choices.containerInner.element, false);\n this.focusableElement.setAttribute('tabIndex', this.component.tabindex || 0);\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n set visible(value) {\n // If we go from hidden to visible, trigger a refresh.\n if (value && (!this._visible !== !value)) {\n this.triggerUpdate();\n }\n super.visible = value;\n }\n get visible() {\n return super.visible;\n }\n /**\n * @param {*} value\n * @param {Array} items\n */\n addCurrentChoices(values, items, keyValue) {\n if (!values) {\n return false;\n }\n const notFoundValuesToAdd = [];\n const added = values.reduce((defaultAdded, value) => {\n if (!value || lodash_1.default.isEmpty(value)) {\n return defaultAdded;\n }\n let found = false;\n // Make sure that `items` and `this.selectOptions` points\n // to the same reference. Because `this.selectOptions` is\n // internal property and all items are populated by\n // `this.addOption` method, we assume that items has\n // 'label' and 'value' properties. This assumption allows\n // us to read correct value from the item.\n const isSelectOptions = items === this.selectOptions;\n if (items && items.length) {\n lodash_1.default.each(items, (choice) => {\n if (choice._id && value._id && (choice._id === value._id)) {\n found = true;\n return false;\n }\n const itemValue = keyValue ? choice.value : this.itemValue(choice, isSelectOptions);\n found |= lodash_1.default.isEqual(itemValue, value);\n return found ? false : true;\n });\n }\n // Add the default option if no item is found.\n if (!found) {\n notFoundValuesToAdd.push(this.selectValueAndLabel(value));\n return true;\n }\n return found || defaultAdded;\n }, false);\n if (notFoundValuesToAdd.length) {\n if (this.choices) {\n this.choices.setChoices(notFoundValuesToAdd, 'value', 'label');\n }\n notFoundValuesToAdd.map(notFoundValue => {\n this.addOption(notFoundValue.value, notFoundValue.label);\n });\n }\n return added;\n }\n getValueAsString(data, options) {\n return (this.component.multiple && Array.isArray(data))\n ? data.map((v) => this.asString(v, options)).join(', ')\n : this.asString(data, options);\n }\n getValue() {\n // If the widget isn't active.\n if (this.viewOnly || this.loading\n || (!this.component.lazyLoad && !this.selectOptions.length)\n || !this.element) {\n return this.dataValue;\n }\n let value = this.emptyValue;\n if (this.choices) {\n value = this.choices.getValue(true);\n // Make sure we don't get the placeholder\n if (!this.component.multiple &&\n this.component.placeholder &&\n (value === this.t(this.component.placeholder, { _userInput: true }))) {\n value = this.emptyValue;\n }\n }\n else if (this.refs.selectContainer) {\n value = this.refs.selectContainer.value;\n if (this.valueProperty === '' || this.isEntireObjectDisplay()) {\n if (value === '') {\n return {};\n }\n const option = this.selectOptions[value] ||\n this.selectOptions.find(option => option.id === value);\n if (option && lodash_1.default.isObject(option.value)) {\n value = option.value;\n }\n }\n }\n else {\n value = this.dataValue;\n }\n // Choices will return undefined if nothing is selected. We really want '' to be empty.\n if (value === undefined || value === null) {\n value = '';\n }\n return value;\n }\n redraw() {\n const done = super.redraw();\n this.triggerUpdate();\n return done;\n }\n normalizeSingleValue(value) {\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n const dataType = this.component.dataType || 'auto';\n const normalize = {\n value,\n number() {\n const numberValue = Number(this.value);\n const isEquivalent = value.toString() === numberValue.toString();\n if (!Number.isNaN(numberValue) && Number.isFinite(numberValue) && value !== '' && isEquivalent) {\n this.value = numberValue;\n }\n return this;\n },\n boolean() {\n if (lodash_1.default.isString(this.value)\n && (this.value.toLowerCase() === 'true'\n || this.value.toLowerCase() === 'false')) {\n this.value = (this.value.toLowerCase() === 'true');\n }\n return this;\n },\n string() {\n this.value = String(this.value);\n return this;\n },\n object() {\n return this;\n },\n auto() {\n if (lodash_1.default.isObject(this.value)) {\n this.value = this.object().value;\n }\n else {\n this.value = this.string().number().boolean().value;\n }\n return this;\n }\n };\n try {\n return normalize[dataType]().value;\n }\n catch (err) {\n console.warn('Failed to normalize value', err);\n return value;\n }\n }\n /**\n * Normalize values coming into updateValue.\n *\n * @param value\n * @return {*}\n */\n normalizeValue(value) {\n if (this.component.multiple && Array.isArray(value)) {\n return value.map((singleValue) => this.normalizeSingleValue(singleValue));\n }\n return super.normalizeValue(this.normalizeSingleValue(value));\n }\n setMetadata(value) {\n var _a;\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n // Check to see if we need to save off the template data into our metadata.\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n const shouldSaveData = !valueIsObject || this.component.reference;\n if (templateValue && shouldSaveData && this.templateData && this.templateData[templateValue] && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submission)) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n let templateData = this.templateData[templateValue];\n if (this.component.multiple) {\n templateData = {};\n const dataValue = this.dataValue;\n if (dataValue && lodash_1.default.isArray(dataValue) && dataValue.length) {\n dataValue.forEach((dataValueItem) => {\n const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;\n templateData[dataValueItemValue] = this.templateData[dataValueItemValue];\n });\n }\n templateData[value] = this.templateData[value];\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, templateData);\n }\n }\n updateValue(value, flags) {\n const changed = super.updateValue(value, flags);\n if (changed || !this.selectMetadata) {\n if (this.component.multiple && Array.isArray(this.dataValue)) {\n this.dataValue.forEach(singleValue => this.setMetadata(singleValue));\n }\n else {\n this.setMetadata(this.dataValue);\n }\n }\n return changed;\n }\n setValue(value, flags = {}) {\n const previousValue = this.dataValue;\n const changed = this.updateValue(value, flags);\n if (this.component.widget === 'html5' && (lodash_1.default.isEqual(value, previousValue) || lodash_1.default.isEqual(previousValue, {}) && lodash_1.default.isEqual(flags, {})) && !flags.fromSubmission) {\n return false;\n }\n value = this.dataValue;\n const hasPreviousValue = !this.isEmpty(previousValue);\n const hasValue = !this.isEmpty(value);\n // Undo typing when searching to set the value.\n if (this.component.multiple && Array.isArray(value)) {\n value = value.map(value => {\n if (typeof value === 'boolean' || typeof value === 'number') {\n return value.toString();\n }\n return value;\n });\n }\n else {\n if (typeof value === 'boolean' || typeof value === 'number') {\n value = value.toString();\n }\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.itemsLoaded.then(() => {\n this.redraw();\n });\n return changed;\n }\n // Do not set the value if we are loading... that will happen after it is done.\n if (this.loading) {\n return changed;\n }\n // Determine if we need to perform an initial lazyLoad api call if searchField is provided.\n if (this.isInitApiCallNeeded(hasValue)) {\n this.loading = true;\n this.lazyLoadInit = true;\n const searchProperty = this.component.searchField || this.component.valueProperty;\n this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);\n return changed;\n }\n // Add the value options.\n this.itemsLoaded.then(() => {\n this.addValueOptions();\n this.setChoicesValue(value, hasPreviousValue, flags);\n });\n return changed;\n }\n isInitApiCallNeeded(hasValue) {\n return this.component.lazyLoad &&\n !this.lazyLoadInit &&\n !this.active &&\n !this.selectOptions.length &&\n hasValue &&\n this.shouldInitialLoad &&\n this.visible && (this.component.searchField || this.component.valueProperty);\n }\n setChoicesValue(value, hasPreviousValue, flags = {}) {\n const hasValue = !this.isEmpty(value) || flags.fromSubmission;\n hasPreviousValue = (hasPreviousValue === undefined) ? true : hasPreviousValue;\n if (this.choices) {\n // Now set the value.\n if (hasValue) {\n this.choices.removeActiveItems();\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(value) && this.component.multiple ? value : [value];\n if (!this.addCurrentChoices(currentChoices, this.selectOptions, true)) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n this.choices.setChoiceByValue(currentChoices);\n }\n else if (hasPreviousValue || flags.resetValue) {\n this.choices.removeActiveItems();\n }\n }\n else {\n if (hasValue) {\n const values = Array.isArray(value) ? value : [value];\n if (!lodash_1.default.isEqual(this.dataValue, this.defaultValue) && this.selectOptions.length < 2\n || (this.selectData && flags.fromSubmission)) {\n const { value, label } = this.selectValueAndLabel(this.dataValue);\n this.addOption(value, label);\n }\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n lodash_1.default.each(values, (val) => {\n if (selectOption.value === '') {\n selectOption.value = {};\n }\n if (lodash_1.default.isEqual(val, selectOption.value) && selectOption.element) {\n selectOption.element.selected = true;\n selectOption.element.setAttribute('selected', 'selected');\n return false;\n }\n });\n });\n }\n else {\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n if (selectOption.element) {\n selectOption.element.selected = false;\n selectOption.element.removeAttribute('selected');\n }\n });\n }\n }\n }\n get itemsLoaded() {\n return this._itemsLoaded || Promise.resolve();\n }\n set itemsLoaded(promise) {\n this._itemsLoaded = promise;\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.getOptionsValues();\n if (values) {\n if (lodash_1.default.isObject(value)) {\n const compareComplexValues = (optionValue) => {\n const normalizedOptionValue = this.normalizeSingleValue(optionValue);\n if (!lodash_1.default.isObject(normalizedOptionValue)) {\n return false;\n }\n try {\n return (JSON.stringify(normalizedOptionValue) === JSON.stringify(value));\n }\n catch (err) {\n console.warn.error('Error while comparing items', err);\n return false;\n }\n };\n return values.findIndex((optionValue) => compareComplexValues(optionValue)) !== -1;\n }\n return values.findIndex((optionValue) => this.normalizeSingleValue(optionValue) === value) !== -1;\n }\n return false;\n }\n /**\n * Performs required transformations on the initial value to use in selectOptions\n * @param {*} value\n */\n getOptionValue(value) {\n return lodash_1.default.isObject(value) && this.isEntireObjectDisplay()\n ? this.normalizeSingleValue(value)\n : lodash_1.default.isObject(value) && (this.valueProperty || this.component.key !== 'resource')\n ? value\n : lodash_1.default.isObject(value) && !this.valueProperty\n ? this.interpolate(this.component.template, { item: value }).replace(/<\\/?[^>]+(>|$)/g, '')\n : lodash_1.default.isNull(value)\n ? this.emptyValue\n : String(this.normalizeSingleValue(value));\n }\n /**\n * If component has static values (values, json) or custom values, returns an array of them\n * @returns {Array<*>|undefined}\n */\n getOptionsValues() {\n let rawItems = [];\n switch (this.component.dataSrc) {\n case 'values':\n rawItems = this.component.data.values;\n break;\n case 'json':\n rawItems = this.component.data.json;\n break;\n case 'custom':\n rawItems = this.getCustomItems();\n break;\n }\n if (typeof rawItems === 'string') {\n try {\n rawItems = JSON.parse(rawItems);\n }\n catch (err) {\n console.warn(err.message);\n rawItems = [];\n }\n }\n if (!Array.isArray(rawItems)) {\n return;\n }\n return rawItems.map((item) => this.getOptionValue(this.itemValue(item)));\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue('', {\n noUpdateEvent: true\n });\n this.unset();\n }\n /**\n * Check if a component is eligible for multiple validation\n *\n * @return {boolean}\n */\n validateMultiple() {\n // Select component will contain one input when flagged as multiple.\n return false;\n }\n /**\n * Output this select dropdown as a string value.\n * @return {*}\n */\n isBooleanOrNumber(value) {\n return typeof value === 'number' || typeof value === 'boolean';\n }\n getNormalizedValues() {\n if (!this.component || !this.component.data || !this.component.data.values) {\n return;\n }\n return this.component.data.values.map(value => ({ label: value.label, value: String(this.normalizeSingleValue(value.value)) }));\n }\n asString(value, options = {}) {\n var _a;\n value = value !== null && value !== void 0 ? value : this.getValue();\n //need to convert values to strings to be able to compare values with available options that are strings\n const convertToString = (data, valueProperty) => {\n if (valueProperty) {\n if (Array.isArray(data)) {\n data.forEach((item) => item[valueProperty] = item[valueProperty].toString());\n }\n else {\n data[valueProperty] = data[valueProperty].toString();\n }\n return data;\n }\n if (this.isBooleanOrNumber(data)) {\n data = data.toString();\n }\n if (Array.isArray(data) && data.some(item => this.isBooleanOrNumber(item))) {\n data = data.map(item => {\n if (this.isBooleanOrNumber(item)) {\n item = item.toString();\n }\n });\n }\n return data;\n };\n value = convertToString(value);\n if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {\n const { items, valueProperty, } = this.component.dataSrc === 'values'\n ? {\n items: convertToString(this.getNormalizedValues(), 'value'),\n valueProperty: 'value',\n }\n : {\n items: convertToString(this.getCustomItems(), this.valueProperty),\n valueProperty: this.valueProperty,\n };\n const getFromValues = () => {\n const initialValue = lodash_1.default.find(items, [valueProperty, value]);\n const values = this.defaultSchema.data.values || [];\n return lodash_1.default.isEqual(initialValue, values[0]) ? '-' : initialValue;\n };\n value = (this.component.multiple && Array.isArray(value))\n ? lodash_1.default.filter(items, (item) => value.includes(item.value))\n : valueProperty\n ? (_a = getFromValues()) !== null && _a !== void 0 ? _a : { value, label: value }\n : value;\n }\n if (lodash_1.default.isString(value)) {\n return value;\n }\n const getTemplateValue = (v) => {\n const itemTemplate = this.itemTemplate(v);\n return options.csv && itemTemplate\n ? (0, utils_1.unescapeHTML)(itemTemplate)\n : itemTemplate;\n };\n if (Array.isArray(value)) {\n const items = [];\n value.forEach(item => items.push(getTemplateValue(item)));\n if (this.component.dataSrc === 'resource' && items.length > 0) {\n return items.join(', ');\n }\n else if (items.length > 0) {\n return items.join('<br />');\n }\n else {\n return '-';\n }\n }\n if (this.isEntireObjectDisplay() && lodash_1.default.isObject(value)) {\n return JSON.stringify(value);\n }\n return !lodash_1.default.isNil(value)\n ? getTemplateValue(value)\n : '-';\n }\n detach() {\n var _a, _b;\n this.off('blur');\n if (this.choices) {\n if ((_b = (_a = this.choices.containerOuter) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.parentNode) {\n this.choices.destroy();\n }\n this.choices = null;\n }\n super.detach();\n }\n focus() {\n if (this.focusableElement) {\n super.focus.call(this);\n this.focusableElement.focus();\n }\n }\n setErrorClasses(elements, dirty, hasError, hasMessages, element = this.element) {\n super.setErrorClasses(elements, dirty, hasError, hasMessages, element);\n if (this.choices) {\n super.setErrorClasses([this.choices.containerInner.element], dirty, hasError, hasMessages, element);\n }\n else {\n super.setErrorClasses([this.refs.selectContainer], dirty, hasError, hasMessages, element);\n }\n }\n}\nexports[\"default\"] = SelectComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/select/Select.js?");
|
6984
6984
|
|
6985
6985
|
/***/ }),
|
6986
6986
|
|
@@ -10892,7 +10892,7 @@ eval("\nvar parent = __webpack_require__(/*! ../../es/object/from-entries */ \".
|
|
10892
10892
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
10893
10893
|
|
10894
10894
|
"use strict";
|
10895
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.FormBuilder = exports.Form = exports.Formio = void 0;\nconst CDN_js_1 = __importDefault(__webpack_require__(/*! ./CDN.js */ \"./lib/cjs/CDN.js\"));\nclass Formio {\n static setLicense(license, norecurse = false) {\n _a.license = license;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setLicense(license);\n }\n }\n static setBaseUrl(url, norecurse = false) {\n _a.baseUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setBaseUrl(url);\n }\n }\n static setApiUrl(url, norecurse = false) {\n _a.baseUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setApiUrl(url);\n }\n }\n static setProjectUrl(url, norecurse = false) {\n _a.projectUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setProjectUrl(url);\n }\n }\n static setAppUrl(url, norecurse = false) {\n _a.projectUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setAppUrl(url);\n }\n }\n static setPathType(type, norecurse = false) {\n _a.pathType = type;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setPathType(type);\n }\n }\n static debug(...args) {\n if (_a.config.debug) {\n console.log(...args);\n }\n }\n static clearCache() {\n if (_a.FormioClass) {\n _a.FormioClass.clearCache();\n }\n }\n static global(prop, flag = '') {\n const globalValue = window[prop];\n if (flag && globalValue && !globalValue[flag]) {\n return null;\n }\n _a.debug(`Getting global ${prop}`, globalValue);\n return globalValue;\n }\n static use(module) {\n if (_a.FormioClass && _a.FormioClass.isRenderer) {\n _a.FormioClass.use(module);\n }\n else {\n _a.modules.push(module);\n }\n }\n static createElement(type, attrs, children) {\n const element = document.createElement(type);\n Object.keys(attrs).forEach(key => {\n element.setAttribute(key, attrs[key]);\n });\n (children || []).forEach(child => {\n element.appendChild(_a.createElement(child.tag, child.attrs, child.children));\n });\n return element;\n }\n static addScript(wrapper, src, name, flag = '') {\n return __awaiter(this, void 0, void 0, function* () {\n if (!src) {\n return Promise.resolve();\n }\n if (typeof src !== 'string' && src.length) {\n return Promise.all(src.map(ref => _a.addScript(wrapper, ref)));\n }\n if (name && _a.global(name, flag)) {\n _a.debug(`${name} already loaded.`);\n return Promise.resolve(_a.global(name));\n }\n _a.debug('Adding Script', src);\n try {\n wrapper.appendChild(_a.createElement('script', {\n src\n }));\n }\n catch (err) {\n _a.debug(err);\n return Promise.resolve();\n }\n if (!name) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n _a.debug(`Waiting to load ${name}`);\n const wait = setInterval(() => {\n if (_a.global(name, flag)) {\n clearInterval(wait);\n _a.debug(`${name} loaded.`);\n resolve(_a.global(name));\n }\n }, 100);\n });\n });\n }\n static addStyles(wrapper, href) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!href) {\n return;\n }\n if (typeof href !== 'string' && href.length) {\n href.forEach(ref => _a.addStyles(wrapper, ref));\n return;\n }\n _a.debug('Adding Styles', href);\n wrapper.appendChild(_a.createElement('link', {\n rel: 'stylesheet',\n href\n }));\n });\n }\n static submitDone(instance, submission) {\n return __awaiter(this, void 0, void 0, function* () {\n _a.debug('Submision Complete', submission);\n const successMessage = (_a.config.success || '').toString();\n if (successMessage && successMessage.toLowerCase() !== 'false' && instance.element) {\n instance.element.innerHTML = `<div class=\"alert-success\" role=\"alert\">${successMessage}</div>`;\n }\n let returnUrl = _a.config.redirect;\n // Allow form based configuration for return url.\n if (!returnUrl &&\n (instance._form &&\n instance._form.settings &&\n (instance._form.settings.returnUrl ||\n instance._form.settings.redirect))) {\n _a.debug('Return url found in form configuration');\n returnUrl = instance._form.settings.returnUrl || instance._form.settings.redirect;\n }\n if (returnUrl) {\n const formSrc = instance.formio ? instance.formio.formUrl : '';\n const hasQuery = !!returnUrl.match(/\\?/);\n const isOrigin = returnUrl.indexOf(location.origin) === 0;\n returnUrl += hasQuery ? '&' : '?';\n returnUrl += `sub=${submission._id}`;\n if (!isOrigin && formSrc) {\n returnUrl += `&form=${encodeURIComponent(formSrc)}`;\n }\n _a.debug('Return URL', returnUrl);\n window.location.href = returnUrl;\n if (isOrigin) {\n window.location.reload();\n }\n }\n });\n }\n // Return the full script if the builder is being used.\n static formioScript(script, builder) {\n builder = builder || _a.config.includeBuilder;\n if (_a.fullAdded || builder) {\n _a.fullAdded = true;\n return script.replace('formio.form', 'formio.full');\n }\n return script;\n }\n static addLibrary(wrapper, lib, name) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!lib) {\n return;\n }\n if (lib.dependencies) {\n for (let i = 0; i < lib.dependencies.length; i++) {\n yield _a.addLibrary(wrapper, _a.cdn.libs[lib.dependencies[i]]);\n }\n }\n if (lib.css) {\n yield _a.addStyles(wrapper, lib.css);\n }\n if (lib.js) {\n const module = yield _a.addScript(wrapper, lib.js, lib.use ? name : false);\n if (lib.use) {\n _a.debug(`Using ${name}`);\n const options = lib.options || {};\n if (!options.license && _a.license) {\n options.license = _a.license;\n }\n _a.use((typeof lib.use === 'function' ? lib.use(module) : module), options);\n }\n }\n });\n }\n static addLoader(wrapper) {\n return __awaiter(this, void 0, void 0, function* () {\n wrapper.appendChild(_a.createElement('div', {\n 'class': 'formio-loader'\n }, [{\n tag: 'div',\n attrs: {\n class: 'loader-wrapper'\n },\n children: [{\n tag: 'div',\n attrs: {\n class: 'loader text-center'\n }\n }]\n }]));\n });\n }\n // eslint-disable-next-line max-statements\n static init(element, options = {}, builder = false) {\n return __awaiter(this, void 0, void 0, function* () {\n _a.cdn = new CDN_js_1.default(_a.config.cdn, _a.config.cdnUrls || {});\n _a.config.libs = _a.config.libs || {\n uswds: {\n dependencies: ['fontawesome'],\n js: `${_a.cdn.uswds}/uswds.min.js`,\n css: `${_a.cdn.uswds}/uswds.min.css`,\n use: true\n },\n fontawesome: {\n css: `${_a.cdn['font-awesome']}/css/font-awesome.min.css`\n },\n bootstrap4: {\n dependencies: ['fontawesome'],\n css: `${_a.cdn.bootstrap4}/css/bootstrap.min.css`\n },\n bootstrap: {\n dependencies: ['bootstrap-icons'],\n css: `${_a.cdn.bootstrap}/css/bootstrap.min.css`\n },\n 'bootstrap-icons': {\n css: `${_a.cdn['bootstrap-icons']}/css/bootstrap-icons.css`\n }\n };\n const id = _a.config.id || `formio-${Math.random().toString(36).substring(7)}`;\n // Create a new wrapper and add the element inside of a new wrapper.\n let wrapper = _a.createElement('div', {\n 'id': `${id}-wrapper`\n });\n element.parentNode.insertBefore(wrapper, element);\n // If we include the libraries, then we will attempt to run this in shadow dom.\n const useShadowDom = _a.config.includeLibs && (typeof wrapper.attachShadow === 'function');\n if (useShadowDom) {\n wrapper = wrapper.attachShadow({\n mode: 'open'\n });\n options.shadowRoot = wrapper;\n }\n element.parentNode.removeChild(element);\n wrapper.appendChild(element);\n // If this is inside of shadow dom, then we need to add the styles and scripts to the shadow dom.\n const libWrapper = useShadowDom ? wrapper : document.body;\n // Load the renderer styles.\n yield _a.addStyles(libWrapper, _a.config.embedCSS || `${_a.cdn.js}/formio.embed.css`);\n // Add a loader.\n _a.addLoader(wrapper);\n const formioSrc = _a.config.full ? 'formio.full' : 'formio.form';\n const renderer = _a.config.debug ? formioSrc : `${formioSrc}.min`;\n _a.FormioClass = yield _a.addScript(libWrapper, _a.formioScript(_a.config.script || `${_a.cdn.js}/${renderer}.js`, builder), 'Formio', builder ? 'isBuilder' : 'isRenderer');\n _a.FormioClass.cdn = _a.cdn;\n _a.FormioClass.setBaseUrl(options.baseUrl || _a.baseUrl || _a.config.base);\n _a.FormioClass.setProjectUrl(options.projectUrl || _a.projectUrl || _a.config.project);\n _a.FormioClass.language = _a.language;\n _a.setLicense(_a.license || _a.config.license || false);\n _a.modules.forEach((module) => {\n _a.FormioClass.use(module);\n });\n if (_a.icons) {\n _a.FormioClass.icons = _a.icons;\n }\n if (_a.pathType) {\n _a.FormioClass.setPathType(_a.pathType);\n }\n // Add libraries if they wish to include the libs.\n if (_a.config.template && _a.config.includeLibs) {\n yield _a.addLibrary(libWrapper, _a.config.libs[_a.config.template], _a.config.template);\n }\n // Add the premium modules.\n if (_a.config.premium) {\n _a.config.modules.premium = _a.config.premium;\n }\n // Allow adding dynamic modules.\n if (_a.config.modules) {\n for (const name in _a.config.modules) {\n const lib = _a.config.modules[name];\n lib.use = lib.use || true;\n yield _a.addLibrary(libWrapper, lib, name);\n }\n }\n yield _a.addStyles(libWrapper, _a.formioScript(_a.config.style || `${_a.cdn.js}/${renderer}.css`, builder));\n if (_a.config.before) {\n yield _a.config.before(_a.FormioClass, element, _a.config);\n }\n _a.FormioClass.license = true;\n _a._formioReady(_a.FormioClass);\n return wrapper;\n });\n }\n // Called after an instance has been created.\n static afterCreate(instance, wrapper, readyEvent) {\n return __awaiter(this, void 0, void 0, function* () {\n const loader = wrapper.querySelector('.formio-loader');\n if (loader) {\n wrapper.removeChild(loader);\n }\n _a.FormioClass.events.emit(readyEvent, instance);\n if (_a.config.after) {\n _a.debug('Calling ready callback');\n _a.config.after(instance, _a.config);\n }\n return instance;\n });\n }\n // Create a new form.\n static createForm(element, form, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n if (_a.FormioClass) {\n return _a.FormioClass.createForm(element, form, Object.assign(Object.assign({}, options), { noLoader: true }));\n }\n const wrapper = yield _a.init(element, options);\n return _a.FormioClass.createForm(element, form, Object.assign(Object.assign({}, options), { noLoader: true })).then((instance) => {\n // Set the default submission data.\n if (_a.config.submission) {\n _a.debug('Setting submission', _a.config.submission);\n instance.submission = _a.config.submission;\n }\n // Call the after create method.\n _a.afterCreate(instance, wrapper, 'formEmbedded');\n return instance;\n });\n });\n }\n // Create a form builder.\n static builder(element, form, options = {}) {\n var _b;\n return __awaiter(this, void 0, void 0, function* () {\n if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.builder) {\n return _a.FormioClass.builder(element, form, options);\n }\n const wrapper = yield _a.init(element, options, true);\n return _a.FormioClass.builder(element, form, options).then((instance) => {\n _a.afterCreate(instance, wrapper, 'builderEmbedded');\n return instance;\n });\n });\n }\n}\nexports.Formio = Formio;\n_a = Formio;\nFormio.FormioClass = null;\nFormio.config = {};\nFormio.modules = [];\nFormio.icons = '';\nFormio.license = '';\nFormio.formioReady = new Promise((ready, reject) => {\n _a._formioReady = ready;\n _a._formioReadyReject = reject;\n});\nFormio.version = '5.0.0-rc.47';\n// Create a report.\nFormio.Report = {\n create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {\n var _b;\n if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.Report) {\n return _a.FormioClass.Report.create(element, submission, options);\n }\n const wrapper = yield _a.init(element, options, true);\n return _a.FormioClass.Report.create(element, submission, options).then((instance) => {\n _a.afterCreate(instance, wrapper, 'reportEmbedded');\n return instance;\n });\n })\n};\nCDN_js_1.default.defaultCDN = Formio.version.includes('rc') ? 'https://cdn.test-form.io' : 'https://cdn.form.io';\nclass Form {\n constructor(element, form, options) {\n this.form = form;\n this.element = element;\n this.options = options || {};\n this.init();\n this.instance = {\n proxy: true,\n ready: this.ready,\n destroy: () => { }\n };\n }\n init() {\n if (this.instance && !this.instance.proxy) {\n this.instance.destroy();\n }\n this.element.innerHTML = '';\n this.ready = this.create().then((instance) => {\n this.instance = instance;\n this.form = instance.form;\n return instance;\n });\n }\n create() {\n return Formio.createForm(this.element, this.form, this.options);\n }\n setForm(form) {\n this.form = form;\n if (this.instance) {\n this.instance.setForm(form);\n }\n }\n setDisplay(display) {\n if (this.instance.proxy) {\n return this.ready;\n }\n this.form.display = display;\n this.instance.destroy();\n this.ready = this.create().then((instance) => {\n this.instance = instance;\n this.setForm(this.form);\n });\n return this.ready;\n }\n}\nexports.Form = Form;\nclass FormBuilder extends Form {\n create() {\n return Formio.builder(this.element, this.form, this.options);\n }\n}\nexports.FormBuilder = FormBuilder;\nFormio.Form = Form;\nFormio.FormBuilder = FormBuilder;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Embed.js?");
|
10895
|
+
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.FormBuilder = exports.Form = exports.Formio = void 0;\nconst CDN_js_1 = __importDefault(__webpack_require__(/*! ./CDN.js */ \"./lib/cjs/CDN.js\"));\nclass Formio {\n static setLicense(license, norecurse = false) {\n _a.license = license;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setLicense(license);\n }\n }\n static setBaseUrl(url, norecurse = false) {\n _a.baseUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setBaseUrl(url);\n }\n }\n static setApiUrl(url, norecurse = false) {\n _a.baseUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setApiUrl(url);\n }\n }\n static setProjectUrl(url, norecurse = false) {\n _a.projectUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setProjectUrl(url);\n }\n }\n static setAppUrl(url, norecurse = false) {\n _a.projectUrl = url;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setAppUrl(url);\n }\n }\n static setPathType(type, norecurse = false) {\n _a.pathType = type;\n if (!norecurse && _a.FormioClass) {\n _a.FormioClass.setPathType(type);\n }\n }\n static debug(...args) {\n if (_a.config.debug) {\n console.log(...args);\n }\n }\n static clearCache() {\n if (_a.FormioClass) {\n _a.FormioClass.clearCache();\n }\n }\n static global(prop, flag = '') {\n const globalValue = window[prop];\n if (flag && globalValue && !globalValue[flag]) {\n return null;\n }\n _a.debug(`Getting global ${prop}`, globalValue);\n return globalValue;\n }\n static use(module) {\n if (_a.FormioClass && _a.FormioClass.isRenderer) {\n _a.FormioClass.use(module);\n }\n else {\n _a.modules.push(module);\n }\n }\n static createElement(type, attrs, children) {\n const element = document.createElement(type);\n Object.keys(attrs).forEach(key => {\n element.setAttribute(key, attrs[key]);\n });\n (children || []).forEach(child => {\n element.appendChild(_a.createElement(child.tag, child.attrs, child.children));\n });\n return element;\n }\n static addScript(wrapper, src, name, flag = '') {\n return __awaiter(this, void 0, void 0, function* () {\n if (!src) {\n return Promise.resolve();\n }\n if (typeof src !== 'string' && src.length) {\n return Promise.all(src.map(ref => _a.addScript(wrapper, ref)));\n }\n if (name && _a.global(name, flag)) {\n _a.debug(`${name} already loaded.`);\n return Promise.resolve(_a.global(name));\n }\n _a.debug('Adding Script', src);\n try {\n wrapper.appendChild(_a.createElement('script', {\n src\n }));\n }\n catch (err) {\n _a.debug(err);\n return Promise.resolve();\n }\n if (!name) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n _a.debug(`Waiting to load ${name}`);\n const wait = setInterval(() => {\n if (_a.global(name, flag)) {\n clearInterval(wait);\n _a.debug(`${name} loaded.`);\n resolve(_a.global(name));\n }\n }, 100);\n });\n });\n }\n static addStyles(wrapper, href) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!href) {\n return;\n }\n if (typeof href !== 'string' && href.length) {\n href.forEach(ref => _a.addStyles(wrapper, ref));\n return;\n }\n _a.debug('Adding Styles', href);\n wrapper.appendChild(_a.createElement('link', {\n rel: 'stylesheet',\n href\n }));\n });\n }\n static submitDone(instance, submission) {\n return __awaiter(this, void 0, void 0, function* () {\n _a.debug('Submision Complete', submission);\n const successMessage = (_a.config.success || '').toString();\n if (successMessage && successMessage.toLowerCase() !== 'false' && instance.element) {\n instance.element.innerHTML = `<div class=\"alert-success\" role=\"alert\">${successMessage}</div>`;\n }\n let returnUrl = _a.config.redirect;\n // Allow form based configuration for return url.\n if (!returnUrl &&\n (instance._form &&\n instance._form.settings &&\n (instance._form.settings.returnUrl ||\n instance._form.settings.redirect))) {\n _a.debug('Return url found in form configuration');\n returnUrl = instance._form.settings.returnUrl || instance._form.settings.redirect;\n }\n if (returnUrl) {\n const formSrc = instance.formio ? instance.formio.formUrl : '';\n const hasQuery = !!returnUrl.match(/\\?/);\n const isOrigin = returnUrl.indexOf(location.origin) === 0;\n returnUrl += hasQuery ? '&' : '?';\n returnUrl += `sub=${submission._id}`;\n if (!isOrigin && formSrc) {\n returnUrl += `&form=${encodeURIComponent(formSrc)}`;\n }\n _a.debug('Return URL', returnUrl);\n window.location.href = returnUrl;\n if (isOrigin) {\n window.location.reload();\n }\n }\n });\n }\n // Return the full script if the builder is being used.\n static formioScript(script, builder) {\n builder = builder || _a.config.includeBuilder;\n if (_a.fullAdded || builder) {\n _a.fullAdded = true;\n return script.replace('formio.form', 'formio.full');\n }\n return script;\n }\n static addLibrary(wrapper, lib, name) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!lib) {\n return;\n }\n if (lib.dependencies) {\n for (let i = 0; i < lib.dependencies.length; i++) {\n yield _a.addLibrary(wrapper, _a.cdn.libs[lib.dependencies[i]]);\n }\n }\n if (lib.css) {\n yield _a.addStyles(wrapper, lib.css);\n }\n if (lib.js) {\n const module = yield _a.addScript(wrapper, lib.js, lib.use ? name : false);\n if (lib.use) {\n _a.debug(`Using ${name}`);\n const options = lib.options || {};\n if (!options.license && _a.license) {\n options.license = _a.license;\n }\n _a.use((typeof lib.use === 'function' ? lib.use(module) : module), options);\n }\n }\n });\n }\n static addLoader(wrapper) {\n return __awaiter(this, void 0, void 0, function* () {\n wrapper.appendChild(_a.createElement('div', {\n 'class': 'formio-loader'\n }, [{\n tag: 'div',\n attrs: {\n class: 'loader-wrapper'\n },\n children: [{\n tag: 'div',\n attrs: {\n class: 'loader text-center'\n }\n }]\n }]));\n });\n }\n // eslint-disable-next-line max-statements\n static init(element, options = {}, builder = false) {\n return __awaiter(this, void 0, void 0, function* () {\n _a.cdn = new CDN_js_1.default(_a.config.cdn, _a.config.cdnUrls || {});\n _a.config.libs = _a.config.libs || {\n uswds: {\n dependencies: ['fontawesome'],\n js: `${_a.cdn.uswds}/uswds.min.js`,\n css: `${_a.cdn.uswds}/uswds.min.css`,\n use: true\n },\n fontawesome: {\n css: `${_a.cdn['font-awesome']}/css/font-awesome.min.css`\n },\n bootstrap4: {\n dependencies: ['fontawesome'],\n css: `${_a.cdn.bootstrap4}/css/bootstrap.min.css`\n },\n bootstrap: {\n dependencies: ['bootstrap-icons'],\n css: `${_a.cdn.bootstrap}/css/bootstrap.min.css`\n },\n 'bootstrap-icons': {\n css: `${_a.cdn['bootstrap-icons']}/css/bootstrap-icons.css`\n }\n };\n const id = _a.config.id || `formio-${Math.random().toString(36).substring(7)}`;\n // Create a new wrapper and add the element inside of a new wrapper.\n let wrapper = _a.createElement('div', {\n 'id': `${id}-wrapper`\n });\n element.parentNode.insertBefore(wrapper, element);\n // If we include the libraries, then we will attempt to run this in shadow dom.\n const useShadowDom = _a.config.includeLibs && (typeof wrapper.attachShadow === 'function');\n if (useShadowDom) {\n wrapper = wrapper.attachShadow({\n mode: 'open'\n });\n options.shadowRoot = wrapper;\n }\n element.parentNode.removeChild(element);\n wrapper.appendChild(element);\n // If this is inside of shadow dom, then we need to add the styles and scripts to the shadow dom.\n const libWrapper = useShadowDom ? wrapper : document.body;\n // Load the renderer styles.\n yield _a.addStyles(libWrapper, _a.config.embedCSS || `${_a.cdn.js}/formio.embed.css`);\n // Add a loader.\n _a.addLoader(wrapper);\n const formioSrc = _a.config.full ? 'formio.full' : 'formio.form';\n const renderer = _a.config.debug ? formioSrc : `${formioSrc}.min`;\n _a.FormioClass = yield _a.addScript(libWrapper, _a.formioScript(_a.config.script || `${_a.cdn.js}/${renderer}.js`, builder), 'Formio', builder ? 'isBuilder' : 'isRenderer');\n _a.FormioClass.cdn = _a.cdn;\n _a.FormioClass.setBaseUrl(options.baseUrl || _a.baseUrl || _a.config.base);\n _a.FormioClass.setProjectUrl(options.projectUrl || _a.projectUrl || _a.config.project);\n _a.FormioClass.language = _a.language;\n _a.setLicense(_a.license || _a.config.license || false);\n _a.modules.forEach((module) => {\n _a.FormioClass.use(module);\n });\n if (_a.icons) {\n _a.FormioClass.icons = _a.icons;\n }\n if (_a.pathType) {\n _a.FormioClass.setPathType(_a.pathType);\n }\n // Add libraries if they wish to include the libs.\n if (_a.config.template && _a.config.includeLibs) {\n yield _a.addLibrary(libWrapper, _a.config.libs[_a.config.template], _a.config.template);\n }\n // Add the premium modules.\n if (_a.config.premium) {\n _a.config.modules.premium = _a.config.premium;\n }\n // Allow adding dynamic modules.\n if (_a.config.modules) {\n for (const name in _a.config.modules) {\n const lib = _a.config.modules[name];\n lib.use = lib.use || true;\n yield _a.addLibrary(libWrapper, lib, name);\n }\n }\n yield _a.addStyles(libWrapper, _a.formioScript(_a.config.style || `${_a.cdn.js}/${renderer}.css`, builder));\n if (_a.config.before) {\n yield _a.config.before(_a.FormioClass, element, _a.config);\n }\n _a.FormioClass.license = true;\n _a._formioReady(_a.FormioClass);\n return wrapper;\n });\n }\n // Called after an instance has been created.\n static afterCreate(instance, wrapper, readyEvent) {\n return __awaiter(this, void 0, void 0, function* () {\n const loader = wrapper.querySelector('.formio-loader');\n if (loader) {\n wrapper.removeChild(loader);\n }\n _a.FormioClass.events.emit(readyEvent, instance);\n if (_a.config.after) {\n _a.debug('Calling ready callback');\n _a.config.after(instance, _a.config);\n }\n return instance;\n });\n }\n // Create a new form.\n static createForm(element, form, options = {}) {\n return __awaiter(this, void 0, void 0, function* () {\n if (_a.FormioClass) {\n return _a.FormioClass.createForm(element, form, Object.assign(Object.assign({}, options), { noLoader: true }));\n }\n const wrapper = yield _a.init(element, options);\n return _a.FormioClass.createForm(element, form, Object.assign(Object.assign({}, options), { noLoader: true })).then((instance) => {\n // Set the default submission data.\n if (_a.config.submission) {\n _a.debug('Setting submission', _a.config.submission);\n instance.submission = _a.config.submission;\n }\n // Call the after create method.\n _a.afterCreate(instance, wrapper, 'formEmbedded');\n return instance;\n });\n });\n }\n // Create a form builder.\n static builder(element, form, options = {}) {\n var _b;\n return __awaiter(this, void 0, void 0, function* () {\n if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.builder) {\n return _a.FormioClass.builder(element, form, options);\n }\n const wrapper = yield _a.init(element, options, true);\n return _a.FormioClass.builder(element, form, options).then((instance) => {\n _a.afterCreate(instance, wrapper, 'builderEmbedded');\n return instance;\n });\n });\n }\n}\nexports.Formio = Formio;\n_a = Formio;\nFormio.FormioClass = null;\nFormio.config = {};\nFormio.modules = [];\nFormio.icons = '';\nFormio.license = '';\nFormio.formioReady = new Promise((ready, reject) => {\n _a._formioReady = ready;\n _a._formioReadyReject = reject;\n});\nFormio.version = '5.0.0-rc.48';\n// Create a report.\nFormio.Report = {\n create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {\n var _b;\n if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.Report) {\n return _a.FormioClass.Report.create(element, submission, options);\n }\n const wrapper = yield _a.init(element, options, true);\n return _a.FormioClass.Report.create(element, submission, options).then((instance) => {\n _a.afterCreate(instance, wrapper, 'reportEmbedded');\n return instance;\n });\n })\n};\nCDN_js_1.default.defaultCDN = Formio.version.includes('rc') ? 'https://cdn.test-form.io' : 'https://cdn.form.io';\nclass Form {\n constructor(element, form, options) {\n this.form = form;\n this.element = element;\n this.options = options || {};\n this.init();\n this.instance = {\n proxy: true,\n ready: this.ready,\n destroy: () => { }\n };\n }\n init() {\n if (this.instance && !this.instance.proxy) {\n this.instance.destroy();\n }\n this.element.innerHTML = '';\n this.ready = this.create().then((instance) => {\n this.instance = instance;\n this.form = instance.form;\n return instance;\n });\n }\n create() {\n return Formio.createForm(this.element, this.form, this.options);\n }\n setForm(form) {\n this.form = form;\n if (this.instance) {\n this.instance.setForm(form);\n }\n }\n setDisplay(display) {\n if (this.instance.proxy) {\n return this.ready;\n }\n this.form.display = display;\n this.instance.destroy();\n this.ready = this.create().then((instance) => {\n this.instance = instance;\n this.setForm(this.form);\n });\n return this.ready;\n }\n}\nexports.Form = Form;\nclass FormBuilder extends Form {\n create() {\n return Formio.builder(this.element, this.form, this.options);\n }\n}\nexports.FormBuilder = FormBuilder;\nFormio.Form = Form;\nFormio.FormBuilder = FormBuilder;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Embed.js?");
|
10896
10896
|
|
10897
10897
|
/***/ }),
|
10898
10898
|
|
@@ -10903,7 +10903,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
10903
10903
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
10904
10904
|
|
10905
10905
|
"use strict";
|
10906
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Formio = void 0;\nconst sdk_1 = __webpack_require__(/*! @formio/core/sdk */ \"./node_modules/@formio/core/lib/sdk/index.js\");\nObject.defineProperty(exports, \"Formio\", ({ enumerable: true, get: function () { return sdk_1.Formio; } }));\nconst Embed_1 = __webpack_require__(/*! ./Embed */ \"./lib/cjs/Embed.js\");\nconst CDN_1 = __importDefault(__webpack_require__(/*! ./CDN */ \"./lib/cjs/CDN.js\"));\nconst providers_1 = __importDefault(__webpack_require__(/*! ./providers */ \"./lib/cjs/providers/index.js\"));\nsdk_1.Formio.cdn = new CDN_1.default();\nsdk_1.Formio.Providers = providers_1.default;\nsdk_1.Formio.version = '5.0.0-rc.
|
10906
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Formio = void 0;\nconst sdk_1 = __webpack_require__(/*! @formio/core/sdk */ \"./node_modules/@formio/core/lib/sdk/index.js\");\nObject.defineProperty(exports, \"Formio\", ({ enumerable: true, get: function () { return sdk_1.Formio; } }));\nconst Embed_1 = __webpack_require__(/*! ./Embed */ \"./lib/cjs/Embed.js\");\nconst CDN_1 = __importDefault(__webpack_require__(/*! ./CDN */ \"./lib/cjs/CDN.js\"));\nconst providers_1 = __importDefault(__webpack_require__(/*! ./providers */ \"./lib/cjs/providers/index.js\"));\nsdk_1.Formio.cdn = new CDN_1.default();\nsdk_1.Formio.Providers = providers_1.default;\nsdk_1.Formio.version = '5.0.0-rc.48';\nCDN_1.default.defaultCDN = sdk_1.Formio.version.includes('rc') ? 'https://cdn.test-form.io' : 'https://cdn.form.io';\nconst isNil = (val) => val === null || val === undefined;\nsdk_1.Formio.prototype.uploadFile = function (storage, file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, uploadStartCallback, abortCallback, multipartOptions) {\n const requestArgs = {\n provider: storage,\n method: 'upload',\n file: file,\n fileName: fileName,\n dir: dir\n };\n fileKey = fileKey || 'file';\n const request = sdk_1.Formio.pluginWait('preRequest', requestArgs)\n .then(() => {\n return sdk_1.Formio.pluginGet('fileRequest', requestArgs)\n .then((result) => {\n if (storage && isNil(result)) {\n const Provider = providers_1.default.getProvider('storage', storage);\n if (Provider) {\n const provider = new Provider(this);\n if (uploadStartCallback) {\n uploadStartCallback();\n }\n return provider.uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback, multipartOptions);\n }\n else {\n throw ('Storage provider not found');\n }\n }\n return result || { url: '' };\n });\n });\n return sdk_1.Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);\n};\nsdk_1.Formio.prototype.downloadFile = function (file, options) {\n const requestArgs = {\n method: 'download',\n file: file\n };\n const request = sdk_1.Formio.pluginWait('preRequest', requestArgs)\n .then(() => {\n return sdk_1.Formio.pluginGet('fileRequest', requestArgs)\n .then((result) => {\n if (file.storage && isNil(result)) {\n const Provider = providers_1.default.getProvider('storage', file.storage);\n if (Provider) {\n const provider = new Provider(this);\n return provider.downloadFile(file, options);\n }\n else {\n throw ('Storage provider not found');\n }\n }\n return result || { url: '' };\n });\n });\n return sdk_1.Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);\n};\nsdk_1.Formio.prototype.deleteFile = function (file, options) {\n const requestArgs = {\n method: 'delete',\n file: file\n };\n const request = sdk_1.Formio.pluginWait('preRequest', requestArgs)\n .then(() => {\n return sdk_1.Formio.pluginGet('fileRequest', requestArgs)\n .then((result) => {\n if (file.storage && isNil(result)) {\n const Provider = providers_1.default.getProvider('storage', file.storage);\n if (Provider) {\n const provider = new Provider(this);\n return provider.deleteFile(file, options);\n }\n else {\n throw ('Storage provider not found');\n }\n }\n return result || { url: '' };\n });\n });\n return sdk_1.Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);\n};\n// Esnure we proxy the following methods to the FormioEmbed class.\n['setBaseUrl', 'setApiUrl', 'setAppUrl', 'setProjectUrl', 'setPathType', 'setLicense'].forEach((fn) => {\n const baseFn = sdk_1.Formio[fn];\n sdk_1.Formio[fn] = function (arg) {\n const retVal = Embed_1.Formio[fn](arg, true);\n return baseFn ? baseFn.call(this, arg) : retVal;\n };\n});\n// For reverse compatability.\nsdk_1.Formio.Promise = Promise;\nsdk_1.Formio.formioReady = Embed_1.Formio.formioReady;\nsdk_1.Formio.config = Embed_1.Formio.config;\nsdk_1.Formio.builder = Embed_1.Formio.builder;\nsdk_1.Formio.Report = Embed_1.Formio.Report;\nsdk_1.Formio.Form = Embed_1.Formio.Form;\nsdk_1.Formio.FormBuilder = Embed_1.Formio.FormBuilder;\nsdk_1.Formio.use = Embed_1.Formio.use;\nsdk_1.Formio.createForm = Embed_1.Formio.createForm;\nsdk_1.Formio.submitDone = Embed_1.Formio.submitDone;\nsdk_1.Formio.addLibrary = Embed_1.Formio.addLibrary;\nsdk_1.Formio.addLoader = Embed_1.Formio.addLoader;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Formio.js?");
|
10907
10907
|
|
10908
10908
|
/***/ }),
|
10909
10909
|
|