@formio/js 5.0.0-rc.76 → 5.0.0-rc.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +9 -9
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -1
- package/dist/formio.full.js +9 -9
- 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.min.js.LICENSE.txt +1 -1
- package/lib/cjs/components/_classes/multivalue/Multivalue.d.ts +0 -1
- package/lib/cjs/components/_classes/multivalue/Multivalue.js +43 -25
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +1 -0
- package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +6 -0
- package/lib/cjs/components/address/Address.d.ts +6 -0
- package/lib/cjs/components/address/Address.js +7 -1
- package/lib/cjs/components/datagrid/DataGrid.js +1 -0
- package/lib/cjs/components/datagrid/fixtures/comp11.d.ts +50 -0
- package/lib/cjs/components/datagrid/fixtures/comp11.js +55 -0
- package/lib/cjs/components/datagrid/fixtures/index.d.ts +2 -1
- package/lib/cjs/components/datagrid/fixtures/index.js +5 -1
- package/lib/cjs/components/editgrid/EditGrid.js +1 -0
- package/lib/cjs/components/select/Select.d.ts +38 -0
- package/lib/cjs/components/select/Select.js +10 -0
- package/lib/cjs/components/select/fixtures/comp25.d.ts +44 -0
- package/lib/cjs/components/select/fixtures/comp25.js +59 -0
- package/lib/cjs/components/select/fixtures/index.d.ts +2 -1
- package/lib/cjs/components/select/fixtures/index.js +3 -1
- package/lib/cjs/components/tags/Tags.js +3 -3
- package/lib/mjs/components/_classes/multivalue/Multivalue.d.ts +0 -1
- package/lib/mjs/components/_classes/multivalue/Multivalue.js +43 -25
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +1 -0
- package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +6 -0
- package/lib/mjs/components/address/Address.d.ts +6 -0
- package/lib/mjs/components/address/Address.js +10 -1
- package/lib/mjs/components/datagrid/DataGrid.js +1 -0
- package/lib/mjs/components/datagrid/fixtures/comp11.d.ts +50 -0
- package/lib/mjs/components/datagrid/fixtures/comp11.js +53 -0
- package/lib/mjs/components/datagrid/fixtures/index.d.ts +2 -1
- package/lib/mjs/components/datagrid/fixtures/index.js +3 -1
- package/lib/mjs/components/editgrid/EditGrid.js +1 -0
- package/lib/mjs/components/select/Select.d.ts +38 -0
- package/lib/mjs/components/select/Select.js +13 -1
- package/lib/mjs/components/select/fixtures/comp25.d.ts +44 -0
- package/lib/mjs/components/select/fixtures/comp25.js +57 -0
- package/lib/mjs/components/select/fixtures/index.d.ts +2 -1
- package/lib/mjs/components/select/fixtures/index.js +2 -1
- package/lib/mjs/components/tags/Tags.js +3 -3
- package/package.json +2 -2
package/dist/formio.full.js
CHANGED
@@ -5633,7 +5633,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
5633
5633
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5634
5634
|
|
5635
5635
|
"use strict";
|
5636
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass Multivalue extends Field_1.default {\n get dataValue() {\n const parent = super.dataValue;\n if (!parent && this.component.multiple) {\n return [];\n }\n return parent;\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get defaultValue() {\n let value = super.defaultValue;\n if (this.component.multiple) {\n if (lodash_1.default.isArray(value)) {\n value = !value.length ? [super.emptyValue] : value;\n }\n else {\n value = [value];\n }\n }\n return value;\n }\n get addAnother() {\n return this.t(this.component.addAnother || 'Add Another');\n }\n useWrapper() {\n return this.component.hasOwnProperty('multiple') && this.component.multiple;\n }\n /**\n * @returns {Field} - The created field.\n */\n render() {\n // If single value field.\n if (!this.useWrapper()) {\n return super.render(`<div ${this._referenceAttributeName}=\"element\">\n ${this.renderElement(this.component.type !== 'hidden' ? this.dataValue : '')}\n </div>`);\n }\n // Make sure dataValue is in the correct array format.\n let dataValue = this.dataValue;\n if (!Array.isArray(dataValue)) {\n dataValue = dataValue ? [dataValue] : [];\n }\n // If multiple value field.\n return super.render(this.renderTemplate('multiValueTable', {\n rows: dataValue.map(this.renderRow.bind(this)).join(''),\n disabled: this.disabled,\n addAnother: this.addAnother,\n }));\n }\n renderElement() {\n return '';\n }\n /**\n * Renders a single row for multi-value components.\n * @param {any} value - The value associated with the row to render.\n * @param {number} index - The index of the row in the multi-value list.\n * @returns {any} Returns the HTML string representation of the row.\n */\n renderRow(value, index) {\n return this.renderTemplate('multiValueRow', {\n index,\n disabled: this.disabled,\n element: `${this.renderElement(value, index)}`,\n });\n }\n /**\n * @param {HTMLElement} dom - The DOM element to which the component will attach.\n * @returns {Promise} - Promise that resolves when all asynchronous tasks that have finished.\n */\n attach(dom) {\n const superAttach = super.attach(dom);\n this.loadRefs(dom, {\n addButton: 'multiple',\n input: 'multiple',\n removeRow: 'multiple',\n mask: 'multiple',\n select: 'multiple',\n });\n const promises = [];\n this.refs.input.forEach((element, index) => {\n promises.push(this.attachElement.call(this, element, index));\n });\n if (!this.component.multiple) {\n return Promise.all(promises);\n }\n this.refs.removeRow.forEach((removeButton, index) => {\n this.addEventListener(removeButton, 'click', (event) => {\n event.preventDefault();\n this.removeValue(index);\n });\n });\n // If single value field.\n this.refs.addButton.forEach((addButton) => {\n this.addEventListener(addButton, 'click', (event) => {\n event.preventDefault();\n this.addValue();\n });\n });\n return superAttach.then(() => {\n return Promise.all(promises);\n });\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n if (this.refs.input && this.refs.input.length) {\n this.refs.input.forEach((input) => {\n if (input.mask) {\n input.mask.destroy ? input.mask.destroy() : input.mask.remove();\n }\n if (input.widget) {\n input.widget.destroy();\n }\n });\n }\n if (this.refs.mask && this.refs.mask.length) {\n this.refs.mask.forEach((input) => {\n if (input.mask) {\n input.mask.destroy ? input.mask.destroy() : input.mask.remove();\n }\n });\n }\n super.detach();\n }\n /**\n * Attach inputs to the element.\n * @param {HTMLElement} element - The element to attach.\n * @param {number} index - The index of the element to attach.\n */\n attachElement(element, index) {\n this.addEventListener(element, this.inputInfo.changeEvent, () => {\n // Delay update slightly to give input mask a chance to run.\n const textCase = lodash_1.default.get(this.component, 'case', 'mixed');\n if (textCase !== 'mixed') {\n const { selectionStart, selectionEnd, } = element;\n if (textCase === 'uppercase' && element.value) {\n element.value = element.value.toUpperCase();\n }\n if (textCase === 'lowercase' && element.value) {\n element.value = element.value.toLowerCase();\n }\n if (element.selectionStart && element.selectionEnd) {\n element.selectionStart = selectionStart;\n element.selectionEnd = selectionEnd;\n }\n }\n try {\n this.saveCaretPosition(element, index);\n }\n catch (err) {\n console.warn('An error occurred while trying to save caret position', err);\n }\n // If a mask is present, delay the update to allow mask to update first.\n if (element.mask) {\n setTimeout(() => {\n return this.updateValue(null, {\n modified: (this.component.type !== 'hidden')\n }, index);\n }, 1);\n }\n else {\n return this.updateValue(null, {\n modified: (this.component.type !== 'hidden')\n }, index);\n }\n });\n if (!this.attachMultiMask(index)) {\n const applyMask = () => {\n this.setInputMask(element);\n const valueMask = this.component.inputMask;\n const displayMask = this.component.displayMask;\n if (valueMask && displayMask && displayMask !== valueMask && this.refs.valueMaskInput) {\n this.setInputMask(this.refs.valueMaskInput, valueMask);\n }\n };\n if (this.inputInfo.changeEvent === 'blur') {\n this.addEventListener(element, this.inputInfo.changeEvent, () => {\n applyMask();\n this.dataValue = this.refs.input[0].value;\n if (this.checkComponentValidity()) {\n this.updateComponentValue(this.refs.input[0].value);\n }\n });\n }\n else {\n applyMask();\n }\n }\n }\n /**\n * Event handler for selecting a mask from a dropdown.\n * @param {Event} event - Event triggered by changing the selected option in mask.\n */\n onSelectMaskHandler(event) {\n this.updateMask(event.target.maskInput, this.getMaskPattern(event.target.value));\n }\n /**\n * Retrieves the mask pattern for a given mask name\n * @param {string} maskName - The name of the mask to retrieve.\n * @returns {any} The mask pattern associated with the given mask name.\n */\n getMaskPattern(maskName) {\n if (!this.multiMasks) {\n this.multiMasks = {};\n }\n if (this.multiMasks[maskName]) {\n return this.multiMasks[maskName];\n }\n const mask = this.component.inputMasks.find(inputMask => inputMask.label === maskName);\n this.multiMasks[maskName] = mask ? mask.mask : this.component.inputMasks[0].mask;\n return this.multiMasks[maskName];\n }\n /**\n * Attaches a selectable mask to an input field based on its configuration.\n * @param {number} index - The index of the select or input in component array.\n * @returns {boolean} - Returns true if the mask was successfully attached\n */\n attachMultiMask(index) {\n if (!(this.isMultipleMasksField && this.component.inputMasks.length && this.refs.input.length)) {\n return false;\n }\n const maskSelect = this.refs.select[index];\n maskSelect.onchange = this.onSelectMaskHandler.bind(this);\n maskSelect.maskInput = this.refs.mask[index];\n this.setInputMask(maskSelect.maskInput, this.component.inputMasks[0].mask);\n return true;\n }\n /**\n * @param {any} input - The input element on which the mask is to be applied.\n * @param {string} mask - The mask pattern to apply to the input element. Exit early if no mask.\n */\n updateMask(input, mask) {\n if (!mask) {\n return;\n }\n this.setInputMask(input, mask, !this.component.placeholder);\n this.updateValue();\n }\n /**\n * Adds a new empty value to the data array.\n * @param {any} value -A value to be added to the data array.\n */\n addNewValue(value) {\n if (value === undefined) {\n value = this.component.defaultValue ?\n this.component.defaultValue : this.emptyValue;\n // If default is an empty aray, default back to empty value.\n if (Array.isArray(value) && value.length === 0) {\n value = this.emptyValue;\n }\n }\n let dataValue = this.dataValue || [];\n if (!Array.isArray(dataValue)) {\n dataValue = [dataValue];\n }\n if (Array.isArray(value)) {\n dataValue = dataValue.concat(value);\n }\n else {\n dataValue.push(value);\n }\n this.dataValue = dataValue;\n }\n /**\n * Adds a new empty value to the data array, and add a new row to contain it.\n */\n addValue() {\n this.addNewValue();\n this.redraw();\n this.checkConditions();\n if (!this.isEmpty(this.dataValue)) {\n this.restoreValue();\n }\n if (this.root) {\n this.root.onChange();\n }\n }\n}\nexports[\"default\"] = Multivalue;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/multivalue/Multivalue.js?");
|
5636
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass Multivalue extends Field_1.default {\n /**\n * Normalize values coming into updateValue.\n * @param {*} value - The value to normalize before setting.\n * @returns {*} - The normalized value.\n */\n normalizeValue(value) {\n if (this.component.multiple) {\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return [this.emptyValue];\n }\n if (this.component.storeas === 'array') {\n return super.normalizeValue([value]);\n }\n return super.normalizeValue(value);\n }\n else {\n return super.normalizeValue(value == null ? [this.emptyValue] : [value]);\n }\n }\n else {\n if (Array.isArray(value) && this.component.storeas !== 'array') {\n if (this.component.storeas === 'string') {\n return super.normalizeValue(value.join(this.delimiter || ''));\n }\n return super.normalizeValue(value[0] || this.emptyValue);\n }\n else {\n return super.normalizeValue(value);\n }\n }\n }\n get dataValue() {\n return super.dataValue;\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get defaultValue() {\n let value = super.defaultValue;\n if (this.component.multiple) {\n if (lodash_1.default.isArray(value)) {\n value = !value.length ? [super.emptyValue] : value;\n }\n else {\n value = [value];\n }\n }\n return value;\n }\n get addAnother() {\n return this.t(this.component.addAnother || 'Add Another');\n }\n /**\n * @returns {Field} - The created field.\n */\n render() {\n let dataValue = this.normalizeValue(this.dataValue);\n return this.component.hasOwnProperty('multiple') && this.component.multiple\n ? super.render(this.renderTemplate('multiValueTable', {\n rows: dataValue.map(this.renderRow.bind(this)).join(''),\n disabled: this.disabled,\n addAnother: this.addAnother,\n }))\n : super.render(`<div ${this._referenceAttributeName}=\"element\">\n ${this.renderElement(this.component.type !== 'hidden' ? dataValue : '')}\n </div>`);\n }\n renderElement() {\n return '';\n }\n /**\n * Renders a single row for multi-value components.\n * @param {any} value - The value associated with the row to render.\n * @param {number} index - The index of the row in the multi-value list.\n * @returns {any} Returns the HTML string representation of the row.\n */\n renderRow(value, index) {\n return this.renderTemplate('multiValueRow', {\n index,\n disabled: this.disabled,\n element: `${this.renderElement(value, index)}`,\n });\n }\n /**\n * @param {HTMLElement} dom - The DOM element to which the component will attach.\n * @returns {Promise} - Promise that resolves when all asynchronous tasks that have finished.\n */\n attach(dom) {\n const superAttach = super.attach(dom);\n this.loadRefs(dom, {\n addButton: 'multiple',\n input: 'multiple',\n removeRow: 'multiple',\n mask: 'multiple',\n select: 'multiple',\n });\n const promises = [];\n this.refs.input.forEach((element, index) => {\n promises.push(this.attachElement.call(this, element, index));\n });\n if (!this.component.multiple) {\n return Promise.all(promises);\n }\n this.refs.removeRow.forEach((removeButton, index) => {\n this.addEventListener(removeButton, 'click', (event) => {\n event.preventDefault();\n this.removeValue(index);\n });\n });\n // If single value field.\n this.refs.addButton.forEach((addButton) => {\n this.addEventListener(addButton, 'click', (event) => {\n event.preventDefault();\n this.addValue();\n });\n });\n return superAttach.then(() => {\n return Promise.all(promises);\n });\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n if (this.refs.input && this.refs.input.length) {\n this.refs.input.forEach((input) => {\n if (input.mask) {\n input.mask.destroy ? input.mask.destroy() : input.mask.remove();\n }\n if (input.widget) {\n input.widget.destroy();\n }\n });\n }\n if (this.refs.mask && this.refs.mask.length) {\n this.refs.mask.forEach((input) => {\n if (input.mask) {\n input.mask.destroy ? input.mask.destroy() : input.mask.remove();\n }\n });\n }\n super.detach();\n }\n /**\n * Attach inputs to the element.\n * @param {HTMLElement} element - The element to attach.\n * @param {number} index - The index of the element to attach.\n */\n attachElement(element, index) {\n this.addEventListener(element, this.inputInfo.changeEvent, () => {\n // Delay update slightly to give input mask a chance to run.\n const textCase = lodash_1.default.get(this.component, 'case', 'mixed');\n if (textCase !== 'mixed') {\n const { selectionStart, selectionEnd, } = element;\n if (textCase === 'uppercase' && element.value) {\n element.value = element.value.toUpperCase();\n }\n if (textCase === 'lowercase' && element.value) {\n element.value = element.value.toLowerCase();\n }\n if (element.selectionStart && element.selectionEnd) {\n element.selectionStart = selectionStart;\n element.selectionEnd = selectionEnd;\n }\n }\n try {\n this.saveCaretPosition(element, index);\n }\n catch (err) {\n console.warn('An error occurred while trying to save caret position', err);\n }\n // If a mask is present, delay the update to allow mask to update first.\n if (element.mask) {\n setTimeout(() => {\n return this.updateValue(null, {\n modified: (this.component.type !== 'hidden')\n }, index);\n }, 1);\n }\n else {\n return this.updateValue(null, {\n modified: (this.component.type !== 'hidden')\n }, index);\n }\n });\n if (!this.attachMultiMask(index)) {\n const applyMask = () => {\n this.setInputMask(element);\n const valueMask = this.component.inputMask;\n const displayMask = this.component.displayMask;\n if (valueMask && displayMask && displayMask !== valueMask && this.refs.valueMaskInput) {\n this.setInputMask(this.refs.valueMaskInput, valueMask);\n }\n };\n if (this.inputInfo.changeEvent === 'blur') {\n this.addEventListener(element, this.inputInfo.changeEvent, () => {\n applyMask();\n this.dataValue = this.refs.input[0].value;\n if (this.checkComponentValidity()) {\n this.updateComponentValue(this.refs.input[0].value);\n }\n });\n }\n else {\n applyMask();\n }\n }\n }\n /**\n * Event handler for selecting a mask from a dropdown.\n * @param {Event} event - Event triggered by changing the selected option in mask.\n */\n onSelectMaskHandler(event) {\n this.updateMask(event.target.maskInput, this.getMaskPattern(event.target.value));\n }\n /**\n * Retrieves the mask pattern for a given mask name\n * @param {string} maskName - The name of the mask to retrieve.\n * @returns {any} The mask pattern associated with the given mask name.\n */\n getMaskPattern(maskName) {\n if (!this.multiMasks) {\n this.multiMasks = {};\n }\n if (this.multiMasks[maskName]) {\n return this.multiMasks[maskName];\n }\n const mask = this.component.inputMasks.find(inputMask => inputMask.label === maskName);\n this.multiMasks[maskName] = mask ? mask.mask : this.component.inputMasks[0].mask;\n return this.multiMasks[maskName];\n }\n /**\n * Attaches a selectable mask to an input field based on its configuration.\n * @param {number} index - The index of the select or input in component array.\n * @returns {boolean} - Returns true if the mask was successfully attached\n */\n attachMultiMask(index) {\n if (!(this.isMultipleMasksField && this.component.inputMasks.length && this.refs.input.length)) {\n return false;\n }\n const maskSelect = this.refs.select[index];\n maskSelect.onchange = this.onSelectMaskHandler.bind(this);\n maskSelect.maskInput = this.refs.mask[index];\n this.setInputMask(maskSelect.maskInput, this.component.inputMasks[0].mask);\n return true;\n }\n /**\n * @param {any} input - The input element on which the mask is to be applied.\n * @param {string} mask - The mask pattern to apply to the input element. Exit early if no mask.\n */\n updateMask(input, mask) {\n if (!mask) {\n return;\n }\n this.setInputMask(input, mask, !this.component.placeholder);\n this.updateValue();\n }\n /**\n * Adds a new empty value to the data array.\n * @param {any} value -A value to be added to the data array.\n */\n addNewValue(value) {\n if (value === undefined) {\n value = this.component.defaultValue ?\n this.component.defaultValue : this.emptyValue;\n // If default is an empty aray, default back to empty value.\n if (Array.isArray(value) && value.length === 0) {\n value = this.emptyValue;\n }\n }\n let dataValue = this.dataValue || [];\n if (!Array.isArray(dataValue)) {\n dataValue = [dataValue];\n }\n if (Array.isArray(value)) {\n dataValue = dataValue.concat(value);\n }\n else {\n dataValue.push(value);\n }\n this.dataValue = dataValue;\n }\n /**\n * Adds a new empty value to the data array, and add a new row to contain it.\n */\n addValue() {\n this.addNewValue();\n this.redraw();\n this.checkConditions();\n if (!this.isEmpty(this.dataValue)) {\n this.restoreValue();\n }\n if (this.root) {\n this.root.onChange();\n }\n }\n}\nexports[\"default\"] = Multivalue;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/multivalue/Multivalue.js?");
|
5637
5637
|
|
5638
5638
|
/***/ }),
|
5639
5639
|
|
@@ -5666,7 +5666,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5666
5666
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5667
5667
|
|
5668
5668
|
"use strict";
|
5669
|
-
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?");
|
5669
|
+
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 removeSubmissionMetadataRow(index) {\n const componentMetadata = lodash_1.default.get(this.root, `submission.metadata.selectData.${this.path}`, null);\n if (lodash_1.default.isArray(componentMetadata)) {\n componentMetadata.splice(index, 1);\n }\n }\n}\nexports[\"default\"] = NestedArrayComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js?");
|
5670
5670
|
|
5671
5671
|
/***/ }),
|
5672
5672
|
|
@@ -5699,7 +5699,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5699
5699
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5700
5700
|
|
5701
5701
|
"use strict";
|
5702
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.AddressComponentMode = void 0;\nconst autocompleter_1 = __importDefault(__webpack_require__(/*! autocompleter */ \"./node_modules/autocompleter/autocomplete.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst GoogleAddressProvider_1 = __webpack_require__(/*! ../../providers/address/GoogleAddressProvider */ \"./lib/cjs/providers/address/GoogleAddressProvider.js\");\nconst Field_1 = __importDefault(__webpack_require__(/*! ../_classes/field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst NestedComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nconst Container_1 = __importDefault(__webpack_require__(/*! ../container/Container */ \"./lib/cjs/components/container/Container.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nexports.AddressComponentMode = {\n Autocomplete: 'autocomplete',\n Manual: 'manual',\n};\nconst RemoveValueIconHiddenClass = 'address-autocomplete-remove-value-icon--hidden';\nconst ChildConditional = 'show = _.get(instance, \\'parent.manualMode\\', false);';\nclass AddressComponent extends Container_1.default {\n static schema(...extend) {\n return Container_1.default.schema({\n type: 'address',\n label: 'Address',\n key: 'address',\n switchToManualModeLabel: 'Can\\'t find address? Switch to manual mode.',\n provider: '',\n providerOptions: {},\n manualModeViewString: '',\n hideLabel: false,\n disableClearIcon: false,\n enableManualMode: false,\n components: [\n {\n label: 'Address 1',\n tableView: false,\n key: 'address1',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Address 2',\n tableView: false,\n key: 'address2',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'City',\n tableView: false,\n key: 'city',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'State',\n tableView: false,\n key: 'state',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Country',\n tableView: false,\n key: 'country',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Zip Code',\n tableView: false,\n key: 'zip',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n ],\n }, ...extend);\n }\n static savedValueTypes(schema) {\n schema = schema || {};\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.object];\n }\n static get builderInfo() {\n return {\n title: 'Address',\n group: 'advanced',\n icon: 'home',\n documentation: '/userguide/form-building/advanced-components#address',\n weight: 35,\n schema: AddressComponent.schema(),\n };\n }\n mergeSchema(component = {}) {\n let { defaultSchema } = this;\n if (component.components) {\n defaultSchema = lodash_1.default.omit(defaultSchema, 'components');\n }\n return lodash_1.default.defaultsDeep(component, defaultSchema);\n }\n init() {\n this.components = this.components || [];\n if (this.builderMode || this.manualModeEnabled) {\n NestedComponent_1.default.prototype.addComponents.call(this, this.manualMode ? this.address : {});\n }\n Field_1.default.prototype.init.call(this);\n if (!this.builderMode) {\n if (this.component.provider) {\n const { provider, providerOptions, } = this.component;\n if (lodash_1.default.get(providerOptions, 'params.subscriptionKey')) {\n lodash_1.default.set(providerOptions, \"params['subscription-key']\", lodash_1.default.get(providerOptions, 'params.subscriptionKey'));\n lodash_1.default.unset(providerOptions, 'params.subscriptionKey');\n }\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n else if (this.component.map) {\n // Fallback to legacy version where Google Maps was the only provider.\n this.component.provider = GoogleAddressProvider_1.GoogleAddressProvider.name;\n this.component.providerOptions = this.component.providerOptions || {};\n const { map, provider, providerOptions, } = this.component;\n const { key, region, } = map;\n if (key) {\n lodash_1.default.set(providerOptions, 'params.key', key);\n }\n if (region) {\n lodash_1.default.set(providerOptions, 'params.region', region);\n }\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n }\n }\n initializeProvider(provider, options = {}) {\n const url = this.interpolate(options.url);\n const Provider = Formio_1.Formio.Providers.getProvider('address', provider);\n return new Provider(Object.assign(Object.assign({}, options), { url }));\n }\n get emptyValue() {\n return this.manualModeEnabled\n ? {\n mode: exports.AddressComponentMode.Autocomplete,\n address: {},\n }\n : {};\n }\n get mode() {\n var _a, _b;\n if (!this.manualModeEnabled) {\n return exports.AddressComponentMode.Autocomplete;\n }\n return (_b = (_a = this.dataValue) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : exports.AddressComponentMode.Autocomplete;\n }\n set mode(value) {\n if (this.manualModeEnabled) {\n this.dataValue.mode = value;\n }\n }\n get autocompleteMode() {\n return this.mode === exports.AddressComponentMode.Autocomplete;\n }\n get manualMode() {\n return this.mode === exports.AddressComponentMode.Manual;\n }\n get manualModeEnabled() {\n return !this.isMultiple && Boolean(this.component.enableManualMode);\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n component.data = this.address;\n component.setValue(component.dataValue, {\n noUpdateEvent: true,\n });\n });\n }\n get isMultiple() {\n return Boolean(this.component.multiple);\n }\n get address() {\n if (this.isMultiple) {\n return lodash_1.default.isArray(this.dataValue) ? this.dataValue : [this.dataValue];\n }\n // Manual mode is not implementing for multiple value\n return (this.manualModeEnabled && this.dataValue) ? this.dataValue.address : this.dataValue;\n }\n set address(value) {\n if (this.manualModeEnabled && !this.isMultiple) {\n this.dataValue.address = value;\n }\n else {\n this.dataValue = value;\n }\n }\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (this.isMultiple) {\n defaultValue = lodash_1.default.isArray(defaultValue) ? defaultValue : [defaultValue];\n }\n return defaultValue;\n }\n get defaultSchema() {\n return AddressComponent.schema();\n }\n isValueInLegacyFormat(value) {\n return value && !value.mode;\n }\n normalizeValue(value) {\n return (this.manualModeEnabled && this.isValueInLegacyFormat(value))\n ? {\n mode: exports.AddressComponentMode.Autocomplete,\n address: value,\n }\n : value;\n }\n setValue(value, flags = {}) {\n const changed = Field_1.default.prototype.setValue.call(this, value, flags);\n if (this.manualMode) {\n this.restoreComponentsContext();\n }\n if (changed || !lodash_1.default.isEmpty(value) && flags.fromSubmission) {\n this.redraw();\n }\n return changed;\n }\n static get modeSwitcherRef() {\n return 'modeSwitcher';\n }\n static get removeValueIconRef() {\n return 'removeValueIcon';\n }\n static get searchInputRef() {\n return 'searchInput';\n }\n static get addRowButtonRef() {\n return 'addButton';\n }\n static get removeRowButtonRef() {\n return 'removeRow';\n }\n get modeSwitcher() {\n return this.refs\n ? (this.refs[AddressComponent.modeSwitcherRef] || null)\n : null;\n }\n get removeValueIcon() {\n return this.refs\n ? (this.refs[AddressComponent.removeValueIconRef] || null)\n : null;\n }\n get searchInput() {\n return this.refs\n ? (this.refs[AddressComponent.searchInputRef] || null)\n : null;\n }\n get addRowButton() {\n return this.refs\n ? (this.refs[AddressComponent.addRowButtonRef] || null)\n : null;\n }\n get removeRowButton() {\n return this.refs\n ? (this.refs[AddressComponent.removeRowButtonRef] || null)\n : null;\n }\n get searchInputAttributes() {\n const attr = {\n name: this.options.name,\n type: 'text',\n class: 'form-control',\n lang: this.options.language,\n tabindex: this.component.tabindex || 0,\n };\n if (this.component.placeholder) {\n attr.placeholder = this.t(this.component.placeholder), { _userInput: true };\n }\n if (this.disabled) {\n attr.disabled = 'disabled';\n }\n lodash_1.default.defaults(attr, this.component.attributes);\n return attr;\n }\n get templateName() {\n return 'address';\n }\n get gridTemplateName() {\n return 'multiValueTable';\n }\n get rowTemplateName() {\n return 'multiValueRow';\n }\n get hasChildren() {\n return !this.isMultiple && (this.builderMode || this.manualModeEnabled);\n }\n get addAnother() {\n return this.t(this.component.addAnother || 'Add Another');\n }\n renderElement(value) {\n return this.renderTemplate(this.templateName, {\n children: this.hasChildren ? this.renderComponents() : '',\n nestedKey: this.nestedKey,\n inputAttributes: this.searchInputAttributes,\n ref: {\n modeSwitcher: AddressComponent.modeSwitcherRef,\n removeValueIcon: AddressComponent.removeValueIconRef,\n searchInput: AddressComponent.searchInputRef,\n },\n displayValue: this.getDisplayValue(value),\n mode: {\n autocomplete: this.autocompleteMode,\n manual: this.manualMode,\n },\n });\n }\n renderRow(value, index) {\n return this.renderTemplate(this.rowTemplateName, {\n index,\n disabled: this.disabled,\n element: `${this.renderElement(value, index)}`,\n });\n }\n renderGrid() {\n return this.renderTemplate(this.gridTemplateName, {\n rows: this.address.map(this.renderRow.bind(this)).join(''),\n disabled: this.disabled,\n addAnother: this.addAnother,\n });\n }\n render() {\n if (this.isMultiple) {\n return super.render(this.renderGrid());\n }\n return super.render(this.renderElement());\n }\n onSelectAddress(address, element, index) {\n if (this.isMultiple) {\n this.address[index] = address;\n this.address = [...this.address];\n }\n else {\n this.address = address;\n }\n this.triggerChange({\n modified: true,\n });\n if (element) {\n element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);\n }\n this.updateRemoveIcon(index);\n }\n addRow() {\n this.address = this.address.concat(this.emptyValue);\n super.redraw();\n }\n attach(element) {\n const result = ((this.builderMode || this.manualMode) ? super.attach : Field_1.default.prototype.attach).call(this, element);\n if (!this.builderMode) {\n if (!this.provider && this.component.provider) {\n const { provider, providerOptions, } = this.component;\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n }\n this.loadRefs(element, {\n [AddressComponent.addRowButtonRef]: 'single',\n [AddressComponent.modeSwitcherRef]: 'single',\n [AddressComponent.removeRowButtonRef]: 'multiple',\n [AddressComponent.removeValueIconRef]: 'multiple',\n [AddressComponent.searchInputRef]: 'multiple',\n });\n this.searchInput.forEach((element, index) => {\n if (!this.builderMode && element && this.provider) {\n if (this.component.provider === 'google') {\n this.provider.attachAutocomplete(element, index, this.onSelectAddress.bind(this));\n }\n else {\n (0, autocompleter_1.default)({\n input: element,\n debounceWaitMs: 300,\n fetch: (text, update) => {\n const query = text;\n this.provider.search(query).then(update);\n },\n render: (address) => {\n const div = this.ce('div');\n div.textContent = this.getDisplayValue(address);\n return div;\n },\n onSelect: (address) => {\n this.onSelectAddress(address, element, index);\n },\n });\n }\n this.addEventListener(element, 'blur', () => {\n if (!element) {\n return;\n }\n if (element.value) {\n element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);\n }\n });\n this.addEventListener(element, 'keyup', () => {\n if (!element) {\n return;\n }\n if (!element.value) {\n this.clearAddress(element, index);\n }\n });\n }\n });\n if (this.addRowButton) {\n this.addEventListener(this.addRowButton, 'click', event => {\n event.preventDefault();\n this.addRow();\n });\n }\n this.removeRowButton.forEach((removeRowButton, index) => {\n this.addEventListener(removeRowButton, 'click', event => {\n event.preventDefault();\n this.removeValue(index);\n });\n });\n if (this.modeSwitcher) {\n this.addEventListener(this.modeSwitcher, 'change', () => {\n if (!this.modeSwitcher) {\n return;\n }\n this.dataValue = this.emptyValue;\n this.mode = this.modeSwitcher.checked\n ? exports.AddressComponentMode.Manual\n : exports.AddressComponentMode.Autocomplete;\n if (!this.builderMode) {\n if (this.manualMode) {\n this.restoreComponentsContext();\n }\n this.triggerChange({\n modified: true,\n });\n }\n this.redraw();\n });\n }\n if (!this.builderMode) {\n this.removeValueIcon.forEach((removeValueIcon, index) => {\n this.updateRemoveIcon(index);\n const removeValueHandler = () => {\n var _a;\n const searchInput = (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a[index];\n this.clearAddress(searchInput, index);\n if (searchInput) {\n searchInput.focus();\n }\n };\n this.addEventListener(removeValueIcon, 'click', removeValueHandler);\n this.addEventListener(removeValueIcon, 'keydown', ({ key }) => {\n if (key === 'Enter') {\n removeValueHandler();\n }\n });\n });\n lodash_1.default.each(this.refs.searchInput || [], el => this.addFocusBlurEvents(el));\n }\n return result;\n }\n addChildComponent(component) {\n component.customConditional = ChildConditional;\n }\n redraw() {\n const modeSwitcherInFocus = (this.modeSwitcher && (document.activeElement === this.modeSwitcher));\n return super.redraw()\n .then((result) => {\n if (modeSwitcherInFocus && this.modeSwitcher) {\n this.modeSwitcher.focus();\n }\n return result;\n });\n }\n clearAddress(element, index) {\n var _a;\n if (!this.isEmpty()) {\n this.triggerChange();\n }\n if ((_a = this.address) === null || _a === void 0 ? void 0 : _a[index]) {\n this.address[index] = this.emptyValue;\n }\n else {\n this.address = this.emptyValue;\n }\n if (element) {\n element.value = '';\n }\n this.updateRemoveIcon(index);\n }\n getDisplayValue(value = this.address) {\n return (this.provider && !this.manualMode)\n ? this.provider.getDisplayValue(value)\n : '';\n }\n validateMultiple() {\n return this.isMultiple;\n }\n updateRemoveIcon(index) {\n var _a;\n const removeValueIcon = (_a = this.removeValueIcon) === null || _a === void 0 ? void 0 : _a[index];\n if (removeValueIcon) {\n const value = this.isMultiple ? this.address[index] : this.address;\n if (this.isEmpty(value) || this.disabled) {\n this.addClass(removeValueIcon, RemoveValueIconHiddenClass);\n }\n else {\n this.removeClass(removeValueIcon, RemoveValueIconHiddenClass);\n }\n }\n }\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n const normalizedValue = this.normalizeValue(value);\n const { address, mode, } = (this.manualModeEnabled\n ? normalizedValue\n : {\n address: normalizedValue,\n mode: exports.AddressComponentMode.Autocomplete,\n });\n const valueInManualMode = (mode === exports.AddressComponentMode.Manual);\n if (this.provider && !valueInManualMode) {\n return this.getDisplayValue(address);\n }\n if (valueInManualMode) {\n if (this.component.manualModeViewString) {\n return this.interpolate(this.component.manualModeViewString, {\n address,\n data: this.data,\n component: this.component,\n });\n }\n return this.getComponents()\n .filter((component) => component.hasValue(address))\n .map((component) => [component, lodash_1.default.get(address, component.key)])\n .filter(([component, componentValue]) => !component.isEmpty(componentValue))\n .map(([component, componentValue]) => component.getValueAsString(componentValue, options))\n .join(', ');\n }\n return super.getValueAsString(address, options);\n }\n focus() {\n if (this.searchInput && this.searchInput[0]) {\n this.searchInput[0].focus();\n }\n }\n}\nexports[\"default\"] = AddressComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/address/Address.js?");
|
5702
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.AddressComponentMode = void 0;\nconst autocompleter_1 = __importDefault(__webpack_require__(/*! autocompleter */ \"./node_modules/autocompleter/autocomplete.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst GoogleAddressProvider_1 = __webpack_require__(/*! ../../providers/address/GoogleAddressProvider */ \"./lib/cjs/providers/address/GoogleAddressProvider.js\");\nconst Field_1 = __importDefault(__webpack_require__(/*! ../_classes/field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst NestedComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nconst Container_1 = __importDefault(__webpack_require__(/*! ../container/Container */ \"./lib/cjs/components/container/Container.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nexports.AddressComponentMode = {\n Autocomplete: 'autocomplete',\n Manual: 'manual',\n};\nconst RemoveValueIconHiddenClass = 'address-autocomplete-remove-value-icon--hidden';\nconst ChildConditional = 'show = _.get(instance, \\'parent.manualMode\\', false);';\nclass AddressComponent extends Container_1.default {\n static schema(...extend) {\n return Container_1.default.schema({\n type: 'address',\n label: 'Address',\n key: 'address',\n switchToManualModeLabel: 'Can\\'t find address? Switch to manual mode.',\n provider: '',\n providerOptions: {},\n manualModeViewString: '',\n hideLabel: false,\n disableClearIcon: false,\n enableManualMode: false,\n components: [\n {\n label: 'Address 1',\n tableView: false,\n key: 'address1',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Address 2',\n tableView: false,\n key: 'address2',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'City',\n tableView: false,\n key: 'city',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'State',\n tableView: false,\n key: 'state',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Country',\n tableView: false,\n key: 'country',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n {\n label: 'Zip Code',\n tableView: false,\n key: 'zip',\n type: 'textfield',\n input: true,\n customConditional: ChildConditional,\n },\n ],\n }, ...extend);\n }\n static savedValueTypes(schema) {\n schema = schema || {};\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.object];\n }\n static get builderInfo() {\n return {\n title: 'Address',\n group: 'advanced',\n icon: 'home',\n documentation: '/userguide/form-building/advanced-components#address',\n weight: 35,\n schema: AddressComponent.schema(),\n };\n }\n static get serverConditionSettings() {\n return AddressComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { operators: ['isEmpty', 'isNotEmpty'] });\n }\n mergeSchema(component = {}) {\n let { defaultSchema } = this;\n if (component.components) {\n defaultSchema = lodash_1.default.omit(defaultSchema, 'components');\n }\n return lodash_1.default.defaultsDeep(component, defaultSchema);\n }\n init() {\n this.components = this.components || [];\n if (this.builderMode || this.manualModeEnabled) {\n NestedComponent_1.default.prototype.addComponents.call(this, this.manualMode ? this.address : {});\n }\n Field_1.default.prototype.init.call(this);\n if (!this.builderMode) {\n if (this.component.provider) {\n const { provider, providerOptions, } = this.component;\n if (lodash_1.default.get(providerOptions, 'params.subscriptionKey')) {\n lodash_1.default.set(providerOptions, \"params['subscription-key']\", lodash_1.default.get(providerOptions, 'params.subscriptionKey'));\n lodash_1.default.unset(providerOptions, 'params.subscriptionKey');\n }\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n else if (this.component.map) {\n // Fallback to legacy version where Google Maps was the only provider.\n this.component.provider = GoogleAddressProvider_1.GoogleAddressProvider.name;\n this.component.providerOptions = this.component.providerOptions || {};\n const { map, provider, providerOptions, } = this.component;\n const { key, region, } = map;\n if (key) {\n lodash_1.default.set(providerOptions, 'params.key', key);\n }\n if (region) {\n lodash_1.default.set(providerOptions, 'params.region', region);\n }\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n }\n }\n initializeProvider(provider, options = {}) {\n const url = this.interpolate(options.url);\n const Provider = Formio_1.Formio.Providers.getProvider('address', provider);\n return new Provider(Object.assign(Object.assign({}, options), { url }));\n }\n get emptyValue() {\n return this.manualModeEnabled\n ? {\n mode: exports.AddressComponentMode.Autocomplete,\n address: {},\n }\n : {};\n }\n get mode() {\n var _a, _b;\n if (!this.manualModeEnabled) {\n return exports.AddressComponentMode.Autocomplete;\n }\n return (_b = (_a = this.dataValue) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : exports.AddressComponentMode.Autocomplete;\n }\n set mode(value) {\n if (this.manualModeEnabled) {\n this.dataValue.mode = value;\n }\n }\n get autocompleteMode() {\n return this.mode === exports.AddressComponentMode.Autocomplete;\n }\n get manualMode() {\n return this.mode === exports.AddressComponentMode.Manual;\n }\n get manualModeEnabled() {\n return !this.isMultiple && Boolean(this.component.enableManualMode);\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n component.data = this.address;\n component.setValue(component.dataValue, {\n noUpdateEvent: true,\n });\n });\n }\n get isMultiple() {\n return Boolean(this.component.multiple);\n }\n get address() {\n if (this.isMultiple) {\n return lodash_1.default.isArray(this.dataValue) ? this.dataValue : [this.dataValue];\n }\n // Manual mode is not implementing for multiple value\n return (this.manualModeEnabled && this.dataValue) ? this.dataValue.address : this.dataValue;\n }\n set address(value) {\n if (this.manualModeEnabled && !this.isMultiple && !lodash_1.default.isEqual(value, this.emptyValue)) {\n this.dataValue.address = value;\n }\n else {\n this.dataValue = value;\n }\n }\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (this.isMultiple) {\n defaultValue = lodash_1.default.isArray(defaultValue) ? defaultValue : [defaultValue];\n }\n return defaultValue;\n }\n get defaultSchema() {\n return AddressComponent.schema();\n }\n isValueInLegacyFormat(value) {\n return value && !value.mode;\n }\n normalizeValue(value) {\n return (this.manualModeEnabled && this.isValueInLegacyFormat(value))\n ? {\n mode: exports.AddressComponentMode.Autocomplete,\n address: value,\n }\n : value;\n }\n setValue(value, flags = {}) {\n const changed = Field_1.default.prototype.setValue.call(this, value, flags);\n if (this.manualMode) {\n this.restoreComponentsContext();\n }\n if (changed || !lodash_1.default.isEmpty(value) && flags.fromSubmission) {\n this.redraw();\n }\n return changed;\n }\n static get modeSwitcherRef() {\n return 'modeSwitcher';\n }\n static get removeValueIconRef() {\n return 'removeValueIcon';\n }\n static get searchInputRef() {\n return 'searchInput';\n }\n static get addRowButtonRef() {\n return 'addButton';\n }\n static get removeRowButtonRef() {\n return 'removeRow';\n }\n get modeSwitcher() {\n return this.refs\n ? (this.refs[AddressComponent.modeSwitcherRef] || null)\n : null;\n }\n get removeValueIcon() {\n return this.refs\n ? (this.refs[AddressComponent.removeValueIconRef] || null)\n : null;\n }\n get searchInput() {\n return this.refs\n ? (this.refs[AddressComponent.searchInputRef] || null)\n : null;\n }\n get addRowButton() {\n return this.refs\n ? (this.refs[AddressComponent.addRowButtonRef] || null)\n : null;\n }\n get removeRowButton() {\n return this.refs\n ? (this.refs[AddressComponent.removeRowButtonRef] || null)\n : null;\n }\n get searchInputAttributes() {\n const attr = {\n name: this.options.name,\n type: 'text',\n class: 'form-control',\n lang: this.options.language,\n tabindex: this.component.tabindex || 0,\n };\n if (this.component.placeholder) {\n attr.placeholder = this.t(this.component.placeholder), { _userInput: true };\n }\n if (this.disabled) {\n attr.disabled = 'disabled';\n }\n lodash_1.default.defaults(attr, this.component.attributes);\n return attr;\n }\n get templateName() {\n return 'address';\n }\n get gridTemplateName() {\n return 'multiValueTable';\n }\n get rowTemplateName() {\n return 'multiValueRow';\n }\n get hasChildren() {\n return !this.isMultiple && (this.builderMode || this.manualModeEnabled);\n }\n get addAnother() {\n return this.t(this.component.addAnother || 'Add Another');\n }\n renderElement(value) {\n return this.renderTemplate(this.templateName, {\n children: this.hasChildren ? this.renderComponents() : '',\n nestedKey: this.nestedKey,\n inputAttributes: this.searchInputAttributes,\n ref: {\n modeSwitcher: AddressComponent.modeSwitcherRef,\n removeValueIcon: AddressComponent.removeValueIconRef,\n searchInput: AddressComponent.searchInputRef,\n },\n displayValue: this.getDisplayValue(value),\n mode: {\n autocomplete: this.autocompleteMode,\n manual: this.manualMode,\n },\n });\n }\n renderRow(value, index) {\n return this.renderTemplate(this.rowTemplateName, {\n index,\n disabled: this.disabled,\n element: `${this.renderElement(value, index)}`,\n });\n }\n renderGrid() {\n return this.renderTemplate(this.gridTemplateName, {\n rows: this.address.map(this.renderRow.bind(this)).join(''),\n disabled: this.disabled,\n addAnother: this.addAnother,\n });\n }\n render() {\n if (this.isMultiple) {\n return super.render(this.renderGrid());\n }\n return super.render(this.renderElement());\n }\n onSelectAddress(address, element, index) {\n if (this.isMultiple) {\n this.address[index] = address;\n this.address = [...this.address];\n }\n else {\n this.address = address;\n }\n this.triggerChange({\n modified: true,\n });\n if (element) {\n element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);\n }\n this.updateRemoveIcon(index);\n }\n addRow() {\n this.address = this.address.concat(this.emptyValue);\n super.redraw();\n }\n attach(element) {\n const result = ((this.builderMode || this.manualMode) ? super.attach : Field_1.default.prototype.attach).call(this, element);\n if (!this.builderMode) {\n if (!this.provider && this.component.provider) {\n const { provider, providerOptions, } = this.component;\n this.provider = this.initializeProvider(provider, providerOptions);\n }\n }\n this.loadRefs(element, {\n [AddressComponent.addRowButtonRef]: 'single',\n [AddressComponent.modeSwitcherRef]: 'single',\n [AddressComponent.removeRowButtonRef]: 'multiple',\n [AddressComponent.removeValueIconRef]: 'multiple',\n [AddressComponent.searchInputRef]: 'multiple',\n });\n this.searchInput.forEach((element, index) => {\n if (!this.builderMode && element && this.provider) {\n if (this.component.provider === 'google') {\n this.provider.attachAutocomplete(element, index, this.onSelectAddress.bind(this));\n }\n else {\n (0, autocompleter_1.default)({\n input: element,\n debounceWaitMs: 300,\n fetch: (text, update) => {\n const query = text;\n this.provider.search(query).then(update);\n },\n render: (address) => {\n const div = this.ce('div');\n div.textContent = this.getDisplayValue(address);\n return div;\n },\n onSelect: (address) => {\n this.onSelectAddress(address, element, index);\n },\n });\n }\n this.addEventListener(element, 'blur', () => {\n if (!element) {\n return;\n }\n if (element.value) {\n element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);\n }\n });\n this.addEventListener(element, 'keyup', () => {\n if (!element) {\n return;\n }\n if (!element.value) {\n this.clearAddress(element, index);\n }\n });\n }\n });\n if (this.addRowButton) {\n this.addEventListener(this.addRowButton, 'click', event => {\n event.preventDefault();\n this.addRow();\n });\n }\n this.removeRowButton.forEach((removeRowButton, index) => {\n this.addEventListener(removeRowButton, 'click', event => {\n event.preventDefault();\n this.removeValue(index);\n });\n });\n if (this.modeSwitcher) {\n this.addEventListener(this.modeSwitcher, 'change', () => {\n if (!this.modeSwitcher) {\n return;\n }\n this.dataValue = this.emptyValue;\n this.mode = this.modeSwitcher.checked\n ? exports.AddressComponentMode.Manual\n : exports.AddressComponentMode.Autocomplete;\n if (!this.builderMode) {\n if (this.manualMode) {\n this.restoreComponentsContext();\n }\n this.triggerChange({\n modified: true,\n });\n }\n this.redraw();\n });\n }\n if (!this.builderMode) {\n this.removeValueIcon.forEach((removeValueIcon, index) => {\n this.updateRemoveIcon(index);\n const removeValueHandler = () => {\n var _a;\n const searchInput = (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a[index];\n this.clearAddress(searchInput, index);\n if (searchInput) {\n searchInput.focus();\n }\n };\n this.addEventListener(removeValueIcon, 'click', removeValueHandler);\n this.addEventListener(removeValueIcon, 'keydown', ({ key }) => {\n if (key === 'Enter') {\n removeValueHandler();\n }\n });\n });\n lodash_1.default.each(this.refs.searchInput || [], el => this.addFocusBlurEvents(el));\n }\n return result;\n }\n addChildComponent(component) {\n component.customConditional = ChildConditional;\n }\n redraw() {\n const modeSwitcherInFocus = (this.modeSwitcher && (document.activeElement === this.modeSwitcher));\n return super.redraw()\n .then((result) => {\n if (modeSwitcherInFocus && this.modeSwitcher) {\n this.modeSwitcher.focus();\n }\n return result;\n });\n }\n clearAddress(element, index) {\n var _a;\n if (!this.isEmpty()) {\n this.triggerChange();\n }\n if ((_a = this.address) === null || _a === void 0 ? void 0 : _a[index]) {\n this.address[index] = this.emptyValue;\n }\n else {\n this.address = this.emptyValue;\n }\n if (element) {\n element.value = '';\n }\n this.updateRemoveIcon(index);\n }\n getDisplayValue(value = this.address) {\n return (this.provider && !this.manualMode)\n ? this.provider.getDisplayValue(value)\n : '';\n }\n validateMultiple() {\n return this.isMultiple;\n }\n updateRemoveIcon(index) {\n var _a;\n const removeValueIcon = (_a = this.removeValueIcon) === null || _a === void 0 ? void 0 : _a[index];\n if (removeValueIcon) {\n const value = this.isMultiple ? this.address[index] : this.address;\n if (this.isEmpty(value) || this.disabled) {\n this.addClass(removeValueIcon, RemoveValueIconHiddenClass);\n }\n else {\n this.removeClass(removeValueIcon, RemoveValueIconHiddenClass);\n }\n }\n }\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n const normalizedValue = this.normalizeValue(value);\n const { address, mode, } = (this.manualModeEnabled\n ? normalizedValue\n : {\n address: normalizedValue,\n mode: exports.AddressComponentMode.Autocomplete,\n });\n const valueInManualMode = (mode === exports.AddressComponentMode.Manual);\n if (this.provider && !valueInManualMode) {\n return this.getDisplayValue(address);\n }\n if (valueInManualMode) {\n if (this.component.manualModeViewString) {\n return this.interpolate(this.component.manualModeViewString, {\n address,\n data: this.data,\n component: this.component,\n });\n }\n return this.getComponents()\n .filter((component) => component.hasValue(address))\n .map((component) => [component, lodash_1.default.get(address, component.key)])\n .filter(([component, componentValue]) => !component.isEmpty(componentValue))\n .map(([component, componentValue]) => component.getValueAsString(componentValue, options))\n .join(', ');\n }\n return super.getValueAsString(address, options);\n }\n focus() {\n if (this.searchInput && this.searchInput[0]) {\n this.searchInput[0].focus();\n }\n }\n}\nexports[\"default\"] = AddressComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/address/Address.js?");
|
5703
5703
|
|
5704
5704
|
/***/ }),
|
5705
5705
|
|
@@ -6029,7 +6029,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6029
6029
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
6030
6030
|
|
6031
6031
|
"use strict";
|
6032
|
-
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 NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Components_1 = __importDefault(__webpack_require__(/*! ../Components */ \"./lib/cjs/components/Components.js\"));\nconst dragula_1 = __importDefault(__webpack_require__(/*! dragula */ \"./node_modules/dragula/dragula.js\"));\nclass DataGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n label: 'Data Grid',\n key: 'dataGrid',\n type: 'datagrid',\n clearOnHide: true,\n input: true,\n tree: true,\n components: []\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Data Grid',\n icon: 'th',\n group: 'data',\n documentation: '/userguide/form-building/data-components#data-grid',\n showPreview: false,\n weight: 30,\n schema: DataGridComponent.schema()\n };\n }\n constructor(...args) {\n super(...args);\n this.type = 'datagrid';\n this.tabIndex = 0;\n }\n init() {\n this.components = this.components || [];\n // Add new values based on minLength.\n this.rows = [];\n this.columns = [...this.component.components];\n if (this.initRows || !lodash_1.default.isEqual(this.dataValue, this.emptyValue)) {\n this.createRows(true);\n }\n this.visibleColumns = {};\n this.prevHasAddButton = this.hasAddButton();\n this.checkColumns();\n }\n get dataValue() {\n const dataValue = super.dataValue;\n if (!dataValue || !Array.isArray(dataValue)) {\n return this.emptyValue;\n }\n return dataValue;\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get defaultSchema() {\n return DataGridComponent.schema();\n }\n get initEmpty() {\n return this.component.initEmpty || this.component.noFirstRow;\n }\n get initRows() {\n return this.builderMode || this.path === 'defaultValue' || !this.initEmpty;\n }\n get emptyValue() {\n return this.initEmpty ? [] : [{}];\n }\n get addAnotherPosition() {\n return lodash_1.default.get(this.component, 'addAnotherPosition', 'bottom');\n }\n get minLength() {\n if (this.hasRowGroups()) {\n return lodash_1.default.sum(this.getGroupSizes());\n }\n else {\n return lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n }\n get defaultValue() {\n const isBuilderMode = this.builderMode;\n const isEmptyInit = this.initEmpty;\n // Ensure we have one and only one row in builder mode.\n if (isBuilderMode || (isEmptyInit && !this.dataValue.length)) {\n return isEmptyInit && !isBuilderMode ? [] : [{}];\n }\n const value = super.defaultValue;\n let defaultValue;\n if (Array.isArray(value)) {\n defaultValue = value;\n }\n else if (value && (typeof value === 'object')) {\n defaultValue = [value];\n }\n else {\n defaultValue = this.emptyValue;\n }\n for (let dIndex = defaultValue.length; dIndex < this.minLength; dIndex++) {\n defaultValue.push({});\n }\n return defaultValue;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n lodash_1.default.each(this.refs[`${this.datagridKey}-addRow`], (button) => {\n button.disabled = disabled;\n });\n lodash_1.default.each(this.refs[`${this.datagridKey}-removeRow`], (button) => {\n button.disabled = disabled;\n });\n }\n get disabled() {\n return super.disabled;\n }\n get datagridKey() {\n return `datagrid-${this.key}`;\n }\n get allowReorder() {\n return !this.options.readOnly && lodash_1.default.get(this.component, 'reorder', false);\n }\n get iteratableRows() {\n return this.rows.map((row, index) => ({\n components: row,\n data: this.dataValue[index],\n }));\n }\n isEmpty(value = this.dataValue) {\n var _a;\n const isEmpty = super.isEmpty(value);\n if ((_a = this.components) === null || _a === void 0 ? void 0 : _a.length) {\n return this.components.reduce((isEmpty, component) => {\n return isEmpty && component.isEmpty();\n }, true);\n }\n return isEmpty;\n }\n /**\n * Split rows into chunks.\n * @param {number[]} groups - array of numbers where each item is size of group\n * @param {Array<T>} rows - rows collection\n * @returns {Array<T[]>} - The chunked rows\n */\n getRowChunks(groups, rows) {\n const [, chunks] = groups.reduce(([startIndex, acc], size) => {\n const endIndex = startIndex + size;\n return [endIndex, [...acc, [startIndex, endIndex]]];\n }, [0, []]);\n return chunks.map(range => lodash_1.default.slice(rows, ...range));\n }\n /**\n * Create groups object.\n * Each key in object represents index of first row in group.\n * @returns {object} - The groups object.\n */\n getGroups() {\n const groups = lodash_1.default.get(this.component, 'rowGroups', []);\n const sizes = lodash_1.default.map(groups, 'numberOfRows').slice(0, -1);\n const indexes = sizes.reduce((groupIndexes, size) => {\n const last = groupIndexes[groupIndexes.length - 1];\n return groupIndexes.concat(last + size);\n }, [0]);\n return groups.reduce((gidxs, group, idx) => {\n return Object.assign(Object.assign({}, gidxs), { [indexes[idx]]: group });\n }, {});\n }\n /**\n * Get group sizes.\n * @returns {number[]} - The array of group sizes.\n */\n getGroupSizes() {\n return lodash_1.default.map(lodash_1.default.get(this.component, 'rowGroups', []), 'numberOfRows');\n }\n hasRowGroups() {\n return lodash_1.default.get(this, 'component.enableRowGroups', false) && !this.builderMode;\n }\n totalRowsNumber(groups) {\n return lodash_1.default.sum(lodash_1.default.map(groups, 'numberOfRows'));\n }\n setStaticValue(n) {\n this.dataValue = lodash_1.default.range(n).map(() => ({}));\n }\n hasExtraColumn() {\n return (this.hasRemoveButtons() || this.canAddColumn);\n }\n hasRemoveButtons() {\n return !this.builderMode && !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n hasTopSubmit() {\n return this.hasAddButton() && ['top', 'both'].includes(this.addAnotherPosition);\n }\n hasBottomSubmit() {\n return this.hasAddButton() && ['bottom', 'both'].includes(this.addAnotherPosition);\n }\n get canAddColumn() {\n return this.builderMode && !this.options.design;\n }\n render() {\n const columns = this.getColumns();\n let columnExtra = 0;\n const hasRemoveButtons = this.hasRemoveButtons();\n if (this.component.reorder) {\n columnExtra++;\n }\n if (hasRemoveButtons) {\n columnExtra++;\n }\n if (this.canAddColumn) {\n columnExtra++;\n }\n const colWidth = Math.floor(12 / (columns.length + columnExtra));\n return super.render(this.renderTemplate('datagrid', {\n rows: this.getRows(),\n columns: columns,\n groups: this.hasRowGroups() ? this.getGroups() : [],\n visibleColumns: this.visibleColumns,\n hasToggle: lodash_1.default.get(this, 'component.groupToggle', false),\n hasHeader: this.hasHeader(),\n hasExtraColumn: this.hasExtraColumn(),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons,\n hasTopSubmit: this.hasTopSubmit(),\n hasBottomSubmit: this.hasBottomSubmit(),\n hasGroups: this.hasRowGroups(),\n numColumns: columns.length + (this.hasExtraColumn() ? 1 : 0),\n datagridKey: this.datagridKey,\n allowReorder: this.allowReorder,\n builder: this.builderMode,\n canAddColumn: this.canAddColumn,\n tabIndex: this.tabIndex,\n placeholder: this.renderTemplate('builderPlaceholder', {\n position: this.componentComponents.length,\n }),\n colWidth: colWidth.toString()\n }));\n }\n getRows() {\n return this.rows.map(row => {\n const components = {};\n lodash_1.default.each(row, (col, key) => {\n components[key] = col.render();\n });\n return components;\n });\n }\n getColumns() {\n return this.columns.filter((comp) => {\n return (!this.visibleColumns.hasOwnProperty(comp.key) || this.visibleColumns[comp.key]);\n });\n }\n hasHeader() {\n return this.component.components.reduce((hasHeader, col) => {\n // If any of the components has a title and it isn't hidden, display the header.\n return hasHeader || ((col.label || col.title) && !col.hideLabel);\n }, false);\n }\n attach(element) {\n this.loadRefs(element, {\n [`${this.datagridKey}-row`]: 'multiple',\n [`${this.datagridKey}-tbody`]: 'single',\n [`${this.datagridKey}-addRow`]: 'multiple',\n [`${this.datagridKey}-removeRow`]: 'multiple',\n [`${this.datagridKey}-group-header`]: 'multiple',\n [this.datagridKey]: 'multiple',\n });\n if (this.allowReorder) {\n this.refs[`${this.datagridKey}-row`].forEach((row, index) => {\n row.dragInfo = { index };\n });\n this.dragula = (0, dragula_1.default)([this.refs[`${this.datagridKey}-tbody`]], {\n moves: (_draggedElement, _oldParent, clickedElement) => {\n const clickedElementKey = clickedElement.getAttribute('data-key');\n const oldParentKey = _oldParent.getAttribute('data-key');\n //Check if the clicked button belongs to that container, if false, it belongs to the nested container\n if (oldParentKey === clickedElementKey) {\n return clickedElement.classList.contains('formio-drag-button');\n }\n }\n }).on('drop', this.onReorder.bind(this));\n this.dragula.on('cloned', (el, original) => {\n if (el && el.children && original && original.children) {\n lodash_1.default.each(original.children, (child, index) => {\n const styles = getComputedStyle(child, null);\n if (styles.cssText !== '') {\n el.children[index].style.cssText = styles.cssText;\n }\n else {\n const cssText = Object.values(styles).reduce((css, propertyName) => {\n return `${css}${propertyName}:${styles.getPropertyValue(propertyName)};`;\n }, '');\n el.children[index].style.cssText = cssText;\n }\n });\n }\n });\n }\n this.refs[`${this.datagridKey}-addRow`].forEach((addButton) => {\n this.addEventListener(addButton, 'click', this.addRow.bind(this));\n });\n this.refs[`${this.datagridKey}-removeRow`].forEach((removeButton, index) => {\n this.addEventListener(removeButton, 'click', this.removeRow.bind(this, index));\n });\n if (this.hasRowGroups()) {\n this.refs.chunks = this.getRowChunks(this.getGroupSizes(), this.refs[`${this.datagridKey}-row`]);\n this.refs[`${this.datagridKey}-group-header`].forEach((header, index) => {\n this.addEventListener(header, 'click', () => this.toggleGroup(header, index));\n });\n }\n const columns = this.getColumns();\n const rowLength = columns.length;\n this.rows.forEach((row, rowIndex) => {\n let columnIndex = 0;\n columns.forEach((col) => {\n this.attachComponents(this.refs[this.datagridKey][(rowIndex * rowLength) + columnIndex], [this.rows[rowIndex][col.key]], this.getComponentsContainer());\n columnIndex++;\n });\n });\n return super.attach(element);\n }\n getComponentsContainer() {\n return this.component.components;\n }\n /**\n * Reorder values in array based on the old and new position\n * @param {any} valuesArr - An array of values.\n * @param {number} oldPosition - The index of the value in array before reordering.\n * @param {number} newPosition - The index of the value in array after reordering.\n * @param {boolean|any} movedBelow - Whether or not the value is moved below.\n * @returns {void}\n */\n reorderValues(valuesArr, oldPosition, newPosition, movedBelow) {\n if (!lodash_1.default.isArray(valuesArr) || lodash_1.default.isEmpty(valuesArr)) {\n return;\n }\n const draggedRowData = valuesArr[oldPosition];\n //insert element at new position\n valuesArr.splice(newPosition, 0, draggedRowData);\n //remove element from old position (if was moved above, after insertion it's at +1 index)\n valuesArr.splice(movedBelow ? oldPosition : oldPosition + 1, 1);\n }\n onReorder(element, _target, _source, sibling) {\n if (!element.dragInfo || (sibling && !sibling.dragInfo)) {\n console.warn('There is no Drag Info available for either dragged or sibling element');\n return;\n }\n const oldPosition = element.dragInfo.index;\n //should drop at next sibling position; no next sibling means drop to last position\n const newPosition = sibling ? sibling.dragInfo.index : this.dataValue.length;\n const movedBelow = newPosition > oldPosition;\n const dataValue = (0, utils_1.fastCloneDeep)(this.dataValue);\n this.reorderValues(dataValue, oldPosition, newPosition, movedBelow);\n //reorder select data\n this.reorderValues(lodash_1.default.get(this.root, `submission.metadata.selectData.${this.path}`, []), oldPosition, newPosition, movedBelow);\n //need to re-build rows to re-calculate indexes and other indexed fields for component instance (like rows for ex.)\n this.setValue(dataValue, { isReordered: true });\n this.rebuild();\n }\n focusOnNewRowElement(row) {\n Object.keys(row).find((key) => {\n const element = row[key].element;\n if (element) {\n const focusableElements = (0, utils_1.getFocusableElements)(element);\n if (focusableElements && focusableElements[0]) {\n focusableElements[0].focus();\n return true;\n }\n }\n return false;\n });\n }\n addRow() {\n const index = this.rows.length;\n // Handle length mismatch between rows and dataValue\n if (this.dataValue.length === index) {\n this.dataValue.push({});\n }\n let row;\n const dataValue = this.dataValue;\n const defaultValue = this.defaultValue;\n if (this.initEmpty && defaultValue[index]) {\n row = defaultValue[index];\n dataValue[index] = row;\n }\n else {\n row = dataValue[index];\n }\n this.rows[index] = this.createRowComponents(row, index);\n this.emit('dataGridAddRow', {\n component: this.component,\n row\n });\n this.checkConditions();\n this.triggerChange();\n this.redraw().then(() => {\n this.focusOnNewRowElement(this.rows[index]);\n });\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n var _a;\n if ((_a = component.options) === null || _a === void 0 ? void 0 : _a.name) {\n const newName = `[${this.key}][${rowIndex}]`;\n component.options.name = component.options.name.replace(`[${this.key}][${component.rowIndex}]`, newName);\n }\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n component.path = Components_1.default.getComponentPath(component);\n });\n }\n updateRowsComponents(rowIndex) {\n this.rows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(Object.values(row), rowIndex + index);\n });\n }\n removeRow(index) {\n const makeEmpty = index === 0 && this.rows.length === 1;\n const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };\n this.splice(index, flags);\n this.emit('dataGridDeleteRow', { index });\n const [row] = this.rows.splice(index, 1);\n this.removeRowComponents(row);\n this.updateRowsComponents(index);\n this.setValue(this.dataValue, flags);\n this.redraw();\n }\n removeRowComponents(row) {\n lodash_1.default.each(row, (component) => this.removeComponent(component));\n }\n getRowValues() {\n return this.dataValue;\n }\n setRowComponentsData(rowIndex, rowData) {\n lodash_1.default.each(this.rows[rowIndex], (component) => {\n component.data = rowData;\n });\n }\n createRows(init, rebuild) {\n let added = false;\n const rowValues = this.getRowValues();\n // Create any missing rows.\n rowValues.forEach((row, index) => {\n if (!rebuild && this.rows[index]) {\n this.setRowComponentsData(index, row);\n }\n else {\n if (this.rows[index]) {\n this.removeRowComponents(this.rows[index]);\n }\n this.rows[index] = this.createRowComponents(row, index);\n added = true;\n }\n });\n // Delete any extra rows.\n const removedRows = this.rows.splice(rowValues.length);\n const removed = !!removedRows.length;\n // Delete components of extra rows (to make sure that this.components contain only components of exisiting rows)\n if (removed) {\n removedRows.forEach(row => this.removeRowComponents(row));\n }\n if (!init && (added || removed)) {\n this.redraw();\n }\n return added;\n }\n createRowComponents(row, rowIndex) {\n const components = {};\n this.tabIndex = 0;\n this.component.components.map((col, colIndex) => {\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n let columnComponent;\n if (this.builderMode) {\n col.id = col.id + rowIndex;\n columnComponent = col;\n }\n else {\n columnComponent = Object.assign(Object.assign({}, col), { id: (col.id + rowIndex) });\n }\n const component = this.createComponent(columnComponent, options, row);\n component.parentDisabled = !!this.disabled;\n component.rowIndex = rowIndex;\n component.inDataGrid = true;\n if (columnComponent.tabindex &&\n parseInt(columnComponent.tabindex) > this.tabIndex) {\n this.tabIndex = parseInt(columnComponent.tabindex);\n }\n components[col.key] = component;\n });\n return components;\n }\n checkColumns(data, flags = {}) {\n data = data || this.rootValue;\n let show = false;\n if (!this.rows || !this.rows.length) {\n return { rebuild: false, show: false };\n }\n if (this.builderMode) {\n return { rebuild: false, show: true };\n }\n const visibility = {};\n let logicRebuild = false;\n const dataValue = this.dataValue;\n this.rows.forEach((row, rowIndex) => {\n lodash_1.default.each(row, (col, key) => {\n if (col && (typeof col.checkConditions === 'function')) {\n const firstRowCheck = visibility[key] === undefined;\n visibility[key] = !!visibility[key] ||\n (col.checkConditions(data, flags, dataValue[rowIndex]) && col.type !== 'hidden');\n if (col.component.logic && firstRowCheck) {\n const compIndex = lodash_1.default.findIndex(this.columns, ['key', key]);\n const equalColumns = lodash_1.default.isEqualWith(this.columns[compIndex], col.component, (col1, col2, key) => {\n // Don't compare columns by their auto-generated ids.\n if (key === 'id') {\n return true;\n }\n });\n if (!equalColumns) {\n logicRebuild = true;\n this.columns[compIndex] = col.component;\n }\n }\n }\n });\n });\n const rebuild = !lodash_1.default.isEqual(visibility, this.visibleColumns) || logicRebuild;\n lodash_1.default.each(visibility, (col) => {\n show |= col;\n });\n this.visibleColumns = visibility;\n return { rebuild, show };\n }\n checkComponentConditions(data, flags, row) {\n const isVisible = this.visible;\n // If table isn't visible, don't bother calculating columns.\n if (!super.checkComponentConditions(data, flags, row)) {\n return false;\n }\n const { rebuild, show } = this.checkColumns(data, flags);\n // Check if a rebuild is needed or the visibility changes.\n if (rebuild || !isVisible) {\n this.createRows(false, rebuild);\n }\n // Return if this table should show.\n return show;\n }\n setValue(value, flags = {}) {\n if (!value) {\n this.dataValue = this.defaultValue;\n this.createRows();\n return false;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n this.createRows();\n value = [{}];\n }\n }\n // Make sure we always have at least one row.\n // NOTE: Removing this will break \"Public Configurations\" in portal. ;)\n if (value && !value.length && !this.initEmpty) {\n value.push({});\n }\n const isSettingSubmission = flags.fromSubmission && !lodash_1.default.isEqual(value, this.emptyValue);\n const changed = this.hasChanged(value, this.dataValue);\n this.dataValue = value;\n if (this.initRows || isSettingSubmission ||\n (Array.isArray(this.dataValue) && this.dataValue.length !== this.rows.length)) {\n if (!this.createRows() && changed) {\n this.redraw();\n }\n }\n if (this.componentModal && isSettingSubmission) {\n this.componentModal.setValue(value);\n }\n this.rows.forEach((row, rowIndex) => {\n if (value.length <= rowIndex) {\n return;\n }\n lodash_1.default.each(row, (col) => {\n col.rowIndex = rowIndex;\n this.setNestedValue(col, value[rowIndex], flags);\n });\n });\n this.updateOnChange(flags, changed);\n return changed;\n }\n restoreComponentsContext() {\n this.rows.forEach((row, index) => lodash_1.default.forIn(row, (component) => component.data = this.dataValue[index]));\n }\n getComponent(path, fn) {\n path = Array.isArray(path) ? path : [path];\n const [key, ...remainingPath] = path;\n let result = [];\n if (lodash_1.default.isNumber(key) && remainingPath.length) {\n const compKey = remainingPath.pop();\n result = this.rows[key][compKey];\n // If the component is inside a Layout Component, try to find it among all the row's components\n if (!result) {\n Object.entries(this.rows[key]).forEach(([, comp]) => {\n if ('getComponent' in comp) {\n const possibleResult = comp.getComponent([compKey], fn);\n if (possibleResult) {\n result = possibleResult;\n }\n }\n });\n }\n if (result && lodash_1.default.isFunction(fn)) {\n fn(result, this.getComponents());\n }\n if (remainingPath.length && 'getComponent' in result) {\n return result.getComponent(remainingPath, fn);\n }\n return result;\n }\n if (!lodash_1.default.isString(key)) {\n return result;\n }\n this.everyComponent((component, components) => {\n if (component.component.key === key) {\n let comp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn);\n }\n else if (fn) {\n fn(component, components);\n }\n result = result.concat(comp);\n }\n });\n return result.length > 0 ? result : null;\n }\n toggleGroup(element, index) {\n element.classList.toggle('collapsed');\n lodash_1.default.each(this.refs.chunks[index], row => {\n row.classList.toggle('hidden');\n });\n }\n}\nexports[\"default\"] = DataGridComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/datagrid/DataGrid.js?");
|
6032
|
+
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 NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Components_1 = __importDefault(__webpack_require__(/*! ../Components */ \"./lib/cjs/components/Components.js\"));\nconst dragula_1 = __importDefault(__webpack_require__(/*! dragula */ \"./node_modules/dragula/dragula.js\"));\nclass DataGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n label: 'Data Grid',\n key: 'dataGrid',\n type: 'datagrid',\n clearOnHide: true,\n input: true,\n tree: true,\n components: []\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Data Grid',\n icon: 'th',\n group: 'data',\n documentation: '/userguide/form-building/data-components#data-grid',\n showPreview: false,\n weight: 30,\n schema: DataGridComponent.schema()\n };\n }\n constructor(...args) {\n super(...args);\n this.type = 'datagrid';\n this.tabIndex = 0;\n }\n init() {\n this.components = this.components || [];\n // Add new values based on minLength.\n this.rows = [];\n this.columns = [...this.component.components];\n if (this.initRows || !lodash_1.default.isEqual(this.dataValue, this.emptyValue)) {\n this.createRows(true);\n }\n this.visibleColumns = {};\n this.prevHasAddButton = this.hasAddButton();\n this.checkColumns();\n }\n get dataValue() {\n const dataValue = super.dataValue;\n if (!dataValue || !Array.isArray(dataValue)) {\n return this.emptyValue;\n }\n return dataValue;\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get defaultSchema() {\n return DataGridComponent.schema();\n }\n get initEmpty() {\n return this.component.initEmpty || this.component.noFirstRow;\n }\n get initRows() {\n return this.builderMode || this.path === 'defaultValue' || !this.initEmpty;\n }\n get emptyValue() {\n return this.initEmpty ? [] : [{}];\n }\n get addAnotherPosition() {\n return lodash_1.default.get(this.component, 'addAnotherPosition', 'bottom');\n }\n get minLength() {\n if (this.hasRowGroups()) {\n return lodash_1.default.sum(this.getGroupSizes());\n }\n else {\n return lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n }\n get defaultValue() {\n const isBuilderMode = this.builderMode;\n const isEmptyInit = this.initEmpty;\n // Ensure we have one and only one row in builder mode.\n if (isBuilderMode || (isEmptyInit && !this.dataValue.length)) {\n return isEmptyInit && !isBuilderMode ? [] : [{}];\n }\n const value = super.defaultValue;\n let defaultValue;\n if (Array.isArray(value)) {\n defaultValue = value;\n }\n else if (value && (typeof value === 'object')) {\n defaultValue = [value];\n }\n else {\n defaultValue = this.emptyValue;\n }\n for (let dIndex = defaultValue.length; dIndex < this.minLength; dIndex++) {\n defaultValue.push({});\n }\n return defaultValue;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n lodash_1.default.each(this.refs[`${this.datagridKey}-addRow`], (button) => {\n button.disabled = disabled;\n });\n lodash_1.default.each(this.refs[`${this.datagridKey}-removeRow`], (button) => {\n button.disabled = disabled;\n });\n }\n get disabled() {\n return super.disabled;\n }\n get datagridKey() {\n return `datagrid-${this.key}`;\n }\n get allowReorder() {\n return !this.options.readOnly && lodash_1.default.get(this.component, 'reorder', false);\n }\n get iteratableRows() {\n return this.rows.map((row, index) => ({\n components: row,\n data: this.dataValue[index],\n }));\n }\n isEmpty(value = this.dataValue) {\n var _a;\n const isEmpty = super.isEmpty(value);\n if ((_a = this.components) === null || _a === void 0 ? void 0 : _a.length) {\n return this.components.reduce((isEmpty, component) => {\n return isEmpty && component.isEmpty();\n }, true);\n }\n return isEmpty;\n }\n /**\n * Split rows into chunks.\n * @param {number[]} groups - array of numbers where each item is size of group\n * @param {Array<T>} rows - rows collection\n * @returns {Array<T[]>} - The chunked rows\n */\n getRowChunks(groups, rows) {\n const [, chunks] = groups.reduce(([startIndex, acc], size) => {\n const endIndex = startIndex + size;\n return [endIndex, [...acc, [startIndex, endIndex]]];\n }, [0, []]);\n return chunks.map(range => lodash_1.default.slice(rows, ...range));\n }\n /**\n * Create groups object.\n * Each key in object represents index of first row in group.\n * @returns {object} - The groups object.\n */\n getGroups() {\n const groups = lodash_1.default.get(this.component, 'rowGroups', []);\n const sizes = lodash_1.default.map(groups, 'numberOfRows').slice(0, -1);\n const indexes = sizes.reduce((groupIndexes, size) => {\n const last = groupIndexes[groupIndexes.length - 1];\n return groupIndexes.concat(last + size);\n }, [0]);\n return groups.reduce((gidxs, group, idx) => {\n return Object.assign(Object.assign({}, gidxs), { [indexes[idx]]: group });\n }, {});\n }\n /**\n * Get group sizes.\n * @returns {number[]} - The array of group sizes.\n */\n getGroupSizes() {\n return lodash_1.default.map(lodash_1.default.get(this.component, 'rowGroups', []), 'numberOfRows');\n }\n hasRowGroups() {\n return lodash_1.default.get(this, 'component.enableRowGroups', false) && !this.builderMode;\n }\n totalRowsNumber(groups) {\n return lodash_1.default.sum(lodash_1.default.map(groups, 'numberOfRows'));\n }\n setStaticValue(n) {\n this.dataValue = lodash_1.default.range(n).map(() => ({}));\n }\n hasExtraColumn() {\n return (this.hasRemoveButtons() || this.canAddColumn);\n }\n hasRemoveButtons() {\n return !this.builderMode && !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n hasTopSubmit() {\n return this.hasAddButton() && ['top', 'both'].includes(this.addAnotherPosition);\n }\n hasBottomSubmit() {\n return this.hasAddButton() && ['bottom', 'both'].includes(this.addAnotherPosition);\n }\n get canAddColumn() {\n return this.builderMode && !this.options.design;\n }\n render() {\n const columns = this.getColumns();\n let columnExtra = 0;\n const hasRemoveButtons = this.hasRemoveButtons();\n if (this.component.reorder) {\n columnExtra++;\n }\n if (hasRemoveButtons) {\n columnExtra++;\n }\n if (this.canAddColumn) {\n columnExtra++;\n }\n const colWidth = Math.floor(12 / (columns.length + columnExtra));\n return super.render(this.renderTemplate('datagrid', {\n rows: this.getRows(),\n columns: columns,\n groups: this.hasRowGroups() ? this.getGroups() : [],\n visibleColumns: this.visibleColumns,\n hasToggle: lodash_1.default.get(this, 'component.groupToggle', false),\n hasHeader: this.hasHeader(),\n hasExtraColumn: this.hasExtraColumn(),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons,\n hasTopSubmit: this.hasTopSubmit(),\n hasBottomSubmit: this.hasBottomSubmit(),\n hasGroups: this.hasRowGroups(),\n numColumns: columns.length + (this.hasExtraColumn() ? 1 : 0),\n datagridKey: this.datagridKey,\n allowReorder: this.allowReorder,\n builder: this.builderMode,\n canAddColumn: this.canAddColumn,\n tabIndex: this.tabIndex,\n placeholder: this.renderTemplate('builderPlaceholder', {\n position: this.componentComponents.length,\n }),\n colWidth: colWidth.toString()\n }));\n }\n getRows() {\n return this.rows.map(row => {\n const components = {};\n lodash_1.default.each(row, (col, key) => {\n components[key] = col.render();\n });\n return components;\n });\n }\n getColumns() {\n return this.columns.filter((comp) => {\n return (!this.visibleColumns.hasOwnProperty(comp.key) || this.visibleColumns[comp.key]);\n });\n }\n hasHeader() {\n return this.component.components.reduce((hasHeader, col) => {\n // If any of the components has a title and it isn't hidden, display the header.\n return hasHeader || ((col.label || col.title) && !col.hideLabel);\n }, false);\n }\n attach(element) {\n this.loadRefs(element, {\n [`${this.datagridKey}-row`]: 'multiple',\n [`${this.datagridKey}-tbody`]: 'single',\n [`${this.datagridKey}-addRow`]: 'multiple',\n [`${this.datagridKey}-removeRow`]: 'multiple',\n [`${this.datagridKey}-group-header`]: 'multiple',\n [this.datagridKey]: 'multiple',\n });\n if (this.allowReorder) {\n this.refs[`${this.datagridKey}-row`].forEach((row, index) => {\n row.dragInfo = { index };\n });\n this.dragula = (0, dragula_1.default)([this.refs[`${this.datagridKey}-tbody`]], {\n moves: (_draggedElement, _oldParent, clickedElement) => {\n const clickedElementKey = clickedElement.getAttribute('data-key');\n const oldParentKey = _oldParent.getAttribute('data-key');\n //Check if the clicked button belongs to that container, if false, it belongs to the nested container\n if (oldParentKey === clickedElementKey) {\n return clickedElement.classList.contains('formio-drag-button');\n }\n }\n }).on('drop', this.onReorder.bind(this));\n this.dragula.on('cloned', (el, original) => {\n if (el && el.children && original && original.children) {\n lodash_1.default.each(original.children, (child, index) => {\n const styles = getComputedStyle(child, null);\n if (styles.cssText !== '') {\n el.children[index].style.cssText = styles.cssText;\n }\n else {\n const cssText = Object.values(styles).reduce((css, propertyName) => {\n return `${css}${propertyName}:${styles.getPropertyValue(propertyName)};`;\n }, '');\n el.children[index].style.cssText = cssText;\n }\n });\n }\n });\n }\n this.refs[`${this.datagridKey}-addRow`].forEach((addButton) => {\n this.addEventListener(addButton, 'click', this.addRow.bind(this));\n });\n this.refs[`${this.datagridKey}-removeRow`].forEach((removeButton, index) => {\n this.addEventListener(removeButton, 'click', this.removeRow.bind(this, index));\n });\n if (this.hasRowGroups()) {\n this.refs.chunks = this.getRowChunks(this.getGroupSizes(), this.refs[`${this.datagridKey}-row`]);\n this.refs[`${this.datagridKey}-group-header`].forEach((header, index) => {\n this.addEventListener(header, 'click', () => this.toggleGroup(header, index));\n });\n }\n const columns = this.getColumns();\n const rowLength = columns.length;\n this.rows.forEach((row, rowIndex) => {\n let columnIndex = 0;\n columns.forEach((col) => {\n this.attachComponents(this.refs[this.datagridKey][(rowIndex * rowLength) + columnIndex], [this.rows[rowIndex][col.key]], this.getComponentsContainer());\n columnIndex++;\n });\n });\n return super.attach(element);\n }\n getComponentsContainer() {\n return this.component.components;\n }\n /**\n * Reorder values in array based on the old and new position\n * @param {any} valuesArr - An array of values.\n * @param {number} oldPosition - The index of the value in array before reordering.\n * @param {number} newPosition - The index of the value in array after reordering.\n * @param {boolean|any} movedBelow - Whether or not the value is moved below.\n * @returns {void}\n */\n reorderValues(valuesArr, oldPosition, newPosition, movedBelow) {\n if (!lodash_1.default.isArray(valuesArr) || lodash_1.default.isEmpty(valuesArr)) {\n return;\n }\n const draggedRowData = valuesArr[oldPosition];\n //insert element at new position\n valuesArr.splice(newPosition, 0, draggedRowData);\n //remove element from old position (if was moved above, after insertion it's at +1 index)\n valuesArr.splice(movedBelow ? oldPosition : oldPosition + 1, 1);\n }\n onReorder(element, _target, _source, sibling) {\n if (!element.dragInfo || (sibling && !sibling.dragInfo)) {\n console.warn('There is no Drag Info available for either dragged or sibling element');\n return;\n }\n const oldPosition = element.dragInfo.index;\n //should drop at next sibling position; no next sibling means drop to last position\n const newPosition = sibling ? sibling.dragInfo.index : this.dataValue.length;\n const movedBelow = newPosition > oldPosition;\n const dataValue = (0, utils_1.fastCloneDeep)(this.dataValue);\n this.reorderValues(dataValue, oldPosition, newPosition, movedBelow);\n //reorder select data\n this.reorderValues(lodash_1.default.get(this.root, `submission.metadata.selectData.${this.path}`, []), oldPosition, newPosition, movedBelow);\n //need to re-build rows to re-calculate indexes and other indexed fields for component instance (like rows for ex.)\n this.setValue(dataValue, { isReordered: true });\n this.rebuild();\n }\n focusOnNewRowElement(row) {\n Object.keys(row).find((key) => {\n const element = row[key].element;\n if (element) {\n const focusableElements = (0, utils_1.getFocusableElements)(element);\n if (focusableElements && focusableElements[0]) {\n focusableElements[0].focus();\n return true;\n }\n }\n return false;\n });\n }\n addRow() {\n const index = this.rows.length;\n // Handle length mismatch between rows and dataValue\n if (this.dataValue.length === index) {\n this.dataValue.push({});\n }\n let row;\n const dataValue = this.dataValue;\n const defaultValue = this.defaultValue;\n if (this.initEmpty && defaultValue[index]) {\n row = defaultValue[index];\n dataValue[index] = row;\n }\n else {\n row = dataValue[index];\n }\n this.rows[index] = this.createRowComponents(row, index);\n this.emit('dataGridAddRow', {\n component: this.component,\n row\n });\n this.checkConditions();\n this.triggerChange();\n this.redraw().then(() => {\n this.focusOnNewRowElement(this.rows[index]);\n });\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n var _a;\n if ((_a = component.options) === null || _a === void 0 ? void 0 : _a.name) {\n const newName = `[${this.key}][${rowIndex}]`;\n component.options.name = component.options.name.replace(`[${this.key}][${component.rowIndex}]`, newName);\n }\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n component.path = Components_1.default.getComponentPath(component);\n });\n }\n updateRowsComponents(rowIndex) {\n this.rows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(Object.values(row), rowIndex + index);\n });\n }\n removeRow(index) {\n const makeEmpty = index === 0 && this.rows.length === 1;\n const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };\n this.splice(index, flags);\n this.emit('dataGridDeleteRow', { index });\n const [row] = this.rows.splice(index, 1);\n this.removeSubmissionMetadataRow(index);\n this.removeRowComponents(row);\n this.updateRowsComponents(index);\n this.setValue(this.dataValue, flags);\n this.redraw();\n }\n removeRowComponents(row) {\n lodash_1.default.each(row, (component) => this.removeComponent(component));\n }\n getRowValues() {\n return this.dataValue;\n }\n setRowComponentsData(rowIndex, rowData) {\n lodash_1.default.each(this.rows[rowIndex], (component) => {\n component.data = rowData;\n });\n }\n createRows(init, rebuild) {\n let added = false;\n const rowValues = this.getRowValues();\n // Create any missing rows.\n rowValues.forEach((row, index) => {\n if (!rebuild && this.rows[index]) {\n this.setRowComponentsData(index, row);\n }\n else {\n if (this.rows[index]) {\n this.removeRowComponents(this.rows[index]);\n }\n this.rows[index] = this.createRowComponents(row, index);\n added = true;\n }\n });\n // Delete any extra rows.\n const removedRows = this.rows.splice(rowValues.length);\n const removed = !!removedRows.length;\n // Delete components of extra rows (to make sure that this.components contain only components of exisiting rows)\n if (removed) {\n removedRows.forEach(row => this.removeRowComponents(row));\n }\n if (!init && (added || removed)) {\n this.redraw();\n }\n return added;\n }\n createRowComponents(row, rowIndex) {\n const components = {};\n this.tabIndex = 0;\n this.component.components.map((col, colIndex) => {\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n let columnComponent;\n if (this.builderMode) {\n col.id = col.id + rowIndex;\n columnComponent = col;\n }\n else {\n columnComponent = Object.assign(Object.assign({}, col), { id: (col.id + rowIndex) });\n }\n const component = this.createComponent(columnComponent, options, row);\n component.parentDisabled = !!this.disabled;\n component.rowIndex = rowIndex;\n component.inDataGrid = true;\n if (columnComponent.tabindex &&\n parseInt(columnComponent.tabindex) > this.tabIndex) {\n this.tabIndex = parseInt(columnComponent.tabindex);\n }\n components[col.key] = component;\n });\n return components;\n }\n checkColumns(data, flags = {}) {\n data = data || this.rootValue;\n let show = false;\n if (!this.rows || !this.rows.length) {\n return { rebuild: false, show: false };\n }\n if (this.builderMode) {\n return { rebuild: false, show: true };\n }\n const visibility = {};\n let logicRebuild = false;\n const dataValue = this.dataValue;\n this.rows.forEach((row, rowIndex) => {\n lodash_1.default.each(row, (col, key) => {\n if (col && (typeof col.checkConditions === 'function')) {\n const firstRowCheck = visibility[key] === undefined;\n visibility[key] = !!visibility[key] ||\n (col.checkConditions(data, flags, dataValue[rowIndex]) && col.type !== 'hidden');\n if (col.component.logic && firstRowCheck) {\n const compIndex = lodash_1.default.findIndex(this.columns, ['key', key]);\n const equalColumns = lodash_1.default.isEqualWith(this.columns[compIndex], col.component, (col1, col2, key) => {\n // Don't compare columns by their auto-generated ids.\n if (key === 'id') {\n return true;\n }\n });\n if (!equalColumns) {\n logicRebuild = true;\n this.columns[compIndex] = col.component;\n }\n }\n }\n });\n });\n const rebuild = !lodash_1.default.isEqual(visibility, this.visibleColumns) || logicRebuild;\n lodash_1.default.each(visibility, (col) => {\n show |= col;\n });\n this.visibleColumns = visibility;\n return { rebuild, show };\n }\n checkComponentConditions(data, flags, row) {\n const isVisible = this.visible;\n // If table isn't visible, don't bother calculating columns.\n if (!super.checkComponentConditions(data, flags, row)) {\n return false;\n }\n const { rebuild, show } = this.checkColumns(data, flags);\n // Check if a rebuild is needed or the visibility changes.\n if (rebuild || !isVisible) {\n this.createRows(false, rebuild);\n }\n // Return if this table should show.\n return show;\n }\n setValue(value, flags = {}) {\n if (!value) {\n this.dataValue = this.defaultValue;\n this.createRows();\n return false;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n this.createRows();\n value = [{}];\n }\n }\n // Make sure we always have at least one row.\n // NOTE: Removing this will break \"Public Configurations\" in portal. ;)\n if (value && !value.length && !this.initEmpty) {\n value.push({});\n }\n const isSettingSubmission = flags.fromSubmission && !lodash_1.default.isEqual(value, this.emptyValue);\n const changed = this.hasChanged(value, this.dataValue);\n this.dataValue = value;\n if (this.initRows || isSettingSubmission ||\n (Array.isArray(this.dataValue) && this.dataValue.length !== this.rows.length)) {\n if (!this.createRows() && changed) {\n this.redraw();\n }\n }\n if (this.componentModal && isSettingSubmission) {\n this.componentModal.setValue(value);\n }\n this.rows.forEach((row, rowIndex) => {\n if (value.length <= rowIndex) {\n return;\n }\n lodash_1.default.each(row, (col) => {\n col.rowIndex = rowIndex;\n this.setNestedValue(col, value[rowIndex], flags);\n });\n });\n this.updateOnChange(flags, changed);\n return changed;\n }\n restoreComponentsContext() {\n this.rows.forEach((row, index) => lodash_1.default.forIn(row, (component) => component.data = this.dataValue[index]));\n }\n getComponent(path, fn) {\n path = Array.isArray(path) ? path : [path];\n const [key, ...remainingPath] = path;\n let result = [];\n if (lodash_1.default.isNumber(key) && remainingPath.length) {\n const compKey = remainingPath.pop();\n result = this.rows[key][compKey];\n // If the component is inside a Layout Component, try to find it among all the row's components\n if (!result) {\n Object.entries(this.rows[key]).forEach(([, comp]) => {\n if ('getComponent' in comp) {\n const possibleResult = comp.getComponent([compKey], fn);\n if (possibleResult) {\n result = possibleResult;\n }\n }\n });\n }\n if (result && lodash_1.default.isFunction(fn)) {\n fn(result, this.getComponents());\n }\n if (remainingPath.length && 'getComponent' in result) {\n return result.getComponent(remainingPath, fn);\n }\n return result;\n }\n if (!lodash_1.default.isString(key)) {\n return result;\n }\n this.everyComponent((component, components) => {\n if (component.component.key === key) {\n let comp = component;\n if (remainingPath.length > 0 && 'getComponent' in component) {\n comp = component.getComponent(remainingPath, fn);\n }\n else if (fn) {\n fn(component, components);\n }\n result = result.concat(comp);\n }\n });\n return result.length > 0 ? result : null;\n }\n toggleGroup(element, index) {\n element.classList.toggle('collapsed');\n lodash_1.default.each(this.refs.chunks[index], row => {\n row.classList.toggle('hidden');\n });\n }\n}\nexports[\"default\"] = DataGridComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/datagrid/DataGrid.js?");
|
6033
6033
|
|
6034
6034
|
/***/ }),
|
6035
6035
|
|
@@ -6293,7 +6293,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6293
6293
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
6294
6294
|
|
6295
6295
|
"use strict";
|
6296
|
-
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 process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst components_1 = __webpack_require__(/*! @formio/bootstrap/components */ \"./node_modules/@formio/bootstrap/lib/cjs/templates/components/index.js\");\nconst NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst Alert_1 = __importDefault(__webpack_require__(/*! ../alert/Alert */ \"./lib/cjs/components/alert/Alert.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst EditRowState = {\n New: 'new',\n Editing: 'editing',\n Saved: 'saved',\n Viewing: 'viewing',\n Removed: 'removed',\n Draft: 'draft',\n};\nclass EditGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n type: 'editgrid',\n label: 'Edit Grid',\n key: 'editGrid',\n clearOnHide: true,\n input: true,\n tree: true,\n removeRow: 'Cancel',\n defaultOpen: false,\n openWhenEmpty: false,\n modal: false,\n components: [],\n inlineEdit: false,\n templates: {\n header: EditGridComponent.defaultHeaderTemplate,\n row: EditGridComponent.defaultRowTemplate,\n tableHeader: EditGridComponent.defaultTableHeaderTemplate,\n tableRow: EditGridComponent.defaultTableRowTemplate,\n footer: '',\n },\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Edit Grid',\n icon: 'tasks',\n group: 'data',\n documentation: '/userguide/form-building/data-components#edit-grid',\n showPreview: false,\n weight: 30,\n schema: EditGridComponent.schema(),\n };\n }\n static get defaultHeaderTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">{{ t(component.label) }}</div>\n {% } %}\n {% }) %}\n </div>`;\n }\n static get defaultTableHeaderTemplate() {\n return `\n <tr>\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">{{ component.label }}</td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">Actions</td>\n {% } %}\n </tr>\n `;\n }\n static get defaultRowTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">\n {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}\n </div>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <div class=\"col-sm-2\">\n <div class=\"btn-group pull-right\">\n <button class=\"btn btn-default btn-light btn-sm editRow\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </div>\n {% } %}\n </div>`;\n }\n static get defaultTableRowTemplate() {\n return `\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">\n {{ getView(component, row[component.key]) }}\n </td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">\n <div class=\"btn-group\">\n <button class=\"btn btn-default btn-light btn-sm editRow\" aria-label=\"{{ t('Edit row') }}\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\" aria-label=\"{{ t('Remove row') }}\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </td>\n {% } %}\n `;\n }\n get defaultDialogTemplate() {\n return `\n <h3 ${this._referenceAttributeName}=\"dialogHeader\">${this.t('Do you want to clear data?')}</h3>\n <div style=\"display:flex; justify-content: flex-end;\">\n <button ${this._referenceAttributeName}=\"dialogCancelButton\" class=\"btn btn-secondary\" aria-label=\"${this.t('Cancel')}\">${this.t('Cancel')}</button>\n <button ${this._referenceAttributeName}=\"dialogYesButton\" class=\"btn btn-danger\" aria-label=\"${this.t('Yes, delete it')}\">${this.t('Yes, delete it')}</button>\n </div>\n `;\n }\n get defaultRowTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableRowTemplate\n : EditGridComponent.defaultRowTemplate;\n }\n get defaultHeaderTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableHeaderTemplate\n : EditGridComponent.defaultHeaderTemplate;\n }\n get rowTemplate() {\n let rowTemplate;\n if (utils_1.Evaluator.noeval) {\n rowTemplate = this.displayAsTable ?\n components_1.editgrid.tableRow\n : components_1.editgrid.row;\n }\n else {\n rowTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableRow', this.defaultRowTemplate)\n : lodash_1.default.get(this.component, 'templates.row', this.defaultRowTemplate);\n }\n return rowTemplate;\n }\n get headerTemplate() {\n let headerTemplate;\n if (utils_1.Evaluator.noeval) {\n headerTemplate = this.displayAsTable ?\n components_1.editgrid.tableHeader\n : components_1.editgrid.header;\n }\n else {\n headerTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableHeader', this.defaultHeaderTemplate)\n : lodash_1.default.get(this.component, 'templates.header', this.defaultHeaderTemplate);\n }\n return headerTemplate;\n }\n /**\n * @returns {boolean} - Returns true if the component has nested components which don't trigger changes on the root level\n */\n get hasScopedChildren() {\n return !this.inlineEditMode;\n }\n get defaultSchema() {\n return EditGridComponent.schema();\n }\n get emptyValue() {\n return [];\n }\n get editgridKey() {\n return `editgrid-${this.key}`;\n }\n get rowRef() {\n return `${this.editgridKey}-row`;\n }\n get rowElements() {\n return this.refs[this.rowRef];\n }\n get rowRefs() {\n return this.refs[`editgrid-${this.component.key}-row`];\n }\n get addRowRef() {\n return `${this.editgridKey}-addRow`;\n }\n get addRowElements() {\n return this.refs[this.addRowRef];\n }\n get saveRowRef() {\n return `${this.editgridKey}-saveRow`;\n }\n get saveRowElements() {\n return this.refs[this.saveRowRef];\n }\n get cancelRowRef() {\n return `${this.editgridKey}-cancelRow`;\n }\n get cancelRowElements() {\n return this.refs[this.cancelRowRef];\n }\n get inlineEditMode() {\n return this.component.inlineEdit;\n }\n get saveEditMode() {\n return !this.inlineEditMode;\n }\n get minLength() {\n return this.builderMode ? 0 : lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n get data() {\n return this._data;\n }\n get dataValue() {\n return super.dataValue || [];\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get displayAsTable() {\n return this.component.displayAsTable;\n }\n set data(value) {\n this._data = value;\n const data = this.dataValue;\n (this.editRows || []).forEach((row, index) => {\n if (!data[index] && row.state !== EditRowState.New) {\n data[index] = {};\n }\n const rowData = data[index] || {};\n row.data = rowData;\n row.components.forEach((component) => {\n component.data = rowData;\n });\n });\n }\n get iteratableRows() {\n return this.editRows;\n }\n get defaultValue() {\n const value = super.defaultValue;\n const defaultValue = Array.isArray(value) ? value : [];\n lodash_1.default.times(this.minLength - defaultValue.length, () => defaultValue.push({}));\n return defaultValue;\n }\n constructor(...args) {\n super(...args);\n this.type = 'editgrid';\n }\n hasRemoveButtons() {\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n init() {\n if (this.builderMode) {\n this.editRows = [];\n return super.init();\n }\n this.components = this.components || [];\n const dataValue = this.dataValue;\n const openWhenEmpty = !dataValue.length && this.component.openWhenEmpty;\n if (openWhenEmpty) {\n const dataObj = {};\n this.editRows = [];\n this.createRow(dataObj, 0);\n }\n else {\n this.editRows = dataValue.map((row, rowIndex) => ({\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n error: null,\n rowIndex,\n }));\n }\n this.prevHasAddButton = this.hasAddButton();\n this.checkData();\n this.setVariableTypeComponents();\n if (this.variableTypeComponentsIndexes.length) {\n lodash_1.default.each(this.editRows || [], (editRow, rowIndex) => this.checkRowVariableTypeComponents(editRow, rowIndex));\n }\n }\n checkRowVariableTypeComponents(editRow, rowIndex) {\n const rowComponents = editRow.components;\n if (lodash_1.default.some(this.variableTypeComponentsIndexes, (compIndex) => {\n const variableTypeComp = rowComponents[compIndex];\n return variableTypeComp.type !== variableTypeComp.component.type;\n })) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex, true);\n }\n }\n setVariableTypeComponents() {\n //set components which type is changing within a row (e.g.,by mergeComponentSchema action)\n this.variableTypeComponentsIndexes = [];\n lodash_1.default.each(this.component.components, (comp, index) => {\n if (comp.typeChangeEnabled) {\n this.variableTypeComponentsIndexes.push(index);\n }\n });\n }\n isOpen(editRow) {\n return [EditRowState.New, EditRowState.Editing, EditRowState.Viewing].includes(editRow.state);\n }\n isComponentVisibleInSomeRow(component) {\n const rows = this.editRows;\n const savedStates = [EditRowState.Saved, EditRowState.Editing, EditRowState.Draft];\n const savedRows = rows.filter(row => lodash_1.default.includes(savedStates, row.state));\n this.visibleInHeader = this.visibleInHeader || [];\n const changeVisibleInHeader = (component, isVisible) => {\n if (!isVisible) {\n lodash_1.default.remove(this.visibleInHeader, (key) => key === component.key);\n }\n if (isVisible && !lodash_1.default.includes(this.visibleInHeader, component.key)) {\n this.visibleInHeader.push(component.key);\n }\n };\n if (lodash_1.default.isEmpty(rows)) {\n const rowComponents = this.createRowComponents({}, 0);\n let checkComponent;\n (0, utils_1.eachComponent)(rowComponents, (comp) => {\n if (comp.component.key === component.key) {\n checkComponent = comp;\n }\n comp.checkConditions();\n });\n const isVisible = checkComponent ? checkComponent.visible : true;\n [...this.components].forEach((comp) => this.removeComponent(comp, this.components));\n changeVisibleInHeader(component, isVisible);\n return isVisible;\n }\n const isOpenRowWhenEmpty = lodash_1.default.get(this.component, 'openWhenEmpty') && rows.length === 1 && rows[0].state === EditRowState.New;\n if (!lodash_1.default.isEmpty(rows) && lodash_1.default.isEmpty(savedRows) && !isOpenRowWhenEmpty) {\n return lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return lodash_1.default.some(isOpenRowWhenEmpty ? rows : savedRows, (row, index) => {\n const editingRow = row.state === EditRowState.Editing;\n let isVisible;\n if (!editingRow) {\n const flattenedComponents = this.flattenComponents(index);\n const instance = flattenedComponents[component.key];\n isVisible = instance ? instance.visible : true;\n changeVisibleInHeader(component, isVisible);\n }\n else {\n isVisible = lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return isVisible;\n });\n }\n render(children) {\n if (this.builderMode) {\n return super.render();\n }\n const dataValue = this.dataValue;\n const headerTemplate = this.headerTemplate;\n const t = this.t.bind(this);\n const templateName = this.displayAsTable ? 'editgridTable' : 'editgrid';\n return super.render(children || this.renderTemplate(templateName, {\n ref: {\n row: this.rowRef,\n addRow: this.addRowRef,\n saveRow: this.saveRowRef,\n cancelRow: this.cancelRowRef,\n },\n header: this.renderString(headerTemplate, {\n displayValue: (component) => this.displayComponentValue(component, true),\n components: this.component.components,\n value: dataValue,\n t\n }),\n footer: this.renderString(lodash_1.default.get(this.component, 'templates.footer'), {\n components: this.component.components,\n value: dataValue,\n t\n }),\n rows: this.editRows.map(this.renderRow.bind(this)),\n openRows: this.editRows.map((row) => this.isOpen(row)),\n errors: this.editRows.map((row) => row.error),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons: this.hasRemoveButtons(),\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n const templateName = this.displayAsTable && this.prevHasAddButton ? 'tableComponents' : 'components';\n return this.renderTemplate(templateName, {\n children,\n components,\n });\n }\n attach(element) {\n if (this.builderMode) {\n return super.attach(element);\n }\n this.loadRefs(element, {\n [this.addRowRef]: 'multiple',\n [this.saveRowRef]: 'multiple',\n [this.cancelRowRef]: 'multiple',\n [this.rowRef]: 'multiple',\n });\n this.addRowElements.forEach((addButton) => {\n this.addEventListener(addButton, 'click', () => this.addRow());\n });\n let openRowCount = 0;\n this.rowElements.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow === null || editRow === void 0 ? void 0 : editRow.isRowSelected) {\n row.classList.add('selected');\n }\n if (this.isOpen(editRow)) {\n this.attachComponents(row, editRow.components);\n this.addEventListener(this.saveRowElements[openRowCount], 'click', () => this.saveRow(rowIndex, true));\n this.addEventListener(this.cancelRowElements[openRowCount], 'click', () => this.cancelRow(rowIndex));\n openRowCount++;\n }\n else {\n // Attach edit and remove button events.\n [\n {\n className: 'removeRow',\n event: 'click',\n action: () => this.removeRow(rowIndex, true),\n },\n {\n className: 'editRow',\n event: 'click',\n action: () => {\n this.editRow(rowIndex).then(() => {\n var _a;\n if (this.component.rowDrafts) {\n const errors = this.validateRow(editRow, false);\n const shouldShowRowErrorsAlert = this.component.modal && errors.length && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted);\n if (shouldShowRowErrorsAlert) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n }\n });\n },\n },\n {\n className: 'row',\n event: 'click',\n action: () => {\n row.classList.toggle('selected');\n let eventName = 'editGridSelectRow';\n if (Array.from(row.classList).includes('selected')) {\n editRow.isRowSelected = true;\n }\n else {\n delete editRow.isRowSelected;\n eventName = 'editGridUnSelectRow';\n }\n this.emit(eventName, {\n component: this.component,\n data: this.dataValue[rowIndex]\n });\n },\n }\n ].forEach(({ className, event, action, }) => {\n const elements = row.getElementsByClassName(className);\n Array.prototype.forEach.call(elements, (element) => {\n if (this.options.pdf && lodash_1.default.intersection(element.classList, ['editRow', 'removeRow']).length) {\n element.style.display = 'none';\n }\n else {\n this.addEventListener(element, event, action);\n }\n });\n });\n }\n });\n // Add open class to the element if any edit grid row is open\n if (openRowCount) {\n this.addClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n else {\n this.removeClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n return super.attach(element);\n }\n flattenRowDataValue(dataValue) {\n const flattened = {};\n Object.keys(dataValue).forEach((key) => {\n if (lodash_1.default.isObject(dataValue[key]) && !lodash_1.default.isNil(dataValue[key])) {\n Object.assign(flattened, this.flattenRowDataValue(dataValue[key]));\n }\n else {\n flattened[key] = dataValue[key];\n }\n });\n return flattened;\n }\n isComponentVisibleInRow(component, flattenedComponents) {\n const instance = flattenedComponents[component.key];\n return instance ? instance.visible : true;\n }\n displayComponentValue(component, header) {\n return !!((!component.hasOwnProperty('tableView') || component.tableView)\n && header ? this.isComponentVisibleInSomeRow(component) : lodash_1.default.includes(this.visibleInHeader, component.key));\n }\n renderRow(row, rowIndex) {\n const dataValue = this.dataValue;\n if (this.isOpen(row)) {\n return this.renderComponents(row.components);\n }\n else {\n const flattenedComponents = this.flattenComponents(rowIndex);\n const rowTemplate = this.rowTemplate;\n return this.renderString(rowTemplate, {\n row: dataValue[rowIndex] || {},\n data: this.data,\n rowIndex,\n components: this.component.components,\n flattenedComponents,\n displayValue: (component) => this.displayComponentValue(component),\n isVisibleInRow: (component) => this.isComponentVisibleInRow(component, flattenedComponents),\n getView: (component, data) => {\n var _a, _b;\n const instance = flattenedComponents[component.key];\n const view = instance ? instance.getView(data || instance.dataValue) : '';\n // If there is an html tag in view, don't allow it to be injected in template\n const htmlTagRegExp = new RegExp('<(.*?)>');\n return typeof view === 'string' && view.length && !((_a = instance.component) === null || _a === void 0 ? void 0 : _a.template) && htmlTagRegExp.test(view) && ((_b = instance.component) === null || _b === void 0 ? void 0 : _b.inputFormat) !== 'html'\n ? `<input type=\"text\" value=\"${view.replace(/\"/g, '"')}\" readonly/>`\n : view;\n },\n state: this.editRows[rowIndex].state,\n t: this.t.bind(this)\n });\n }\n }\n eachComponent(fn, rowIndex) {\n lodash_1.default.each(this.getComponents(rowIndex), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n var _a;\n const rowData = this.dataValue[component.rowIndex];\n const editRowData = (_a = this.editRows[component.rowIndex]) === null || _a === void 0 ? void 0 : _a.data;\n component.data = rowData || editRowData;\n });\n }\n flattenComponents(rowIndex) {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n }, rowIndex);\n return result;\n }\n getComponents(rowIndex) {\n var _a;\n // Ensure editrows is set.\n this.editRows = this.editRows || [];\n return this.builderMode\n ? super.getComponents()\n : lodash_1.default.isNumber(rowIndex)\n ? (((_a = this.editRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.components) || [])\n : this.editRows.reduce((result, row) => result.concat(row.components || []), []);\n }\n destroy(all = false) {\n this.calculatedValue = undefined;\n super.destroy(all);\n }\n destroyComponents(all = false, rowIndex = 0) {\n if (this.builderMode) {\n return super.destroyComponents(all);\n }\n const components = this.getComponents(rowIndex).slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n }\n createRow(dataObj, rowIndex) {\n const editRow = {\n components: this.createRowComponents(dataObj, rowIndex),\n data: dataObj,\n state: EditRowState.New,\n backup: null,\n error: null,\n rowIndex,\n };\n this.editRows.push(editRow);\n if (this.inlineEditMode) {\n this.dataValue.push(dataObj);\n }\n return editRow;\n }\n addRow() {\n if (this.options.readOnly) {\n return;\n }\n const dataObj = {};\n const rowIndex = this.editRows.length;\n const editRow = this.createRow(dataObj, rowIndex);\n if (editRow.state === EditRowState.New) {\n this.emptyRow = (0, utils_1.fastCloneDeep)(editRow.data);\n }\n if (this.inlineEditMode) {\n this.triggerChange();\n }\n this.emit('editGridAddRow', {\n component: this.component,\n row: editRow,\n });\n this.processRow('checkData', null, {}, editRow.data, editRow.components);\n if (this.component.modal) {\n this.addRowModal(rowIndex);\n }\n else {\n this.redraw();\n }\n return editRow;\n }\n addRowModal(rowIndex) {\n const modalContent = this.ce('div');\n const editRow = this.editRows[rowIndex];\n editRow.willBeSaved = false;\n const { components } = editRow;\n modalContent.innerHTML = this.renderComponents(components);\n const dialog = this.component.modal ? this.createModal(modalContent, {}, () => this.showDialog(rowIndex)) : undefined;\n dialog.classList.add(`editgrid-row-modal-${this.id}`);\n editRow.dialog = dialog;\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n this.alert = new Alert_1.default(dialog.refs.dialogContents, this);\n this.addEventListener(dialog, 'close', () => {\n if (!editRow.willBeSaved) {\n if (this.editRows[rowIndex] && this.editRows[rowIndex].state !== EditRowState.New) {\n this.editRows[rowIndex].components.forEach((comp) => {\n comp.setPristine(true);\n });\n }\n this.cancelRow(rowIndex);\n }\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n // Remove references to dialog elements to prevent possible in some cases memory leaks\n delete editRow.confirmationDialog;\n delete editRow.dialog;\n });\n dialog.refs.dialogContents.appendChild(this.ce('button', {\n class: 'btn btn-primary',\n onClick: () => {\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!errors.length || this.component.rowDrafts) {\n editRow.willBeSaved = true;\n dialog.close();\n this.saveRow(rowIndex, true);\n }\n else {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n },\n }, this.component.saveRow || 'Save'));\n return this.attachComponents(modalContent, components);\n }\n showDialog(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow.state === EditRowState.New ? lodash_1.default.isEqual(this.emptyRow, editRow.data) : lodash_1.default.isEqual(editRow.backup, editRow.data)) {\n return Promise.resolve();\n }\n const wrapper = this.ce('div', { ref: 'confirmationDialog' });\n const dialogContent = this.component.dialogTemplate || this.defaultDialogTemplate;\n wrapper.innerHTML = dialogContent;\n wrapper.refs = {};\n this.loadRefs.call(wrapper, wrapper, {\n dialogHeader: 'single',\n dialogCancelButton: 'single',\n dialogYesButton: 'single',\n });\n const dialog = this.createModal(wrapper);\n dialog.classList.add(`editgrid-row-modal-confirmation-${this.id}`);\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n let dialogResult;\n const promise = new Promise((resolve, reject) => {\n dialogResult = { resolve, reject };\n });\n this.addEventListener(wrapper.refs.dialogYesButton, 'click', (event) => {\n close(event);\n dialogResult.resolve();\n });\n this.addEventListener(wrapper.refs.dialogCancelButton, 'click', (event) => {\n close(event);\n dialogResult.reject();\n });\n editRow.confirmationDialog = dialog;\n return promise;\n }\n editRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n const isAlreadyEditing = editRow.state === EditRowState.Editing || editRow.state === EditRowState.New;\n if (!editRow || isAlreadyEditing) {\n return Promise.resolve();\n }\n editRow.prevState = editRow.state;\n editRow.state = this.options.readOnly ? EditRowState.Viewing : EditRowState.Editing;\n if (this.lazyLoad && (editRow.components.length === 0)) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex);\n }\n const dataSnapshot = (0, utils_1.fastCloneDeep)(editRow.data);\n if (this.inlineEditMode) {\n editRow.backup = dataSnapshot;\n }\n else {\n editRow.backup = (0, utils_1.fastCloneDeep)(editRow.data);\n editRow.data = dataSnapshot;\n this.restoreRowContext(editRow);\n }\n if (this.component.modal) {\n return this.addRowModal(rowIndex);\n }\n return this.redraw();\n }\n clearErrors(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow && Array.isArray(editRow.components)) {\n editRow.components.forEach((comp) => {\n comp.setPristine(true);\n comp.setCustomValidity('');\n });\n }\n }\n cancelRow(rowIndex) {\n if (this.options.readOnly) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n switch (editRow.state) {\n case EditRowState.New: {\n editRow.state = EditRowState.Removed;\n this.clearErrors(rowIndex);\n this.destroyComponents(false, rowIndex);\n if (this.inlineEditMode) {\n this.splice(rowIndex);\n }\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n break;\n }\n case EditRowState.Editing: {\n editRow.state = editRow.prevState;\n if (this.inlineEditMode) {\n this.dataValue[rowIndex] = editRow.backup;\n }\n editRow.data = editRow.backup;\n editRow.backup = null;\n this.restoreRowContext(editRow);\n this.clearErrors(rowIndex);\n break;\n }\n }\n this.emit('editGridCancelRow', {\n instance: this,\n component: this.component,\n editRow,\n });\n this.checkValidity(null, true);\n this.redraw();\n if (this.component.rowDrafts) {\n this.checkValidity(this.data, false);\n }\n }\n saveRow(rowIndex, modified) {\n var _a, _b;\n const editRow = this.editRows[rowIndex];\n if (this.options.readOnly) {\n return;\n }\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!this.component.rowDrafts) {\n if (errors.length) {\n return false;\n }\n }\n if (this.saveEditMode) {\n const dataValue = this.dataValue;\n if ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.component.typeChangeEnabled) {\n this.root.focusedComponent = null;\n }\n switch (editRow.state) {\n case EditRowState.New: {\n const newIndex = dataValue.length;\n dataValue.push(editRow.data);\n editRow.components.forEach(component => component.rowIndex = newIndex);\n if (rowIndex !== newIndex) {\n this.editRows.splice(rowIndex, 1);\n this.editRows.splice(newIndex, 0, editRow);\n }\n break;\n }\n case EditRowState.Editing: {\n dataValue[rowIndex] = editRow.data;\n break;\n }\n }\n }\n editRow.state = this.component.rowDrafts && errors.length ? EditRowState.Draft : EditRowState.Saved;\n editRow.backup = null;\n this.updateValue();\n this.emit('editGridSaveRow', {\n component: this.component,\n row: editRow.data,\n instance: this\n });\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n if (this.component.rowDrafts) {\n editRow.components.forEach(comp => comp.setPristine(this.pristine));\n }\n this.checkValidity(null, true);\n this.redraw();\n if (editRow.alerts) {\n editRow.alerts = false;\n }\n return true;\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const relativePath = this.getRelativePath(component.path);\n const arrayPath = (0, utils_1.getArrayFromComponentPath)(relativePath);\n const rowIndex = arrayPath[0];\n let rowToEditIndex = arrayPath[0];\n this.editRows.forEach((row, indexInArray) => {\n if (row.rowIndex === rowIndex) {\n rowToEditIndex = indexInArray;\n }\n });\n if (lodash_1.default.isNumber(rowToEditIndex)) {\n this.editRow(rowToEditIndex);\n }\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n });\n }\n updateRowsComponents(rowIndex) {\n this.editRows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(row.components, rowIndex + index);\n });\n }\n baseRemoveRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n editRow.state = EditRowState.Removed;\n this.destroyComponents(false, rowIndex);\n return editRow;\n }\n removeRow(rowIndex, modified) {\n if (this.options.readOnly) {\n return;\n }\n this.clearErrors(rowIndex);\n this.baseRemoveRow(rowIndex);\n this.splice(rowIndex);\n this.emit('editGridDeleteRow', {\n index: rowIndex\n });\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n this.updateRowsComponents(rowIndex);\n this.updateValue();\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n this.checkValidity(null, true);\n this.checkData();\n this.redraw();\n }\n createRowComponents(row, rowIndex, recreatePartially) {\n // Iterate through existing components and destroy the ones with the same rowIndex.\n if (this.components) {\n for (let i = 0; i < this.components.length; i++) {\n if (this.components[i].rowIndex === rowIndex) {\n this.components[i].destroy();\n this.components.splice(i, 1);\n }\n }\n }\n const currentRowComponents = lodash_1.default.get(this.editRows, `[${rowIndex}].components`, null);\n return this.component.components.map((col, colIndex) => {\n var _a;\n if (recreatePartially && currentRowComponents && this.variableTypeComponentsIndexes.length) {\n const currentComp = currentRowComponents[colIndex];\n const shouldRecreate = lodash_1.default.includes(this.variableTypeComponentsIndexes, colIndex) && (currentComp === null || currentComp === void 0 ? void 0 : currentComp.type) !== ((_a = currentComp === null || currentComp === void 0 ? void 0 : currentComp.component) === null || _a === void 0 ? void 0 : _a.type);\n if (!shouldRecreate) {\n return currentComp;\n }\n col = currentComp.component;\n }\n const column = lodash_1.default.clone(col);\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n options.onChange = (flags = {}, changed, modified) => {\n var _a, _b;\n if (((_a = changed.instance.root) === null || _a === void 0 ? void 0 : _a.id) && (((_b = this.root) === null || _b === void 0 ? void 0 : _b.id) !== changed.instance.root.id)) {\n changed.instance.root.triggerChange(flags, changed, modified);\n }\n else if (!this.component.modal) {\n this.triggerRootChange(flags, changed, modified);\n }\n if (this.inlineEditMode) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), editRow.data, editRow.components);\n this.validateRow(editRow, false);\n }\n if (this.variableTypeComponentsIndexes.length) {\n this.checkRowVariableTypeComponents(editRow, rowIndex);\n this.redraw();\n }\n };\n const comp = this.createComponent(lodash_1.default.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);\n comp.rowIndex = rowIndex;\n comp.inEditGrid = true;\n return comp;\n });\n }\n hasOpenRows() {\n return this.editRows.some(row => this.isOpen(row));\n }\n getAttachedData(data = null) {\n const ourData = (0, utils_1.fastCloneDeep)(data || this._data || this.rootValue);\n lodash_1.default.set(ourData, this.key, this.editRows.map((row) => row.data));\n return ourData;\n }\n shouldValidateDraft(editRow) {\n var _a, _b;\n // Draft rows should be validated only when there was an attempt to submit a form\n return (editRow.state === EditRowState.Draft &&\n !this.pristine &&\n !((_a = this.root) === null || _a === void 0 ? void 0 : _a.pristine) &&\n !this.hasOpenRows()) ||\n ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted);\n }\n shouldValidateRow(editRow, dirty) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck) {\n var _a;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty)) {\n const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;\n const rootValue = (0, utils_1.fastCloneDeep)(this.rootValue);\n const editGridValue = lodash_1.default.get(rootValue, this.path, []);\n editGridValue[editRow.rowIndex] = editRow.data;\n lodash_1.default.set(rootValue, this.path, editGridValue);\n const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });\n editRow.errors = (0, process_1.processSync)({\n components: (0, utils_1.fastCloneDeep)(this.component.components).map((component) => {\n component.parentPath = `${this.path}[${editRow.rowIndex}]`;\n return component;\n }),\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n }\n // TODO: this is essentially running its own custom validation and should be moved into a validation rule\n if (this.component.validate && this.component.validate.row) {\n const valid = this.evaluate(this.component.validate.row, {\n valid: (editRow.length === 0),\n row: editRow.data\n }, 'valid', true);\n if (valid.toString() !== 'true') {\n editRow.errors.push({\n type: 'error',\n rowError: true,\n message: valid.toString()\n });\n }\n if (valid === null) {\n editRow.errors.push({\n type: 'error',\n message: `Invalid row validation for ${this.key}`\n });\n }\n }\n if (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted)) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n return editRow.errors;\n }\n showRowErrorAlerts(editRow, errors) {\n if (editRow.alerts) {\n if (this.alert) {\n if (errors.length) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n else {\n this.alert.clear();\n this.alert = null;\n }\n }\n }\n }\n /**\n * @returns {boolean} - Return that this component processes its own validation.\n */\n get processOwnValidation() {\n return true;\n }\n checkComponentValidity(data, dirty, row, options = {}, errors = []) {\n var _a, _b;\n const { silentCheck } = options;\n const superValid = super.checkComponentValidity(data, dirty, row, options, errors);\n // If super tells us that component invalid and there is no need to update alerts, just return false\n if (!superValid && (!this.alert && !this.hasOpenRows())) {\n return false;\n }\n let rowsEditing = false;\n const allRowErrors = [];\n this.editRows.forEach((editRow, index) => {\n // Trigger all errors on the row.\n const rowErrors = this.validateRow(editRow, dirty, silentCheck);\n errors.push(...rowErrors);\n allRowErrors.push(...rowErrors);\n if (this.rowRefs) {\n const rowContainer = this.rowRefs[index];\n if (rowContainer) {\n const errorContainer = rowContainer.querySelector('.editgrid-row-error');\n if (rowErrors.length && errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n const rowError = rowErrors.find(error => error.rowError);\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(rowError ? rowError.message : this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n }\n // If this is a dirty check, and any rows are still editing, we need to throw validation error.\n rowsEditing |= (dirty && this.isOpen(editRow));\n });\n if (allRowErrors.length) {\n if (!silentCheck && (dirty || this.dirty) && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.setCustomValidity(this.t(this.errorMessage('invalidRowsError')), dirty);\n this.removeClass(this.element, 'has-error');\n }\n return false;\n }\n else if (rowsEditing && this.saveEditMode && !this.component.openWhenEmpty) {\n this._errors = this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);\n errors.push(...this._errors);\n return false;\n }\n const message = this.invalid || this.invalidMessage(data, dirty, false, row);\n if (allRowErrors.length && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted) && !message) {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n this.root.showErrors([message]);\n }\n else {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n }\n return superValid;\n }\n setRowInvalid(ref, index) {\n const editRow = this.editRows[index];\n const errorContainer = ref.querySelector('.editgrid-row-error');\n if (errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n changeState(changed, flags) {\n if (this.visible && (changed || (flags.resetValue && this.component.modalEdit))) {\n this.rebuild();\n }\n else {\n this.redraw();\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n value = this.defaultValue;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n return false;\n }\n }\n const changed = this.hasChanged(value, this.dataValue);\n if (this.parent && !this.options.server) {\n this.parent.checkComponentConditions();\n }\n this.dataValue = value;\n // Refresh editRow data when data changes.\n this.dataValue.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n editRow.data = row;\n this.restoreRowContext(editRow, flags);\n editRow.state = EditRowState.Saved;\n editRow.backup = null;\n editRow.errors = [];\n }\n else {\n this.editRows[rowIndex] = {\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n errors: [],\n };\n }\n });\n let { length: dataLength } = this.dataValue;\n // If the last row is a new row, then do not remove it.\n if (this.editRows[dataLength] && (this.editRows[dataLength].state === EditRowState.New)) {\n dataLength = (dataLength + 1);\n }\n this.editRows.slice(dataLength).forEach((editRow, index) => this.baseRemoveRow(dataLength + index));\n this.editRows = this.editRows.slice(0, dataLength);\n this.openWhenEmpty();\n this.updateOnChange(flags, changed);\n // do not call checkData with server option, it is called when change is triggered in updateOnChange\n if (!this.options.server) {\n this.checkData();\n }\n this.changeState(changed, flags);\n return changed;\n }\n openWhenEmpty() {\n const shouldBeOpened = !this.dataValue.length && this.component.openWhenEmpty;\n const hasNoRows = !this.editRows.length;\n if (hasNoRows && shouldBeOpened && !this.builderMode) {\n const dataObj = {};\n this.createRow(dataObj, 0);\n }\n }\n restoreRowContext(editRow, flags = {}) {\n editRow.components.forEach((component) => {\n component.data = editRow.data;\n this.setNestedValue(component, editRow.data, flags);\n });\n }\n emptyRows() {\n this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));\n this.editRows = [];\n }\n resetValue() {\n super.resetValue();\n this.emptyRows();\n }\n}\nexports[\"default\"] = EditGridComponent;\nEditGridComponent.prototype.hasChanged = Component_1.default.prototype.hasChanged;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/editgrid/EditGrid.js?");
|
6296
|
+
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 process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst components_1 = __webpack_require__(/*! @formio/bootstrap/components */ \"./node_modules/@formio/bootstrap/lib/cjs/templates/components/index.js\");\nconst NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst Alert_1 = __importDefault(__webpack_require__(/*! ../alert/Alert */ \"./lib/cjs/components/alert/Alert.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst EditRowState = {\n New: 'new',\n Editing: 'editing',\n Saved: 'saved',\n Viewing: 'viewing',\n Removed: 'removed',\n Draft: 'draft',\n};\nclass EditGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n type: 'editgrid',\n label: 'Edit Grid',\n key: 'editGrid',\n clearOnHide: true,\n input: true,\n tree: true,\n removeRow: 'Cancel',\n defaultOpen: false,\n openWhenEmpty: false,\n modal: false,\n components: [],\n inlineEdit: false,\n templates: {\n header: EditGridComponent.defaultHeaderTemplate,\n row: EditGridComponent.defaultRowTemplate,\n tableHeader: EditGridComponent.defaultTableHeaderTemplate,\n tableRow: EditGridComponent.defaultTableRowTemplate,\n footer: '',\n },\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Edit Grid',\n icon: 'tasks',\n group: 'data',\n documentation: '/userguide/form-building/data-components#edit-grid',\n showPreview: false,\n weight: 30,\n schema: EditGridComponent.schema(),\n };\n }\n static get defaultHeaderTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">{{ t(component.label) }}</div>\n {% } %}\n {% }) %}\n </div>`;\n }\n static get defaultTableHeaderTemplate() {\n return `\n <tr>\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">{{ component.label }}</td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">Actions</td>\n {% } %}\n </tr>\n `;\n }\n static get defaultRowTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">\n {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}\n </div>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <div class=\"col-sm-2\">\n <div class=\"btn-group pull-right\">\n <button class=\"btn btn-default btn-light btn-sm editRow\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </div>\n {% } %}\n </div>`;\n }\n static get defaultTableRowTemplate() {\n return `\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">\n {{ getView(component, row[component.key]) }}\n </td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">\n <div class=\"btn-group\">\n <button class=\"btn btn-default btn-light btn-sm editRow\" aria-label=\"{{ t('Edit row') }}\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\" aria-label=\"{{ t('Remove row') }}\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </td>\n {% } %}\n `;\n }\n get defaultDialogTemplate() {\n return `\n <h3 ${this._referenceAttributeName}=\"dialogHeader\">${this.t('Do you want to clear data?')}</h3>\n <div style=\"display:flex; justify-content: flex-end;\">\n <button ${this._referenceAttributeName}=\"dialogCancelButton\" class=\"btn btn-secondary\" aria-label=\"${this.t('Cancel')}\">${this.t('Cancel')}</button>\n <button ${this._referenceAttributeName}=\"dialogYesButton\" class=\"btn btn-danger\" aria-label=\"${this.t('Yes, delete it')}\">${this.t('Yes, delete it')}</button>\n </div>\n `;\n }\n get defaultRowTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableRowTemplate\n : EditGridComponent.defaultRowTemplate;\n }\n get defaultHeaderTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableHeaderTemplate\n : EditGridComponent.defaultHeaderTemplate;\n }\n get rowTemplate() {\n let rowTemplate;\n if (utils_1.Evaluator.noeval) {\n rowTemplate = this.displayAsTable ?\n components_1.editgrid.tableRow\n : components_1.editgrid.row;\n }\n else {\n rowTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableRow', this.defaultRowTemplate)\n : lodash_1.default.get(this.component, 'templates.row', this.defaultRowTemplate);\n }\n return rowTemplate;\n }\n get headerTemplate() {\n let headerTemplate;\n if (utils_1.Evaluator.noeval) {\n headerTemplate = this.displayAsTable ?\n components_1.editgrid.tableHeader\n : components_1.editgrid.header;\n }\n else {\n headerTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableHeader', this.defaultHeaderTemplate)\n : lodash_1.default.get(this.component, 'templates.header', this.defaultHeaderTemplate);\n }\n return headerTemplate;\n }\n /**\n * @returns {boolean} - Returns true if the component has nested components which don't trigger changes on the root level\n */\n get hasScopedChildren() {\n return !this.inlineEditMode;\n }\n get defaultSchema() {\n return EditGridComponent.schema();\n }\n get emptyValue() {\n return [];\n }\n get editgridKey() {\n return `editgrid-${this.key}`;\n }\n get rowRef() {\n return `${this.editgridKey}-row`;\n }\n get rowElements() {\n return this.refs[this.rowRef];\n }\n get rowRefs() {\n return this.refs[`editgrid-${this.component.key}-row`];\n }\n get addRowRef() {\n return `${this.editgridKey}-addRow`;\n }\n get addRowElements() {\n return this.refs[this.addRowRef];\n }\n get saveRowRef() {\n return `${this.editgridKey}-saveRow`;\n }\n get saveRowElements() {\n return this.refs[this.saveRowRef];\n }\n get cancelRowRef() {\n return `${this.editgridKey}-cancelRow`;\n }\n get cancelRowElements() {\n return this.refs[this.cancelRowRef];\n }\n get inlineEditMode() {\n return this.component.inlineEdit;\n }\n get saveEditMode() {\n return !this.inlineEditMode;\n }\n get minLength() {\n return this.builderMode ? 0 : lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n get data() {\n return this._data;\n }\n get dataValue() {\n return super.dataValue || [];\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get displayAsTable() {\n return this.component.displayAsTable;\n }\n set data(value) {\n this._data = value;\n const data = this.dataValue;\n (this.editRows || []).forEach((row, index) => {\n if (!data[index] && row.state !== EditRowState.New) {\n data[index] = {};\n }\n const rowData = data[index] || {};\n row.data = rowData;\n row.components.forEach((component) => {\n component.data = rowData;\n });\n });\n }\n get iteratableRows() {\n return this.editRows;\n }\n get defaultValue() {\n const value = super.defaultValue;\n const defaultValue = Array.isArray(value) ? value : [];\n lodash_1.default.times(this.minLength - defaultValue.length, () => defaultValue.push({}));\n return defaultValue;\n }\n constructor(...args) {\n super(...args);\n this.type = 'editgrid';\n }\n hasRemoveButtons() {\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n init() {\n if (this.builderMode) {\n this.editRows = [];\n return super.init();\n }\n this.components = this.components || [];\n const dataValue = this.dataValue;\n const openWhenEmpty = !dataValue.length && this.component.openWhenEmpty;\n if (openWhenEmpty) {\n const dataObj = {};\n this.editRows = [];\n this.createRow(dataObj, 0);\n }\n else {\n this.editRows = dataValue.map((row, rowIndex) => ({\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n error: null,\n rowIndex,\n }));\n }\n this.prevHasAddButton = this.hasAddButton();\n this.checkData();\n this.setVariableTypeComponents();\n if (this.variableTypeComponentsIndexes.length) {\n lodash_1.default.each(this.editRows || [], (editRow, rowIndex) => this.checkRowVariableTypeComponents(editRow, rowIndex));\n }\n }\n checkRowVariableTypeComponents(editRow, rowIndex) {\n const rowComponents = editRow.components;\n if (lodash_1.default.some(this.variableTypeComponentsIndexes, (compIndex) => {\n const variableTypeComp = rowComponents[compIndex];\n return variableTypeComp.type !== variableTypeComp.component.type;\n })) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex, true);\n }\n }\n setVariableTypeComponents() {\n //set components which type is changing within a row (e.g.,by mergeComponentSchema action)\n this.variableTypeComponentsIndexes = [];\n lodash_1.default.each(this.component.components, (comp, index) => {\n if (comp.typeChangeEnabled) {\n this.variableTypeComponentsIndexes.push(index);\n }\n });\n }\n isOpen(editRow) {\n return [EditRowState.New, EditRowState.Editing, EditRowState.Viewing].includes(editRow.state);\n }\n isComponentVisibleInSomeRow(component) {\n const rows = this.editRows;\n const savedStates = [EditRowState.Saved, EditRowState.Editing, EditRowState.Draft];\n const savedRows = rows.filter(row => lodash_1.default.includes(savedStates, row.state));\n this.visibleInHeader = this.visibleInHeader || [];\n const changeVisibleInHeader = (component, isVisible) => {\n if (!isVisible) {\n lodash_1.default.remove(this.visibleInHeader, (key) => key === component.key);\n }\n if (isVisible && !lodash_1.default.includes(this.visibleInHeader, component.key)) {\n this.visibleInHeader.push(component.key);\n }\n };\n if (lodash_1.default.isEmpty(rows)) {\n const rowComponents = this.createRowComponents({}, 0);\n let checkComponent;\n (0, utils_1.eachComponent)(rowComponents, (comp) => {\n if (comp.component.key === component.key) {\n checkComponent = comp;\n }\n comp.checkConditions();\n });\n const isVisible = checkComponent ? checkComponent.visible : true;\n [...this.components].forEach((comp) => this.removeComponent(comp, this.components));\n changeVisibleInHeader(component, isVisible);\n return isVisible;\n }\n const isOpenRowWhenEmpty = lodash_1.default.get(this.component, 'openWhenEmpty') && rows.length === 1 && rows[0].state === EditRowState.New;\n if (!lodash_1.default.isEmpty(rows) && lodash_1.default.isEmpty(savedRows) && !isOpenRowWhenEmpty) {\n return lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return lodash_1.default.some(isOpenRowWhenEmpty ? rows : savedRows, (row, index) => {\n const editingRow = row.state === EditRowState.Editing;\n let isVisible;\n if (!editingRow) {\n const flattenedComponents = this.flattenComponents(index);\n const instance = flattenedComponents[component.key];\n isVisible = instance ? instance.visible : true;\n changeVisibleInHeader(component, isVisible);\n }\n else {\n isVisible = lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return isVisible;\n });\n }\n render(children) {\n if (this.builderMode) {\n return super.render();\n }\n const dataValue = this.dataValue;\n const headerTemplate = this.headerTemplate;\n const t = this.t.bind(this);\n const templateName = this.displayAsTable ? 'editgridTable' : 'editgrid';\n return super.render(children || this.renderTemplate(templateName, {\n ref: {\n row: this.rowRef,\n addRow: this.addRowRef,\n saveRow: this.saveRowRef,\n cancelRow: this.cancelRowRef,\n },\n header: this.renderString(headerTemplate, {\n displayValue: (component) => this.displayComponentValue(component, true),\n components: this.component.components,\n value: dataValue,\n t\n }),\n footer: this.renderString(lodash_1.default.get(this.component, 'templates.footer'), {\n components: this.component.components,\n value: dataValue,\n t\n }),\n rows: this.editRows.map(this.renderRow.bind(this)),\n openRows: this.editRows.map((row) => this.isOpen(row)),\n errors: this.editRows.map((row) => row.error),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons: this.hasRemoveButtons(),\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n const templateName = this.displayAsTable && this.prevHasAddButton ? 'tableComponents' : 'components';\n return this.renderTemplate(templateName, {\n children,\n components,\n });\n }\n attach(element) {\n if (this.builderMode) {\n return super.attach(element);\n }\n this.loadRefs(element, {\n [this.addRowRef]: 'multiple',\n [this.saveRowRef]: 'multiple',\n [this.cancelRowRef]: 'multiple',\n [this.rowRef]: 'multiple',\n });\n this.addRowElements.forEach((addButton) => {\n this.addEventListener(addButton, 'click', () => this.addRow());\n });\n let openRowCount = 0;\n this.rowElements.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow === null || editRow === void 0 ? void 0 : editRow.isRowSelected) {\n row.classList.add('selected');\n }\n if (this.isOpen(editRow)) {\n this.attachComponents(row, editRow.components);\n this.addEventListener(this.saveRowElements[openRowCount], 'click', () => this.saveRow(rowIndex, true));\n this.addEventListener(this.cancelRowElements[openRowCount], 'click', () => this.cancelRow(rowIndex));\n openRowCount++;\n }\n else {\n // Attach edit and remove button events.\n [\n {\n className: 'removeRow',\n event: 'click',\n action: () => this.removeRow(rowIndex, true),\n },\n {\n className: 'editRow',\n event: 'click',\n action: () => {\n this.editRow(rowIndex).then(() => {\n var _a;\n if (this.component.rowDrafts) {\n const errors = this.validateRow(editRow, false);\n const shouldShowRowErrorsAlert = this.component.modal && errors.length && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted);\n if (shouldShowRowErrorsAlert) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n }\n });\n },\n },\n {\n className: 'row',\n event: 'click',\n action: () => {\n row.classList.toggle('selected');\n let eventName = 'editGridSelectRow';\n if (Array.from(row.classList).includes('selected')) {\n editRow.isRowSelected = true;\n }\n else {\n delete editRow.isRowSelected;\n eventName = 'editGridUnSelectRow';\n }\n this.emit(eventName, {\n component: this.component,\n data: this.dataValue[rowIndex]\n });\n },\n }\n ].forEach(({ className, event, action, }) => {\n const elements = row.getElementsByClassName(className);\n Array.prototype.forEach.call(elements, (element) => {\n if (this.options.pdf && lodash_1.default.intersection(element.classList, ['editRow', 'removeRow']).length) {\n element.style.display = 'none';\n }\n else {\n this.addEventListener(element, event, action);\n }\n });\n });\n }\n });\n // Add open class to the element if any edit grid row is open\n if (openRowCount) {\n this.addClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n else {\n this.removeClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n return super.attach(element);\n }\n flattenRowDataValue(dataValue) {\n const flattened = {};\n Object.keys(dataValue).forEach((key) => {\n if (lodash_1.default.isObject(dataValue[key]) && !lodash_1.default.isNil(dataValue[key])) {\n Object.assign(flattened, this.flattenRowDataValue(dataValue[key]));\n }\n else {\n flattened[key] = dataValue[key];\n }\n });\n return flattened;\n }\n isComponentVisibleInRow(component, flattenedComponents) {\n const instance = flattenedComponents[component.key];\n return instance ? instance.visible : true;\n }\n displayComponentValue(component, header) {\n return !!((!component.hasOwnProperty('tableView') || component.tableView)\n && header ? this.isComponentVisibleInSomeRow(component) : lodash_1.default.includes(this.visibleInHeader, component.key));\n }\n renderRow(row, rowIndex) {\n const dataValue = this.dataValue;\n if (this.isOpen(row)) {\n return this.renderComponents(row.components);\n }\n else {\n const flattenedComponents = this.flattenComponents(rowIndex);\n const rowTemplate = this.rowTemplate;\n return this.renderString(rowTemplate, {\n row: dataValue[rowIndex] || {},\n data: this.data,\n rowIndex,\n components: this.component.components,\n flattenedComponents,\n displayValue: (component) => this.displayComponentValue(component),\n isVisibleInRow: (component) => this.isComponentVisibleInRow(component, flattenedComponents),\n getView: (component, data) => {\n var _a, _b;\n const instance = flattenedComponents[component.key];\n const view = instance ? instance.getView(data || instance.dataValue) : '';\n // If there is an html tag in view, don't allow it to be injected in template\n const htmlTagRegExp = new RegExp('<(.*?)>');\n return typeof view === 'string' && view.length && !((_a = instance.component) === null || _a === void 0 ? void 0 : _a.template) && htmlTagRegExp.test(view) && ((_b = instance.component) === null || _b === void 0 ? void 0 : _b.inputFormat) !== 'html'\n ? `<input type=\"text\" value=\"${view.replace(/\"/g, '"')}\" readonly/>`\n : view;\n },\n state: this.editRows[rowIndex].state,\n t: this.t.bind(this)\n });\n }\n }\n eachComponent(fn, rowIndex) {\n lodash_1.default.each(this.getComponents(rowIndex), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n var _a;\n const rowData = this.dataValue[component.rowIndex];\n const editRowData = (_a = this.editRows[component.rowIndex]) === null || _a === void 0 ? void 0 : _a.data;\n component.data = rowData || editRowData;\n });\n }\n flattenComponents(rowIndex) {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n }, rowIndex);\n return result;\n }\n getComponents(rowIndex) {\n var _a;\n // Ensure editrows is set.\n this.editRows = this.editRows || [];\n return this.builderMode\n ? super.getComponents()\n : lodash_1.default.isNumber(rowIndex)\n ? (((_a = this.editRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.components) || [])\n : this.editRows.reduce((result, row) => result.concat(row.components || []), []);\n }\n destroy(all = false) {\n this.calculatedValue = undefined;\n super.destroy(all);\n }\n destroyComponents(all = false, rowIndex = 0) {\n if (this.builderMode) {\n return super.destroyComponents(all);\n }\n const components = this.getComponents(rowIndex).slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n }\n createRow(dataObj, rowIndex) {\n const editRow = {\n components: this.createRowComponents(dataObj, rowIndex),\n data: dataObj,\n state: EditRowState.New,\n backup: null,\n error: null,\n rowIndex,\n };\n this.editRows.push(editRow);\n if (this.inlineEditMode) {\n this.dataValue.push(dataObj);\n }\n return editRow;\n }\n addRow() {\n if (this.options.readOnly) {\n return;\n }\n const dataObj = {};\n const rowIndex = this.editRows.length;\n const editRow = this.createRow(dataObj, rowIndex);\n if (editRow.state === EditRowState.New) {\n this.emptyRow = (0, utils_1.fastCloneDeep)(editRow.data);\n }\n if (this.inlineEditMode) {\n this.triggerChange();\n }\n this.emit('editGridAddRow', {\n component: this.component,\n row: editRow,\n });\n this.processRow('checkData', null, {}, editRow.data, editRow.components);\n if (this.component.modal) {\n this.addRowModal(rowIndex);\n }\n else {\n this.redraw();\n }\n return editRow;\n }\n addRowModal(rowIndex) {\n const modalContent = this.ce('div');\n const editRow = this.editRows[rowIndex];\n editRow.willBeSaved = false;\n const { components } = editRow;\n modalContent.innerHTML = this.renderComponents(components);\n const dialog = this.component.modal ? this.createModal(modalContent, {}, () => this.showDialog(rowIndex)) : undefined;\n dialog.classList.add(`editgrid-row-modal-${this.id}`);\n editRow.dialog = dialog;\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n this.alert = new Alert_1.default(dialog.refs.dialogContents, this);\n this.addEventListener(dialog, 'close', () => {\n if (!editRow.willBeSaved) {\n if (this.editRows[rowIndex] && this.editRows[rowIndex].state !== EditRowState.New) {\n this.editRows[rowIndex].components.forEach((comp) => {\n comp.setPristine(true);\n });\n }\n this.cancelRow(rowIndex);\n }\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n // Remove references to dialog elements to prevent possible in some cases memory leaks\n delete editRow.confirmationDialog;\n delete editRow.dialog;\n });\n dialog.refs.dialogContents.appendChild(this.ce('button', {\n class: 'btn btn-primary',\n onClick: () => {\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!errors.length || this.component.rowDrafts) {\n editRow.willBeSaved = true;\n dialog.close();\n this.saveRow(rowIndex, true);\n }\n else {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n },\n }, this.component.saveRow || 'Save'));\n return this.attachComponents(modalContent, components);\n }\n showDialog(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow.state === EditRowState.New ? lodash_1.default.isEqual(this.emptyRow, editRow.data) : lodash_1.default.isEqual(editRow.backup, editRow.data)) {\n return Promise.resolve();\n }\n const wrapper = this.ce('div', { ref: 'confirmationDialog' });\n const dialogContent = this.component.dialogTemplate || this.defaultDialogTemplate;\n wrapper.innerHTML = dialogContent;\n wrapper.refs = {};\n this.loadRefs.call(wrapper, wrapper, {\n dialogHeader: 'single',\n dialogCancelButton: 'single',\n dialogYesButton: 'single',\n });\n const dialog = this.createModal(wrapper);\n dialog.classList.add(`editgrid-row-modal-confirmation-${this.id}`);\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n let dialogResult;\n const promise = new Promise((resolve, reject) => {\n dialogResult = { resolve, reject };\n });\n this.addEventListener(wrapper.refs.dialogYesButton, 'click', (event) => {\n close(event);\n dialogResult.resolve();\n });\n this.addEventListener(wrapper.refs.dialogCancelButton, 'click', (event) => {\n close(event);\n dialogResult.reject();\n });\n editRow.confirmationDialog = dialog;\n return promise;\n }\n editRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n const isAlreadyEditing = editRow.state === EditRowState.Editing || editRow.state === EditRowState.New;\n if (!editRow || isAlreadyEditing) {\n return Promise.resolve();\n }\n editRow.prevState = editRow.state;\n editRow.state = this.options.readOnly ? EditRowState.Viewing : EditRowState.Editing;\n if (this.lazyLoad && (editRow.components.length === 0)) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex);\n }\n const dataSnapshot = (0, utils_1.fastCloneDeep)(editRow.data);\n if (this.inlineEditMode) {\n editRow.backup = dataSnapshot;\n }\n else {\n editRow.backup = (0, utils_1.fastCloneDeep)(editRow.data);\n editRow.data = dataSnapshot;\n this.restoreRowContext(editRow);\n }\n if (this.component.modal) {\n return this.addRowModal(rowIndex);\n }\n return this.redraw();\n }\n clearErrors(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow && Array.isArray(editRow.components)) {\n editRow.components.forEach((comp) => {\n comp.setPristine(true);\n comp.setCustomValidity('');\n });\n }\n }\n cancelRow(rowIndex) {\n if (this.options.readOnly) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n switch (editRow.state) {\n case EditRowState.New: {\n editRow.state = EditRowState.Removed;\n this.clearErrors(rowIndex);\n this.destroyComponents(false, rowIndex);\n if (this.inlineEditMode) {\n this.splice(rowIndex);\n }\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n break;\n }\n case EditRowState.Editing: {\n editRow.state = editRow.prevState;\n if (this.inlineEditMode) {\n this.dataValue[rowIndex] = editRow.backup;\n }\n editRow.data = editRow.backup;\n editRow.backup = null;\n this.restoreRowContext(editRow);\n this.clearErrors(rowIndex);\n break;\n }\n }\n this.emit('editGridCancelRow', {\n instance: this,\n component: this.component,\n editRow,\n });\n this.checkValidity(null, true);\n this.redraw();\n if (this.component.rowDrafts) {\n this.checkValidity(this.data, false);\n }\n }\n saveRow(rowIndex, modified) {\n var _a, _b;\n const editRow = this.editRows[rowIndex];\n if (this.options.readOnly) {\n return;\n }\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!this.component.rowDrafts) {\n if (errors.length) {\n return false;\n }\n }\n if (this.saveEditMode) {\n const dataValue = this.dataValue;\n if ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.component.typeChangeEnabled) {\n this.root.focusedComponent = null;\n }\n switch (editRow.state) {\n case EditRowState.New: {\n const newIndex = dataValue.length;\n dataValue.push(editRow.data);\n editRow.components.forEach(component => component.rowIndex = newIndex);\n if (rowIndex !== newIndex) {\n this.editRows.splice(rowIndex, 1);\n this.editRows.splice(newIndex, 0, editRow);\n }\n break;\n }\n case EditRowState.Editing: {\n dataValue[rowIndex] = editRow.data;\n break;\n }\n }\n }\n editRow.state = this.component.rowDrafts && errors.length ? EditRowState.Draft : EditRowState.Saved;\n editRow.backup = null;\n this.updateValue();\n this.emit('editGridSaveRow', {\n component: this.component,\n row: editRow.data,\n instance: this\n });\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n if (this.component.rowDrafts) {\n editRow.components.forEach(comp => comp.setPristine(this.pristine));\n }\n this.checkValidity(null, true);\n this.redraw();\n if (editRow.alerts) {\n editRow.alerts = false;\n }\n return true;\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const relativePath = this.getRelativePath(component.path);\n const arrayPath = (0, utils_1.getArrayFromComponentPath)(relativePath);\n const rowIndex = arrayPath[0];\n let rowToEditIndex = arrayPath[0];\n this.editRows.forEach((row, indexInArray) => {\n if (row.rowIndex === rowIndex) {\n rowToEditIndex = indexInArray;\n }\n });\n if (lodash_1.default.isNumber(rowToEditIndex)) {\n this.editRow(rowToEditIndex);\n }\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n });\n }\n updateRowsComponents(rowIndex) {\n this.editRows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(row.components, rowIndex + index);\n });\n }\n baseRemoveRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n editRow.state = EditRowState.Removed;\n this.destroyComponents(false, rowIndex);\n return editRow;\n }\n removeRow(rowIndex, modified) {\n if (this.options.readOnly) {\n return;\n }\n this.clearErrors(rowIndex);\n this.baseRemoveRow(rowIndex);\n this.removeSubmissionMetadataRow(rowIndex);\n this.splice(rowIndex);\n this.emit('editGridDeleteRow', {\n index: rowIndex\n });\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n this.updateRowsComponents(rowIndex);\n this.updateValue();\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n this.checkValidity(null, true);\n this.checkData();\n this.redraw();\n }\n createRowComponents(row, rowIndex, recreatePartially) {\n // Iterate through existing components and destroy the ones with the same rowIndex.\n if (this.components) {\n for (let i = 0; i < this.components.length; i++) {\n if (this.components[i].rowIndex === rowIndex) {\n this.components[i].destroy();\n this.components.splice(i, 1);\n }\n }\n }\n const currentRowComponents = lodash_1.default.get(this.editRows, `[${rowIndex}].components`, null);\n return this.component.components.map((col, colIndex) => {\n var _a;\n if (recreatePartially && currentRowComponents && this.variableTypeComponentsIndexes.length) {\n const currentComp = currentRowComponents[colIndex];\n const shouldRecreate = lodash_1.default.includes(this.variableTypeComponentsIndexes, colIndex) && (currentComp === null || currentComp === void 0 ? void 0 : currentComp.type) !== ((_a = currentComp === null || currentComp === void 0 ? void 0 : currentComp.component) === null || _a === void 0 ? void 0 : _a.type);\n if (!shouldRecreate) {\n return currentComp;\n }\n col = currentComp.component;\n }\n const column = lodash_1.default.clone(col);\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n options.onChange = (flags = {}, changed, modified) => {\n var _a, _b;\n if (((_a = changed.instance.root) === null || _a === void 0 ? void 0 : _a.id) && (((_b = this.root) === null || _b === void 0 ? void 0 : _b.id) !== changed.instance.root.id)) {\n changed.instance.root.triggerChange(flags, changed, modified);\n }\n else if (!this.component.modal) {\n this.triggerRootChange(flags, changed, modified);\n }\n if (this.inlineEditMode) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), editRow.data, editRow.components);\n this.validateRow(editRow, false);\n }\n if (this.variableTypeComponentsIndexes.length) {\n this.checkRowVariableTypeComponents(editRow, rowIndex);\n this.redraw();\n }\n };\n const comp = this.createComponent(lodash_1.default.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);\n comp.rowIndex = rowIndex;\n comp.inEditGrid = true;\n return comp;\n });\n }\n hasOpenRows() {\n return this.editRows.some(row => this.isOpen(row));\n }\n getAttachedData(data = null) {\n const ourData = (0, utils_1.fastCloneDeep)(data || this._data || this.rootValue);\n lodash_1.default.set(ourData, this.key, this.editRows.map((row) => row.data));\n return ourData;\n }\n shouldValidateDraft(editRow) {\n var _a, _b;\n // Draft rows should be validated only when there was an attempt to submit a form\n return (editRow.state === EditRowState.Draft &&\n !this.pristine &&\n !((_a = this.root) === null || _a === void 0 ? void 0 : _a.pristine) &&\n !this.hasOpenRows()) ||\n ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted);\n }\n shouldValidateRow(editRow, dirty) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck) {\n var _a;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty)) {\n const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;\n const rootValue = (0, utils_1.fastCloneDeep)(this.rootValue);\n const editGridValue = lodash_1.default.get(rootValue, this.path, []);\n editGridValue[editRow.rowIndex] = editRow.data;\n lodash_1.default.set(rootValue, this.path, editGridValue);\n const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });\n editRow.errors = (0, process_1.processSync)({\n components: (0, utils_1.fastCloneDeep)(this.component.components).map((component) => {\n component.parentPath = `${this.path}[${editRow.rowIndex}]`;\n return component;\n }),\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n }\n // TODO: this is essentially running its own custom validation and should be moved into a validation rule\n if (this.component.validate && this.component.validate.row) {\n const valid = this.evaluate(this.component.validate.row, {\n valid: (editRow.length === 0),\n row: editRow.data\n }, 'valid', true);\n if (valid.toString() !== 'true') {\n editRow.errors.push({\n type: 'error',\n rowError: true,\n message: valid.toString()\n });\n }\n if (valid === null) {\n editRow.errors.push({\n type: 'error',\n message: `Invalid row validation for ${this.key}`\n });\n }\n }\n if (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted)) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n return editRow.errors;\n }\n showRowErrorAlerts(editRow, errors) {\n if (editRow.alerts) {\n if (this.alert) {\n if (errors.length) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n else {\n this.alert.clear();\n this.alert = null;\n }\n }\n }\n }\n /**\n * @returns {boolean} - Return that this component processes its own validation.\n */\n get processOwnValidation() {\n return true;\n }\n checkComponentValidity(data, dirty, row, options = {}, errors = []) {\n var _a, _b;\n const { silentCheck } = options;\n const superValid = super.checkComponentValidity(data, dirty, row, options, errors);\n // If super tells us that component invalid and there is no need to update alerts, just return false\n if (!superValid && (!this.alert && !this.hasOpenRows())) {\n return false;\n }\n let rowsEditing = false;\n const allRowErrors = [];\n this.editRows.forEach((editRow, index) => {\n // Trigger all errors on the row.\n const rowErrors = this.validateRow(editRow, dirty, silentCheck);\n errors.push(...rowErrors);\n allRowErrors.push(...rowErrors);\n if (this.rowRefs) {\n const rowContainer = this.rowRefs[index];\n if (rowContainer) {\n const errorContainer = rowContainer.querySelector('.editgrid-row-error');\n if (rowErrors.length && errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n const rowError = rowErrors.find(error => error.rowError);\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(rowError ? rowError.message : this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n }\n // If this is a dirty check, and any rows are still editing, we need to throw validation error.\n rowsEditing |= (dirty && this.isOpen(editRow));\n });\n if (allRowErrors.length) {\n if (!silentCheck && (dirty || this.dirty) && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.setCustomValidity(this.t(this.errorMessage('invalidRowsError')), dirty);\n this.removeClass(this.element, 'has-error');\n }\n return false;\n }\n else if (rowsEditing && this.saveEditMode && !this.component.openWhenEmpty) {\n this._errors = this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);\n errors.push(...this._errors);\n return false;\n }\n const message = this.invalid || this.invalidMessage(data, dirty, false, row);\n if (allRowErrors.length && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted) && !message) {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n this.root.showErrors([message]);\n }\n else {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n }\n return superValid;\n }\n setRowInvalid(ref, index) {\n const editRow = this.editRows[index];\n const errorContainer = ref.querySelector('.editgrid-row-error');\n if (errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n changeState(changed, flags) {\n if (this.visible && (changed || (flags.resetValue && this.component.modalEdit))) {\n this.rebuild();\n }\n else {\n this.redraw();\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n value = this.defaultValue;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n return false;\n }\n }\n const changed = this.hasChanged(value, this.dataValue);\n if (this.parent && !this.options.server) {\n this.parent.checkComponentConditions();\n }\n this.dataValue = value;\n // Refresh editRow data when data changes.\n this.dataValue.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n editRow.data = row;\n this.restoreRowContext(editRow, flags);\n editRow.state = EditRowState.Saved;\n editRow.backup = null;\n editRow.errors = [];\n }\n else {\n this.editRows[rowIndex] = {\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n errors: [],\n };\n }\n });\n let { length: dataLength } = this.dataValue;\n // If the last row is a new row, then do not remove it.\n if (this.editRows[dataLength] && (this.editRows[dataLength].state === EditRowState.New)) {\n dataLength = (dataLength + 1);\n }\n this.editRows.slice(dataLength).forEach((editRow, index) => this.baseRemoveRow(dataLength + index));\n this.editRows = this.editRows.slice(0, dataLength);\n this.openWhenEmpty();\n this.updateOnChange(flags, changed);\n // do not call checkData with server option, it is called when change is triggered in updateOnChange\n if (!this.options.server) {\n this.checkData();\n }\n this.changeState(changed, flags);\n return changed;\n }\n openWhenEmpty() {\n const shouldBeOpened = !this.dataValue.length && this.component.openWhenEmpty;\n const hasNoRows = !this.editRows.length;\n if (hasNoRows && shouldBeOpened && !this.builderMode) {\n const dataObj = {};\n this.createRow(dataObj, 0);\n }\n }\n restoreRowContext(editRow, flags = {}) {\n editRow.components.forEach((component) => {\n component.data = editRow.data;\n this.setNestedValue(component, editRow.data, flags);\n });\n }\n emptyRows() {\n this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));\n this.editRows = [];\n }\n resetValue() {\n super.resetValue();\n this.emptyRows();\n }\n}\nexports[\"default\"] = EditGridComponent;\nEditGridComponent.prototype.hasChanged = Component_1.default.prototype.hasChanged;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/editgrid/EditGrid.js?");
|
6297
6297
|
|
6298
6298
|
/***/ }),
|
6299
6299
|
|
@@ -6931,7 +6931,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6931
6931
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
6932
6932
|
|
6933
6933
|
"use strict";
|
6934
|
-
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.selectMetadata || this.component.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 const readOnlyResourceLabelData = this.options.readOnly && (this.component.dataSrc === 'resource' || this.component.dataSrc === 'url') && this.selectData;\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : readOnlyResourceLabelData || 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 * @param {*} value - The value of the new option.\n * @param {string} label - The label of the new option.\n * @param {object} [attrs] - Additional value attributes. Defaults to {}.\n * @param {string} [id] - An id. Defaults to a random string.\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 * @returns {*} - Returns 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 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. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\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 - The value to transform.\n * @returns {*} - Returns the options 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} - Returns an array of the static or custom values.\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 * @returns {boolean} - Returns FALSE for select components.\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 * @returns {*}\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 if (options.modalPreview && this.selectData) {\n const { label } = this.selectValueAndLabel(value);\n return label;\n }\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.removeHTML)(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?");
|
6934
|
+
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 const numberType = () => ({ type: 'number' });\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 }, dataTypeOperators: {\n number: ['lessThan', 'greaterThan', 'lessThanOrEqual', 'greaterThanOrEqual'],\n }, dataTypeValueComponents: {\n number: {\n lessThan: numberType,\n greaterThan: numberType,\n lessThanOrEqual: numberType,\n greaterThanOrEqual: numberType,\n },\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.selectMetadata || this.component.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 const readOnlyResourceLabelData = this.options.readOnly && (this.component.dataSrc === 'resource' || this.component.dataSrc === 'url') && this.selectData;\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : readOnlyResourceLabelData || 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 * @param {*} value - The value of the new option.\n * @param {string} label - The label of the new option.\n * @param {object} [attrs] - Additional value attributes. Defaults to {}.\n * @param {string} [id] - An id. Defaults to a random string.\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 * @returns {*} - Returns 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 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. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\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 - The value to transform.\n * @returns {*} - Returns the options 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} - Returns an array of the static or custom values.\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 * @returns {boolean} - Returns FALSE for select components.\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 * @returns {*}\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 if (options.modalPreview && this.selectData) {\n const { label } = this.selectValueAndLabel(value);\n return label;\n }\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.removeHTML)(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?");
|
6935
6935
|
|
6936
6936
|
/***/ }),
|
6937
6937
|
|
@@ -7195,7 +7195,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7195
7195
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
7196
7196
|
|
7197
7197
|
"use strict";
|
7198
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst choices_js_1 = __importDefault(__webpack_require__(/*! @formio/choices.js */ \"./node_modules/@formio/choices.js/public/assets/scripts/choices.js\"));\nclass TagsComponent extends Input_1.default {\n static schema(...extend) {\n return Input_1.default.schema({\n type: 'tags',\n label: 'Tags',\n key: 'tags',\n delimeter: ',',\n storeas: 'string',\n maxTags: 0\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Tags',\n icon: 'tags',\n group: 'advanced',\n documentation: '/userguide/form-building/advanced-components#tags',\n weight: 30,\n schema: TagsComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return TagsComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { operators: [...super.conditionOperatorsSettings.operators, 'includes', 'notIncludes'] });\n }\n static savedValueTypes(schema) {\n schema = schema || {};\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes[schema.storeas] || utils_1.componentValueTypes.string];\n }\n init() {\n super.init();\n }\n get emptyValue() {\n return (this.component.storeas === 'string') ? '' : [];\n }\n get defaultSchema() {\n return TagsComponent.schema();\n }\n get inputInfo() {\n const info = super.inputInfo;\n info.type = 'input';\n info.attr.type = 'text';\n info.changeEvent = 'change';\n return info;\n }\n get delimiter() {\n return this.component.delimeter || ',';\n }\n attachElement(element, index) {\n super.attachElement(element, index);\n if (!element) {\n return;\n }\n if (this.i18next) {\n element.setAttribute('dir', this.i18next.dir());\n }\n if (this.choices) {\n this.choices.destroy();\n }\n if (!choices_js_1.default) {\n return;\n }\n const hasPlaceholder = !!this.component.placeholder;\n this.choices = new choices_js_1.default(element, {\n delimiter: this.delimiter,\n editItems: true,\n allowHTML: true,\n maxItemCount: this.component.maxTags,\n removeItemButton: true,\n duplicateItemsAllowed: false,\n shadowRoot: this.root ? this.root.shadowRoot : null,\n placeholder: hasPlaceholder,\n placeholderValue: hasPlaceholder ? this.t(this.component.placeholder, { _userInput: true }) : null,\n });\n this.choices.itemList.element.tabIndex = element.tabIndex;\n this.addEventListener(this.choices.input.element, 'blur', () => {\n // Emit event to the native Formio input, so the listener attached in the Input.js will be invoked\n element.dispatchEvent(new Event('blur'));\n const value = this.choices.input.value;\n const maxTagsNumber = this.component.maxTags;\n const valuesCount = this.choices.getValue(true).length;\n const isRepeatedValue = this.choices.getValue(true).some(existingValue => existingValue.trim() === value.trim());\n if (value) {\n if (maxTagsNumber && valuesCount === maxTagsNumber) {\n this.choices.addItems = false;\n this.choices.clearInput();\n }\n else if (isRepeatedValue) {\n this.choices.clearInput();\n }\n else {\n this.choices.setValue([value]);\n this.choices.clearInput();\n this.choices.hideDropdown(true);\n this.updateValue(null, {\n modified: true\n });\n }\n }\n });\n }\n detach() {\n if (this.choices) {\n this.choices.destroy();\n this.choices = null;\n }\n super.detach();\n }\n normalizeValue(value) {\n if (this.component.storeas === 'string' && Array.isArray(value)) {\n return value.join(this.delimiter);\n }\n else if (this.component.storeas === 'array' && typeof value === 'string') {\n return value.split(this.delimiter).filter(result => result);\n }\n return value;\n }\n setValue(value, flags = {}) {\n const changed = super.setValue(value, flags);\n if (this.choices) {\n let dataValue = this.dataValue;\n this.choices.removeActiveItems();\n if (dataValue) {\n if (typeof dataValue === 'string') {\n dataValue = dataValue.split(this.delimiter).filter(result => result);\n }\n const value = Array.isArray(dataValue) ? dataValue : [dataValue];\n this.choices.setValue(value.map((val) => this.sanitize(val, this.shouldSanitizeValue)));\n }\n }\n return changed;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.choices.disable();\n }\n else {\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n focus() {\n if (this.refs.input && this.refs.input.length) {\n this.refs.input[0].parentNode.lastChild.focus();\n }\n }\n getValueAsString(value) {\n if (!value) {\n return '';\n }\n if (Array.isArray(value)) {\n return value.join(`${this.delimiter || ','} `);\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue, this.shouldSanitizeValue);\n }\n}\nexports[\"default\"] = TagsComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/tags/Tags.js?");
|
7198
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst choices_js_1 = __importDefault(__webpack_require__(/*! @formio/choices.js */ \"./node_modules/@formio/choices.js/public/assets/scripts/choices.js\"));\nclass TagsComponent extends Input_1.default {\n static schema(...extend) {\n return Input_1.default.schema({\n type: 'tags',\n label: 'Tags',\n key: 'tags',\n delimeter: ',',\n storeas: 'string',\n maxTags: 0\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Tags',\n icon: 'tags',\n group: 'advanced',\n documentation: '/userguide/form-building/advanced-components#tags',\n weight: 30,\n schema: TagsComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return TagsComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { operators: [...super.conditionOperatorsSettings.operators, 'includes', 'notIncludes'] });\n }\n static savedValueTypes(schema) {\n schema = schema || {};\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes[schema.storeas] || utils_1.componentValueTypes.string];\n }\n init() {\n super.init();\n }\n get emptyValue() {\n return (this.component.storeas === 'string') ? '' : [];\n }\n get defaultSchema() {\n return TagsComponent.schema();\n }\n get inputInfo() {\n const info = super.inputInfo;\n info.type = 'input';\n info.attr.type = 'text';\n info.changeEvent = 'change';\n return info;\n }\n get delimiter() {\n return this.component.delimeter || ',';\n }\n attachElement(element, index) {\n super.attachElement(element, index);\n if (!element) {\n return;\n }\n if (this.i18next) {\n element.setAttribute('dir', this.i18next.dir());\n }\n if (this.choices) {\n this.choices.destroy();\n }\n if (!choices_js_1.default) {\n return;\n }\n const hasPlaceholder = !!this.component.placeholder;\n this.choices = new choices_js_1.default(element, {\n delimiter: this.delimiter,\n editItems: true,\n allowHTML: true,\n maxItemCount: this.component.maxTags,\n removeItemButton: true,\n duplicateItemsAllowed: false,\n shadowRoot: this.root ? this.root.shadowRoot : null,\n placeholder: hasPlaceholder,\n placeholderValue: hasPlaceholder ? this.t(this.component.placeholder, { _userInput: true }) : null,\n });\n this.choices.itemList.element.tabIndex = element.tabIndex;\n this.addEventListener(this.choices.input.element, 'blur', () => {\n // Emit event to the native Formio input, so the listener attached in the Input.js will be invoked\n element.dispatchEvent(new Event('blur'));\n const value = this.choices.input.value;\n const maxTagsNumber = this.component.maxTags;\n const valuesCount = this.choices.getValue(true).length;\n const isRepeatedValue = this.choices.getValue(true).some(existingValue => existingValue.trim() === value.trim());\n if (value) {\n if (maxTagsNumber && valuesCount === maxTagsNumber) {\n this.choices.addItems = false;\n this.choices.clearInput();\n }\n else if (isRepeatedValue) {\n this.choices.clearInput();\n }\n else {\n this.choices.setValue([value]);\n this.choices.clearInput();\n this.choices.hideDropdown(true);\n this.updateValue(null, {\n modified: true\n });\n }\n }\n });\n }\n detach() {\n if (this.choices) {\n this.choices.destroy();\n this.choices = null;\n }\n super.detach();\n }\n normalizeValue(value) {\n if (this.component.storeas === 'string' && Array.isArray(value)) {\n return super.normalizeValue(value.join(this.delimiter));\n }\n else if (this.component.storeas === 'array' && typeof value === 'string') {\n return super.normalizeValue(value.split(this.delimiter).filter(result => result));\n }\n return super.normalizeValue(value);\n }\n setValue(value, flags = {}) {\n const changed = super.setValue(value, flags);\n if (this.choices) {\n let dataValue = this.dataValue;\n this.choices.removeActiveItems();\n if (dataValue) {\n if (typeof dataValue === 'string') {\n dataValue = dataValue.split(this.delimiter).filter(result => result);\n }\n const value = Array.isArray(dataValue) ? dataValue : [dataValue];\n this.choices.setValue(value.map((val) => this.sanitize(val, this.shouldSanitizeValue)));\n }\n }\n return changed;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.choices.disable();\n }\n else {\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n focus() {\n if (this.refs.input && this.refs.input.length) {\n this.refs.input[0].parentNode.lastChild.focus();\n }\n }\n getValueAsString(value) {\n if (!value) {\n return '';\n }\n if (Array.isArray(value)) {\n return value.join(`${this.delimiter || ','} `);\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue, this.shouldSanitizeValue);\n }\n}\nexports[\"default\"] = TagsComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/tags/Tags.js?");
|
7199
7199
|
|
7200
7200
|
/***/ }),
|
7201
7201
|
|
@@ -10843,7 +10843,7 @@ eval("\nvar parent = __webpack_require__(/*! ../../es/object/from-entries */ \".
|
|
10843
10843
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
10844
10844
|
|
10845
10845
|
"use strict";
|
10846
|
-
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 if (!attrs) {\n return element;\n }\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 if (_a.config.submitDone) {\n _a.config.submitDone(submission, instance);\n }\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(libWrapper, 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 const libName = lib.dependencies[i];\n yield _a.addLibrary(libWrapper, _a.config.libs[libName], libName);\n }\n }\n if (lib.css) {\n yield _a.addStyles((lib.global ? document.body : libWrapper), lib.css);\n }\n if (lib.js) {\n const module = yield _a.addScript((lib.global ? document.body : libWrapper), 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 if (lib.globalStyle) {\n const style = _a.createElement('style');\n style.type = 'text/css';\n style.innerHTML = lib.globalStyle;\n document.body.appendChild(style);\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 // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need\n // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.\n css: `https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css`,\n globalStyle: `@font-face {\n font-family: 'FontAwesome';\n src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?v=4.7.0');\n src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');\n font-weight: normal;\n font-style: normal;\n }`\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 // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need\n // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.\n css: 'https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.min.css',\n globalStyle: `@font-face {\n font-display: block;\n font-family: \"bootstrap-icons\";\n src: url(\"https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6\") format(\"woff2\"),\n url(\"https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6\") format(\"woff\");\n }`\n }\n };\n // Add all bootswatch templates.\n ['cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal', 'litera', 'lumen', 'lux', 'materia', 'minty', 'pulse', 'sandstone', 'simplex', 'sketchy', 'slate', 'solar', 'spacelab', 'superhero', 'united', 'yeti'].forEach((template) => {\n _a.config.libs[template] = {\n dependencies: ['bootstrap-icons'],\n css: `${_a.cdn.bootswatch}/dist/${template}/bootstrap.min.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 && !_a.config.noshadow && (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 if (!_a.config.libraries) {\n _a.config.libraries = _a.config.modules || {};\n }\n // Adding premium if it is provided via the config.\n if (_a.config.premium) {\n _a.config.libraries.premium = _a.config.premium;\n }\n // Allow adding dynamic modules.\n if (_a.config.libraries) {\n for (const name in _a.config.libraries) {\n const lib = _a.config.libraries[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.76';\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?");
|
10846
|
+
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 if (!attrs) {\n return element;\n }\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 if (_a.config.submitDone) {\n _a.config.submitDone(submission, instance);\n }\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(libWrapper, 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 const libName = lib.dependencies[i];\n yield _a.addLibrary(libWrapper, _a.config.libs[libName], libName);\n }\n }\n if (lib.css) {\n yield _a.addStyles((lib.global ? document.body : libWrapper), lib.css);\n }\n if (lib.js) {\n const module = yield _a.addScript((lib.global ? document.body : libWrapper), 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 if (lib.globalStyle) {\n const style = _a.createElement('style');\n style.type = 'text/css';\n style.innerHTML = lib.globalStyle;\n document.body.appendChild(style);\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 // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need\n // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.\n css: `https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css`,\n globalStyle: `@font-face {\n font-family: 'FontAwesome';\n src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?v=4.7.0');\n src: url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');\n font-weight: normal;\n font-style: normal;\n }`\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 // Due to an issue with font-face not loading in the shadowdom (https://issues.chromium.org/issues/41085401), we need\n // to do 2 things. 1.) Load the fonts from the global cdn, and 2.) add the font-face to the global styles on the page.\n css: 'https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.min.css',\n globalStyle: `@font-face {\n font-display: block;\n font-family: \"bootstrap-icons\";\n src: url(\"https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff2?dd67030699838ea613ee6dbda90effa6\") format(\"woff2\"),\n url(\"https://cdn.jsdelivr.net/npm/bootstrap-icons/font/fonts/bootstrap-icons.woff?dd67030699838ea613ee6dbda90effa6\") format(\"woff\");\n }`\n }\n };\n // Add all bootswatch templates.\n ['cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal', 'litera', 'lumen', 'lux', 'materia', 'minty', 'pulse', 'sandstone', 'simplex', 'sketchy', 'slate', 'solar', 'spacelab', 'superhero', 'united', 'yeti'].forEach((template) => {\n _a.config.libs[template] = {\n dependencies: ['bootstrap-icons'],\n css: `${_a.cdn.bootswatch}/dist/${template}/bootstrap.min.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 && !_a.config.noshadow && (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 if (!_a.config.libraries) {\n _a.config.libraries = _a.config.modules || {};\n }\n // Adding premium if it is provided via the config.\n if (_a.config.premium) {\n _a.config.libraries.premium = _a.config.premium;\n }\n // Allow adding dynamic modules.\n if (_a.config.libraries) {\n for (const name in _a.config.libraries) {\n const lib = _a.config.libraries[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.78';\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?");
|
10847
10847
|
|
10848
10848
|
/***/ }),
|
10849
10849
|
|
@@ -10854,7 +10854,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
10854
10854
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
10855
10855
|
|
10856
10856
|
"use strict";
|
10857
|
-
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.
|
10857
|
+
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.78';\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;\nsdk_1.Formio.addToGlobal = (global) => {\n if (typeof global === 'object' && !global.Formio) {\n global.Formio = sdk_1.Formio;\n }\n};\nif (typeof __webpack_require__.g !== 'undefined') {\n sdk_1.Formio.addToGlobal(__webpack_require__.g);\n}\nif (typeof window !== 'undefined') {\n sdk_1.Formio.addToGlobal(window);\n}\nEmbed_1.Formio._formioReady(sdk_1.Formio);\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/Formio.js?");
|
10858
10858
|
|
10859
10859
|
/***/ }),
|
10860
10860
|
|