@formio/js 5.0.0-dev.5902.1eb1690 → 5.0.0-dev.5902.8763b69

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.
@@ -5172,7 +5172,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
5172
5172
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5173
5173
 
5174
5174
  "use strict";
5175
- 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, '&quot;')}\" 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 this.emit('editGridOpenModal', {\n component: this.component,\n row: editRow,\n instance: this,\n });\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 this.emit('editGridEditRow', {\n component: this.component,\n row: editRow,\n instance: this,\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.rowIndex = rowIndex;\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, 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, fromSubmission) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n fromSubmission ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {\n var _a, _b;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {\n const silentCheck = forceSilentCheck === false ? false : ((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 const errors = (0, process_1.processSync)({\n components: this.component.components,\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: Object.assign(Object.assign({}, this.paths), { dataIndex: editRow.rowIndex }),\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n editRow.errors = (this.component.modal || this.component.rowDrafts)\n ? errors\n : errors.filter((err) => lodash_1.default.find(this.visibleErrors, ['component.id', err.component.id]));\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 (editRow.alerts && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n else if ((_b = editRow.errors) === null || _b === void 0 ? void 0 : _b.length) {\n this.setCustomValidity(editRow.errors, dirty);\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, fromSubmission } = 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, fromSubmission);\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 this.removeClass(errorContainer, 'help-block');\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) {\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 this.checkData();\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?");
5175
+ 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 let typeChanged = false;\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 typeChanged = true;\n }\n return typeChanged;\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, '&quot;')}\" 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 this.emit('editGridOpenModal', {\n component: this.component,\n row: editRow,\n instance: this,\n });\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 this.emit('editGridEditRow', {\n component: this.component,\n row: editRow,\n instance: this,\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.rowIndex = rowIndex;\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, false);\n }\n if (this.variableTypeComponentsIndexes.length) {\n const typeChanged = this.checkRowVariableTypeComponents(editRow, rowIndex);\n if (typeChanged) {\n this.redraw();\n }\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, fromSubmission) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n fromSubmission ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {\n var _a, _b;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {\n const silentCheck = forceSilentCheck === false ? false : ((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 const errors = (0, process_1.processSync)({\n components: this.component.components,\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: Object.assign(Object.assign({}, this.paths), { dataIndex: editRow.rowIndex }),\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n editRow.errors = (this.component.modal || this.component.rowDrafts)\n ? errors\n : errors.filter((err) => lodash_1.default.find(this.visibleErrors, ['component.id', err.component.id]));\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 (editRow.alerts && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n else if ((_b = editRow.errors) === null || _b === void 0 ? void 0 : _b.length) {\n this.setCustomValidity(editRow.errors, dirty);\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, fromSubmission } = 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, fromSubmission);\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 this.removeClass(errorContainer, 'help-block');\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) {\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 this.checkData();\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?");
5176
5176
 
5177
5177
  /***/ }),
5178
5178
 
@@ -5216,7 +5216,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
5216
5216
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5217
5217
 
5218
5218
  "use strict";
5219
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* eslint-disable max-statements */\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../_classes/componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nclass FormComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'Form',\n type: 'form',\n key: 'form',\n src: '',\n reference: true,\n form: '',\n path: '',\n tableView: true,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Nested Form',\n icon: 'wpforms',\n group: 'premium',\n documentation: '/userguide/form-building/premium-components#nested-form',\n weight: 110,\n schema: FormComponent.schema()\n };\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.object];\n }\n init() {\n super.init();\n this.formObj = {\n display: this.component.display,\n settings: this.component.settings,\n components: this.component.components\n };\n this.valueChanged = false;\n this.subForm = null;\n this.formSrc = '';\n if (this.component.src) {\n this.formSrc = this.component.src;\n }\n if (!this.component.src &&\n !this.options.formio &&\n (this.component.form || this.component.path)) {\n if (this.component.project) {\n this.formSrc = Formio_1.Formio.getBaseUrl();\n // Check to see if it is a MongoID.\n if ((0, utils_1.isMongoId)(this.component.project)) {\n this.formSrc += '/project';\n }\n this.formSrc += `/${this.component.project}`;\n this.options.project = this.formSrc;\n }\n else {\n this.formSrc = Formio_1.Formio.getProjectUrl();\n this.options.project = this.formSrc;\n }\n if (this.component.form) {\n if ((0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc += `/form/${this.component.form}`;\n }\n else {\n this.formSrc += `/${this.component.form}`;\n }\n }\n else if (this.component.path) {\n this.formSrc += `/${this.component.path}`;\n }\n }\n // Build the source based on the root src path.\n if (!this.formSrc && this.options.formio) {\n const rootSrc = this.options.formio.formsUrl;\n if (this.component.form && (0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc = `${rootSrc}/${this.component.form}`;\n }\n else {\n const formPath = this.component.path || this.component.form;\n this.formSrc = `${rootSrc.replace(/\\/form$/, '')}/${formPath}`;\n }\n }\n if (this.builderMode && this.component.hasOwnProperty('formRevision')) {\n this.component.revision = this.component.formRevision;\n delete this.component.formRevision;\n }\n // Add revision version if set.\n if (this.component.revision || this.component.revision === 0 ||\n this.component.formRevision || this.component.formRevision === 0\n || this.component.revisionId) {\n this.setFormRevision(this.component.revisionId || this.component.revision || this.component.formRevision);\n }\n return this.createSubForm();\n }\n get dataReady() {\n return this.subFormReady || Promise.resolve();\n }\n get defaultValue() {\n // Not not provide a default value unless the subform is ready so that it will initialize correctly.\n return this.subForm ? super.defaultValue : null;\n }\n get defaultSchema() {\n return FormComponent.schema();\n }\n get emptyValue() {\n return { data: {} };\n }\n get ready() {\n return this.subFormReady || Promise.resolve();\n }\n get useOriginalRevision() {\n var _a, _b;\n return ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && !!((_b = this.formObj) === null || _b === void 0 ? void 0 : _b.revisions);\n }\n setFormRevision(rev) {\n // Remove current revisions from src if it is\n this.formSrc = this.formSrc.replace(/\\/v\\/[0-9a-z]+/, '');\n const revNumber = Number.parseInt(rev);\n if (!isNaN(revNumber)) {\n this.subFormRevision = rev;\n this.formSrc += `/v/${rev}`;\n }\n else {\n this.subFormRevision = undefined;\n }\n }\n getComponent(path) {\n if (!this.subForm) {\n return null;\n }\n return this.subForm.getComponent(path);\n }\n /* eslint-disable max-statements */\n getSubOptions(options = {}) {\n options.events = this.createEmitter();\n // Make sure to not show the submit button in wizards in the nested forms.\n lodash_1.default.set(options, 'buttonSettings.showSubmit', false);\n if (!this.options) {\n return options;\n }\n if (this.options.base) {\n options.base = this.options.base;\n }\n if (this.options.project) {\n options.project = this.options.project;\n }\n if (this.options.readOnly || this.component.disabled) {\n options.readOnly = this.options.readOnly || this.component.disabled;\n }\n if (this.options.breadcrumbSettings) {\n options.breadcrumbSettings = this.options.breadcrumbSettings;\n }\n if (this.options.buttonSettings) {\n options.buttonSettings = lodash_1.default.clone(this.options.buttonSettings);\n }\n if (this.options.viewAsHtml) {\n options.viewAsHtml = this.options.viewAsHtml;\n }\n if (this.options.language) {\n options.language = this.options.language;\n }\n if (this.options.template) {\n options.template = this.options.template;\n }\n if (this.options.templates) {\n options.templates = this.options.templates;\n }\n if (this.options.renderMode) {\n options.renderMode = this.options.renderMode;\n }\n if (this.options.attachMode) {\n options.attachMode = this.options.attachMode;\n }\n if (this.options.iconset) {\n options.iconset = this.options.iconset;\n }\n if (this.options.fileService) {\n options.fileService = this.options.fileService;\n }\n if (this.options.onChange) {\n options.onChange = this.options.onChange;\n }\n if (this.options.preview) {\n options.preview = this.options.preview;\n }\n if (this.options.inEditGrid) {\n options.inEditGrid = this.options.inEditGrid;\n }\n if (this.options.saveDraft) {\n options.saveDraft = this.options.saveDraft;\n options.formio = new Formio_1.Formio(this.formSrc);\n }\n if (this.options.saveDraftThrottle) {\n options.saveDraftThrottle = this.options.saveDraftThrottle;\n }\n if (this.options.skipDraftRestore) {\n options.skipDraftRestore = this.options.skipDraftRestore;\n }\n options.parent = this;\n return options;\n }\n /* eslint-enable max-statements */\n render() {\n if (this.builderMode) {\n return super.render(this.component.label || 'Nested form');\n }\n const subform = this.subForm ? this.subForm.render() : this.renderTemplate('loading');\n return super.render(subform);\n }\n asString(value) {\n return this.getValueAsString(value);\n }\n /**\n * Prints out the value of form components as a datagrid value.\n */\n getValueAsString(value, options) {\n if (!value) {\n return 'No data provided';\n }\n if (!value.data && value._id) {\n return value._id;\n }\n if (!value.data || !Object.keys(value.data).length) {\n return 'No data provided';\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n return '[Complex Data]';\n }\n attach(element) {\n // Don't attach in builder.\n if (this.builderMode) {\n return super.attach(element);\n }\n return super.attach(element)\n .then(() => {\n if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {\n this.createSubForm(true);\n }\n return this.subFormReady.then(() => {\n this.empty(element);\n if (this.options.builder) {\n this.setContent(element, this.ce('div', {\n class: 'text-muted text-center p-2'\n }, this.text(this.formObj.title)));\n return;\n }\n this.setContent(element, this.render());\n if (this.subForm) {\n if (this.isNestedWizard) {\n element = this.root.element;\n }\n this.subForm.attach(element);\n this.valueChanged = this.hasSetValue;\n if (!this.valueChanged && this.dataValue.state !== 'submitted') {\n this.setDefaultValue();\n }\n else {\n this.restoreValue();\n }\n }\n if (!this.builderMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n this.componentModal = new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;\n this.setOpenModalElement();\n }\n this.calculateValue();\n });\n });\n }\n detach() {\n if (this.subForm) {\n this.subForm.detach();\n }\n super.detach();\n }\n get currentForm() {\n return this._currentForm;\n }\n get hasLoadedForm() {\n return this.formObj\n && this.formObj.components\n && Array.isArray(this.formObj.components)\n && this.formObj.components.length;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n if (!this.subForm) {\n return;\n }\n this.subForm.getComponents().forEach(component => {\n component.currentForm = this;\n });\n }\n get isRevisionChanged() {\n return lodash_1.default.isNumber(this.subFormRevision)\n && lodash_1.default.isNumber(this.formObj._vid)\n && this.formObj._vid !== this.subFormRevision;\n }\n destroy(all = false) {\n if (this.subForm) {\n this.subForm.destroy(all);\n this.subForm = null;\n this.subFormReady = null;\n }\n super.destroy(all);\n }\n redraw() {\n if (this.subForm) {\n this.subForm.form = this.formObj;\n this.setSubFormDisabled(this.subForm);\n }\n return super.redraw();\n }\n /**\n * Pass everyComponent to subform.\n * @param {any[]} args - Arguments to pass through to the subform's everyComponent method.\n * @returns {*} - The result of the subform's everyComponent method.\n */\n everyComponent(...args) {\n if (this.subForm) {\n this.subForm.everyComponent(...args);\n }\n }\n setSubFormDisabled(subForm) {\n subForm.disabled = this.disabled; // When the Nested Form is disabled make the subForm disabled\n }\n updateSubWizards(subForm) {\n var _a, _b;\n if (this.isNestedWizard && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.subWizards) && ((_b = subForm === null || subForm === void 0 ? void 0 : subForm._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard') {\n const existedForm = this.root.subWizards.findIndex(form => form.component.form === this.component.form);\n if (existedForm !== -1) {\n this.root.subWizards[existedForm] = this;\n }\n else {\n this.root.subWizards.push(this);\n }\n this.emit('subWizardsUpdated', subForm);\n }\n }\n /**\n * Create a subform instance.\n * @param {boolean} [fromAttach] - This function is being called from an `attach` method.\n * @returns {*} - The subform instance.\n */\n createSubForm(fromAttach) {\n this.subFormReady = this.loadSubForm(fromAttach).then((form) => {\n if (!form) {\n return;\n }\n // Iterate through every component and hide the submit button.\n (0, utils_1.eachComponent)(form.components, (component) => {\n this.hideSubmitButton(component);\n });\n // If the subform is already created then destroy the old one.\n if (this.subForm) {\n this.subForm.destroy();\n }\n // Render the form.\n return (new Form_1.default(form, this.getSubOptions())).ready.then((instance) => {\n this.subForm = instance;\n this.subForm.currentForm = this;\n const componentsMap = this.componentsMap;\n const formComponentsMap = this.subForm.componentsMap;\n lodash_1.default.assign(componentsMap, formComponentsMap);\n this.component.components = this.subForm.components.map((comp) => comp.component);\n this.subForm.parent = this;\n this.subForm.parentVisible = this.visible;\n this.subForm.on('change', () => {\n if (this.subForm) {\n this.dataValue = this.subForm.getValue();\n this.triggerChange({\n noEmit: true\n });\n }\n });\n this.subForm.url = this.formSrc;\n this.subForm.nosubmit = true;\n this.subForm.root = this.root;\n this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;\n this.restoreValue();\n this.valueChanged = this.hasSetValue;\n this.onChange();\n return this.subForm;\n }).catch((err) => {\n console.log(err);\n });\n }).then((subForm) => {\n this.updateSubWizards(subForm);\n return subForm;\n });\n return this.subFormReady;\n }\n hideSubmitButton(component) {\n const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);\n if (isSubmitButton) {\n component.hidden = true;\n component.customConditional = 'show = false';\n }\n }\n /**\n * Load the subform.\n * @param {boolean} fromAttach - This function is being called from an `attach` method.\n * @returns {Promise} - The promise that resolves when the subform is loaded.\n */\n loadSubForm(fromAttach) {\n var _a, _b, _c, _d, _e;\n if (this.builderMode || this.conditionallyHidden || (this.isSubFormLazyLoad() && !fromAttach)) {\n return Promise.resolve();\n }\n if (this.hasLoadedForm && !this.isRevisionChanged &&\n !(this.options.pdf && ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && lodash_1.default.isNull(this.subForm) && !this.subFormLoading)) {\n // Pass config down to sub forms.\n if (this.root && this.root.form && this.root.form.config && !this.formObj.config) {\n this.formObj.config = this.root.form.config;\n }\n return Promise.resolve(this.formObj);\n }\n else if (this.formSrc) {\n this.subFormLoading = true;\n const options = ((_c = (_b = this.root) === null || _b === void 0 ? void 0 : _b.formio) === null || _c === void 0 ? void 0 : _c.base) && ((_e = (_d = this.root) === null || _d === void 0 ? void 0 : _d.formio) === null || _e === void 0 ? void 0 : _e.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n return (new Formio_1.Formio(this.formSrc, options)).loadForm({ params: { live: 1 } })\n .then((formObj) => {\n this.formObj = formObj;\n if (this.options.pdf && this.component.useOriginalRevision) {\n this.formObj.display = 'form';\n }\n this.subFormLoading = false;\n return formObj;\n })\n .catch((err) => {\n console.log(err);\n return null;\n });\n }\n return Promise.resolve();\n }\n checkComponentConditions(data, flags, row) {\n const visible = super.checkComponentConditions(data, flags, row);\n // Return if already hidden\n if (!visible) {\n return visible;\n }\n if (this.subForm) {\n return this.subForm.checkConditions(data, flags, row);\n }\n // There are few cases when subForm is not loaded when a change is triggered,\n // so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode\n else if (this.subFormReady) {\n this.subFormReady.then(() => {\n if (this.subForm) {\n return this.subForm.checkConditions(data, flags, row);\n }\n });\n }\n return visible;\n }\n calculateValue(data, flags, row) {\n if (this.subForm) {\n return this.subForm.calculateValue(data, flags, row);\n }\n return super.calculateValue(data, flags, row);\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n if (this.subForm) {\n this.subForm.setPristine(pristine);\n }\n }\n /**\n * Determine if the subform should be submitted.\n * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.\n */\n get shouldSubmit() {\n return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.conditionallyHidden;\n }\n /**\n * Returns the data for the subform.\n * @returns {*} - the data for the subform.\n */\n getSubFormData() {\n if (lodash_1.default.get(this.subForm, 'form.display') === 'pdf') {\n return this.subForm.getSubmission();\n }\n else {\n return Promise.resolve(this.dataValue);\n }\n }\n /**\n * Submit the subform if configured to do so.\n * @returns {Promise} - The promise that resolves when the subform is submitted.\n */\n submitSubForm() {\n // If we wish to submit the form on next page, then do that here.\n if (this.shouldSubmit) {\n return this.subFormReady.then(() => {\n if (!this.subForm) {\n return this.dataValue;\n }\n this.subForm.nosubmit = false;\n this.subForm.submitted = true;\n return this.subForm.submitForm({}, true).then(result => {\n this.subForm.loading = false;\n this.subForm.showAllErrors = false;\n this.dataValue = result.submission;\n return this.dataValue;\n }).catch(err => {\n this.subForm.showAllErrors = true;\n this.subForm.onSubmissionError(err);\n return Promise.reject(err);\n });\n });\n }\n return this.getSubFormData();\n }\n /**\n * Submit the form before the next page is triggered.\n * @param {Function} next - The function to trigger the next page.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the next page is triggered.\n */\n beforePage(next) {\n // Should not submit child forms if we are going to the previous page\n if (!next) {\n return super.beforePage(next);\n }\n return this.submitSubForm(true).then(() => super.beforePage(next));\n }\n /**\n * Submit the form before the whole form is triggered.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the form is submitted.\n */\n beforeSubmit() {\n var _a, _b, _c;\n const submission = this.dataValue;\n // Cancel triggered saveDraft\n if (((_a = this.subForm) === null || _a === void 0 ? void 0 : _a.draftEnabled) && ((_b = this.subForm.triggerSaveDraft) === null || _b === void 0 ? void 0 : _b.cancel)) {\n this.subForm.triggerSaveDraft.cancel();\n }\n const isAlreadySubmitted = submission && submission._id && submission.form;\n const isDraftSubmission = this.options.saveDraft && submission.state === 'draft';\n // This submission has already been submitted, so just return the reference data.\n if (isAlreadySubmitted && !((_c = this.subForm) === null || _c === void 0 ? void 0 : _c.wizard) && !isDraftSubmission) {\n this.dataValue = submission;\n return Promise.resolve(this.dataValue);\n }\n return this.submitSubForm(false)\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n isSubFormLazyLoad() {\n var _a, _b;\n return ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && this.component.lazyLoad;\n }\n isHidden() {\n if (!this.visible) {\n return true;\n }\n return !super.checkConditions(this.rootValue);\n }\n setValue(submission, flags = {}) {\n var _a;\n const changed = super.setValue(submission, flags);\n this.valueChanged = true;\n if (this.subForm) {\n const revisionPath = submission._frid ? '_frid' : '_vid';\n const shouldLoadOriginalRevision = this.useOriginalRevision\n && (lodash_1.default.isNumber(submission[revisionPath]) || lodash_1.default.isNumber(submission._fvid))\n && lodash_1.default.isNumber((_a = this.subForm.form) === null || _a === void 0 ? void 0 : _a[revisionPath])\n && submission._fvid !== this.subForm.form[revisionPath];\n if (shouldLoadOriginalRevision) {\n this.setFormRevision(submission._frid || submission._fvid);\n this.createSubForm().then(() => {\n this.attach(this.element);\n });\n }\n else {\n this.setSubFormValue(submission, flags);\n }\n }\n return changed;\n }\n setSubFormValue(submission, flags) {\n var _a, _b, _c, _d;\n const shouldLoadSubmissionById = submission\n && submission._id\n && this.subForm.formio\n && lodash_1.default.isEmpty(submission.data);\n const shouldLoadDraftById = this.options.saveDraft && lodash_1.default.isEmpty(submission.data) && lodash_1.default.get(this.subForm, 'submission._id');\n if (shouldLoadSubmissionById || shouldLoadDraftById) {\n const formId = submission.form || this.formObj.form || this.component.form;\n const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;\n const options = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.formio) === null || _b === void 0 ? void 0 : _b.base) && ((_d = (_c = this.root) === null || _c === void 0 ? void 0 : _c.formio) === null || _d === void 0 ? void 0 : _d.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n this.subForm.setUrl(submissionUrl, Object.assign(Object.assign({}, this.options), options));\n this.subForm.loadSubmission().catch((err) => {\n console.error(`Unable to load subform submission ${submission._id}:`, err);\n });\n }\n else {\n this.onSetSubFormValue(submission, flags);\n }\n }\n /**\n * Sets the subform value\n * @param {object|null|undefined} submission - The submission to set.\n * @param {object|null|undefined} flags - Any flags to apply when setting the submission.\n * @returns {void}\n */\n onSetSubFormValue(submission, flags) {\n this.subForm.setValue(submission, flags);\n }\n isEmpty(value = this.dataValue) {\n return value === null || lodash_1.default.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value === null || value === void 0 ? void 0 : value.data) && !(value === null || value === void 0 ? void 0 : value._id));\n }\n areAllComponentsEmpty(data) {\n let res = true;\n if (this.subForm) {\n this.subForm.everyComponent((comp) => {\n const componentValue = lodash_1.default.get(data, comp.key);\n res &= comp.isEmpty(componentValue);\n });\n }\n else {\n res = false;\n }\n return res;\n }\n getValue() {\n if (this.subForm) {\n return this.subForm.getValue();\n }\n return this.dataValue;\n }\n get errors() {\n let errors = super.errors;\n if (this.subForm) {\n errors = errors.concat(this.subForm.errors);\n }\n return errors;\n }\n updateSubFormVisibility() {\n if (this.subForm) {\n this.subForm.parentVisible = this.visible;\n }\n }\n /**\n * Determines if this form is a Nested Wizard\n * which means it should be a Wizard itself and should be a direct child of a Wizard's page\n * @returns {boolean} - TRUE if this form is a Nested Wizard, FALSE otherwise\n */\n get isNestedWizard() {\n var _a, _b, _c, _d, _e;\n return ((_b = (_a = this.subForm) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && ((_e = (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d._form) === null || _e === void 0 ? void 0 : _e.display) === 'wizard';\n }\n get visible() {\n return super.visible;\n }\n set visible(value) {\n const isNestedWizard = this.isNestedWizard;\n if (this._visible !== value) {\n this._visible = value;\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n this.clearOnHide();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.clearOnHide();\n isNestedWizard ? this.rebuild() : this.redraw();\n }\n if (!value && isNestedWizard) {\n this.root.redraw();\n }\n }\n get parentVisible() {\n return super.parentVisible;\n }\n set parentVisible(value) {\n if (this._parentVisible !== value) {\n this._parentVisible = value;\n this.clearOnHide();\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.redraw();\n }\n }\n isInternalEvent(event) {\n switch (event) {\n case 'focus':\n case 'blur':\n case 'componentChange':\n case 'componentError':\n case 'error':\n case 'formLoad':\n case 'languageChanged':\n case 'render':\n case 'checkValidity':\n case 'initialized':\n case 'submit':\n case 'submitButton':\n case 'nosubmit':\n case 'updateComponent':\n case 'submitDone':\n case 'submissionDeleted':\n case 'requestDone':\n case 'nextPage':\n case 'prevPage':\n case 'wizardNavigationClicked':\n case 'updateWizardNav':\n case 'restoreDraft':\n case 'saveDraft':\n case 'saveComponent':\n case 'pdfUploaded':\n return true;\n default:\n return false;\n }\n }\n createEmitter() {\n const emitter = new eventemitter3_1.default();\n const nativeEmit = emitter.emit;\n const that = this;\n emitter.emit = function (event, ...args) {\n const eventType = event.replace(`${that.options.namespace}.`, '');\n nativeEmit.call(this, event, ...args);\n if (!that.isInternalEvent(eventType)) {\n that.emit(eventType, ...args);\n }\n };\n return emitter;\n }\n deleteValue() {\n super.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n}\nexports[\"default\"] = FormComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/form/Form.js?");
5219
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* eslint-disable max-statements */\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../_classes/componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nclass FormComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'Form',\n type: 'form',\n key: 'form',\n src: '',\n reference: true,\n form: '',\n path: '',\n tableView: true,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Nested Form',\n icon: 'wpforms',\n group: 'premium',\n documentation: '/userguide/form-building/premium-components#nested-form',\n weight: 110,\n schema: FormComponent.schema()\n };\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.object];\n }\n init() {\n super.init();\n this.formObj = {\n display: this.component.display,\n settings: this.component.settings,\n components: this.component.components\n };\n this.valueChanged = false;\n this.subForm = null;\n this.formSrc = '';\n if (this.component.src) {\n this.formSrc = this.component.src;\n }\n if (!this.component.src &&\n !this.options.formio &&\n (this.component.form || this.component.path)) {\n if (this.component.project) {\n this.formSrc = Formio_1.Formio.getBaseUrl();\n // Check to see if it is a MongoID.\n if ((0, utils_1.isMongoId)(this.component.project)) {\n this.formSrc += '/project';\n }\n this.formSrc += `/${this.component.project}`;\n this.options.project = this.formSrc;\n }\n else {\n this.formSrc = Formio_1.Formio.getProjectUrl();\n this.options.project = this.formSrc;\n }\n if (this.component.form) {\n if ((0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc += `/form/${this.component.form}`;\n }\n else {\n this.formSrc += `/${this.component.form}`;\n }\n }\n else if (this.component.path) {\n this.formSrc += `/${this.component.path}`;\n }\n }\n // Build the source based on the root src path.\n if (!this.formSrc && this.options.formio) {\n const rootSrc = this.options.formio.formsUrl;\n if (this.component.form && (0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc = `${rootSrc}/${this.component.form}`;\n }\n else {\n const formPath = this.component.path || this.component.form;\n this.formSrc = `${rootSrc.replace(/\\/form$/, '')}/${formPath}`;\n }\n }\n if (this.builderMode && this.component.hasOwnProperty('formRevision')) {\n this.component.revision = this.component.formRevision;\n delete this.component.formRevision;\n }\n // Add revision version if set.\n if (this.component.revision || this.component.revision === 0 ||\n this.component.formRevision || this.component.formRevision === 0\n || this.component.revisionId) {\n this.setFormRevision(this.component.revisionId || this.component.revision || this.component.formRevision);\n }\n return this.createSubForm();\n }\n get dataReady() {\n return this.subFormReady || Promise.resolve();\n }\n get defaultValue() {\n // Not not provide a default value unless the subform is ready so that it will initialize correctly.\n return this.subForm ? super.defaultValue : null;\n }\n get defaultSchema() {\n return FormComponent.schema();\n }\n get emptyValue() {\n return { data: {} };\n }\n get ready() {\n return this.subFormReady || Promise.resolve();\n }\n get useOriginalRevision() {\n var _a, _b;\n return ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && !!((_b = this.formObj) === null || _b === void 0 ? void 0 : _b.revisions);\n }\n setFormRevision(rev) {\n // Remove current revisions from src if it is\n this.formSrc = this.formSrc.replace(/\\/v\\/[0-9a-z]+/, '');\n const revNumber = Number.parseInt(rev);\n if (!isNaN(revNumber)) {\n this.subFormRevision = rev;\n this.formSrc += `/v/${rev}`;\n }\n else {\n this.subFormRevision = undefined;\n }\n }\n getComponent(path) {\n if (!this.subForm) {\n return null;\n }\n return this.subForm.getComponent(path);\n }\n /* eslint-disable max-statements */\n getSubOptions(options = {}) {\n options.events = this.createEmitter();\n // Make sure to not show the submit button in wizards in the nested forms.\n lodash_1.default.set(options, 'buttonSettings.showSubmit', false);\n if (!this.options) {\n return options;\n }\n if (this.options.base) {\n options.base = this.options.base;\n }\n if (this.options.project) {\n options.project = this.options.project;\n }\n if (this.options.readOnly || this.component.disabled) {\n options.readOnly = this.options.readOnly || this.component.disabled;\n }\n if (this.options.breadcrumbSettings) {\n options.breadcrumbSettings = this.options.breadcrumbSettings;\n }\n if (this.options.buttonSettings) {\n options.buttonSettings = lodash_1.default.clone(this.options.buttonSettings);\n }\n if (this.options.viewAsHtml) {\n options.viewAsHtml = this.options.viewAsHtml;\n }\n if (this.options.language) {\n options.language = this.options.language;\n }\n if (this.options.template) {\n options.template = this.options.template;\n }\n if (this.options.templates) {\n options.templates = this.options.templates;\n }\n if (this.options.renderMode) {\n options.renderMode = this.options.renderMode;\n }\n if (this.options.attachMode) {\n options.attachMode = this.options.attachMode;\n }\n if (this.options.iconset) {\n options.iconset = this.options.iconset;\n }\n if (this.options.fileService) {\n options.fileService = this.options.fileService;\n }\n if (this.options.onChange) {\n options.onChange = this.options.onChange;\n }\n if (this.options.preview) {\n options.preview = this.options.preview;\n }\n if (this.options.inEditGrid) {\n options.inEditGrid = this.options.inEditGrid;\n }\n if (this.options.saveDraft) {\n options.saveDraft = this.options.saveDraft;\n options.formio = new Formio_1.Formio(this.formSrc);\n }\n if (this.options.saveDraftThrottle) {\n options.saveDraftThrottle = this.options.saveDraftThrottle;\n }\n if (this.options.skipDraftRestore) {\n options.skipDraftRestore = this.options.skipDraftRestore;\n }\n options.parent = this;\n return options;\n }\n /* eslint-enable max-statements */\n render() {\n if (this.builderMode) {\n return super.render(this.component.label || 'Nested form');\n }\n const subform = this.subForm ? this.subForm.render() : this.renderTemplate('loading');\n return super.render(subform);\n }\n asString(value) {\n return this.getValueAsString(value);\n }\n /**\n * Prints out the value of form components as a datagrid value.\n */\n getValueAsString(value, options) {\n if (!value) {\n return 'No data provided';\n }\n if (!value.data && value._id) {\n return value._id;\n }\n if (!value.data || !Object.keys(value.data).length) {\n return 'No data provided';\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n return '[Complex Data]';\n }\n attach(element) {\n // Don't attach in builder.\n if (this.builderMode) {\n return super.attach(element);\n }\n return super.attach(element)\n .then(() => {\n if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {\n this.createSubForm(true);\n }\n return this.subFormReady.then(() => {\n this.empty(element);\n if (this.options.builder) {\n this.setContent(element, this.ce('div', {\n class: 'text-muted text-center p-2'\n }, this.text(this.formObj.title)));\n return;\n }\n this.setContent(element, this.render());\n if (this.subForm) {\n if (this.isNestedWizard) {\n element = this.root.element;\n }\n this.subForm.attach(element);\n this.valueChanged = this.hasSetValue;\n if (!this.valueChanged && this.dataValue.state !== 'submitted') {\n this.setDefaultValue();\n }\n else {\n this.restoreValue();\n }\n }\n if (!this.builderMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n this.componentModal = new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;\n this.setOpenModalElement();\n }\n this.calculateValue();\n });\n });\n }\n detach() {\n if (this.subForm) {\n this.subForm.detach();\n }\n super.detach();\n }\n get currentForm() {\n return this._currentForm;\n }\n get hasLoadedForm() {\n return this.formObj\n && this.formObj.components\n && Array.isArray(this.formObj.components)\n && this.formObj.components.length;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n if (!this.subForm) {\n return;\n }\n this.subForm.getComponents().forEach(component => {\n component.currentForm = this;\n });\n }\n get isRevisionChanged() {\n return lodash_1.default.isNumber(this.subFormRevision)\n && lodash_1.default.isNumber(this.formObj._vid)\n && this.formObj._vid !== this.subFormRevision;\n }\n destroy(all = false) {\n if (this.subForm) {\n this.subForm.destroy(all);\n this.subForm = null;\n this.subFormReady = null;\n }\n super.destroy(all);\n }\n redraw() {\n if (this.subForm) {\n this.subForm.form = this.formObj;\n this.setSubFormDisabled(this.subForm);\n }\n return super.redraw();\n }\n /**\n * Pass everyComponent to subform.\n * @param {any[]} args - Arguments to pass through to the subform's everyComponent method.\n * @returns {*} - The result of the subform's everyComponent method.\n */\n everyComponent(...args) {\n if (this.subForm) {\n this.subForm.everyComponent(...args);\n }\n }\n setSubFormDisabled(subForm) {\n subForm.disabled = this.disabled; // When the Nested Form is disabled make the subForm disabled\n }\n updateSubWizards(subForm) {\n var _a, _b;\n if (this.isNestedWizard && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.subWizards) && ((_b = subForm === null || subForm === void 0 ? void 0 : subForm._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard') {\n const existedForm = this.root.subWizards.findIndex(form => form.component.form === this.component.form);\n if (existedForm !== -1) {\n this.root.subWizards[existedForm] = this;\n }\n else {\n this.root.subWizards.push(this);\n }\n this.emit('subWizardsUpdated', subForm);\n }\n }\n /**\n * Create a subform instance.\n * @param {boolean} [fromAttach] - This function is being called from an `attach` method.\n * @returns {*} - The subform instance.\n */\n createSubForm(fromAttach) {\n this.subFormReady = this.loadSubForm(fromAttach).then((form) => {\n if (!form) {\n return;\n }\n // Iterate through every component and hide the submit button.\n (0, utils_1.eachComponent)(form.components, (component) => {\n this.hideSubmitButton(component);\n });\n // If the subform is already created then destroy the old one.\n if (this.subForm) {\n this.subForm.destroy();\n }\n // Render the form.\n return (new Form_1.default(form, this.getSubOptions())).ready.then((instance) => {\n this.subForm = instance;\n this.subForm.currentForm = this;\n const componentsMap = this.componentsMap;\n const formComponentsMap = this.subForm.componentsMap;\n lodash_1.default.assign(componentsMap, formComponentsMap);\n this.component.components = this.subForm.components.map((comp) => comp.component);\n this.subForm.parent = this;\n this.subForm.parentVisible = this.visible;\n this.subForm.on('change', () => {\n if (this.subForm) {\n this.dataValue = this.subForm.getValue();\n this.triggerChange({\n noEmit: true\n });\n }\n });\n this.subForm.url = this.formSrc;\n this.subForm.nosubmit = true;\n this.subForm.root = this.root;\n this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;\n this.restoreValue();\n this.valueChanged = this.hasSetValue;\n this.onChange();\n return this.subForm;\n }).catch((err) => {\n console.log(err);\n });\n }).then((subForm) => {\n this.updateSubWizards(subForm);\n return subForm;\n });\n return this.subFormReady;\n }\n hideSubmitButton(component) {\n const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);\n if (isSubmitButton) {\n component.hidden = true;\n // clearOnHide no longer clears from the JSON `hidden` flag, so we make the button conditionally hidden to clear its data\n component.customConditional = 'show = false';\n }\n }\n /**\n * Load the subform.\n * @param {boolean} fromAttach - This function is being called from an `attach` method.\n * @returns {Promise} - The promise that resolves when the subform is loaded.\n */\n loadSubForm(fromAttach) {\n var _a, _b, _c, _d, _e;\n if (this.builderMode || this.conditionallyHidden || (this.isSubFormLazyLoad() && !fromAttach)) {\n return Promise.resolve();\n }\n if (this.hasLoadedForm && !this.isRevisionChanged &&\n !(this.options.pdf && ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && lodash_1.default.isNull(this.subForm) && !this.subFormLoading)) {\n // Pass config down to sub forms.\n if (this.root && this.root.form && this.root.form.config && !this.formObj.config) {\n this.formObj.config = this.root.form.config;\n }\n return Promise.resolve(this.formObj);\n }\n else if (this.formSrc) {\n this.subFormLoading = true;\n const options = ((_c = (_b = this.root) === null || _b === void 0 ? void 0 : _b.formio) === null || _c === void 0 ? void 0 : _c.base) && ((_e = (_d = this.root) === null || _d === void 0 ? void 0 : _d.formio) === null || _e === void 0 ? void 0 : _e.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n return (new Formio_1.Formio(this.formSrc, options)).loadForm({ params: { live: 1 } })\n .then((formObj) => {\n this.formObj = formObj;\n if (this.options.pdf && this.component.useOriginalRevision) {\n this.formObj.display = 'form';\n }\n this.subFormLoading = false;\n return formObj;\n })\n .catch((err) => {\n console.log(err);\n return null;\n });\n }\n return Promise.resolve();\n }\n checkComponentConditions(data, flags, row) {\n const visible = super.checkComponentConditions(data, flags, row);\n // Return if already hidden\n if (!visible) {\n return visible;\n }\n if (this.subForm) {\n return this.subForm.checkConditions(data, flags, row);\n }\n // There are few cases when subForm is not loaded when a change is triggered,\n // so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode\n else if (this.subFormReady) {\n this.subFormReady.then(() => {\n if (this.subForm) {\n return this.subForm.checkConditions(data, flags, row);\n }\n });\n }\n return visible;\n }\n calculateValue(data, flags, row) {\n if (this.subForm) {\n return this.subForm.calculateValue(data, flags, row);\n }\n return super.calculateValue(data, flags, row);\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n if (this.subForm) {\n this.subForm.setPristine(pristine);\n }\n }\n /**\n * Determine if the subform should be submitted.\n * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.\n */\n get shouldSubmit() {\n return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.conditionallyHidden;\n }\n /**\n * Returns the data for the subform.\n * @returns {*} - the data for the subform.\n */\n getSubFormData() {\n if (lodash_1.default.get(this.subForm, 'form.display') === 'pdf') {\n return this.subForm.getSubmission();\n }\n else {\n return Promise.resolve(this.dataValue);\n }\n }\n /**\n * Submit the subform if configured to do so.\n * @returns {Promise} - The promise that resolves when the subform is submitted.\n */\n submitSubForm() {\n // If we wish to submit the form on next page, then do that here.\n if (this.shouldSubmit) {\n return this.subFormReady.then(() => {\n if (!this.subForm) {\n return this.dataValue;\n }\n this.subForm.nosubmit = false;\n this.subForm.submitted = true;\n return this.subForm.submitForm({}, true).then(result => {\n this.subForm.loading = false;\n this.subForm.showAllErrors = false;\n this.dataValue = result.submission;\n return this.dataValue;\n }).catch(err => {\n this.subForm.showAllErrors = true;\n this.subForm.onSubmissionError(err);\n return Promise.reject(err);\n });\n });\n }\n return this.getSubFormData();\n }\n /**\n * Submit the form before the next page is triggered.\n * @param {Function} next - The function to trigger the next page.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the next page is triggered.\n */\n beforePage(next) {\n // Should not submit child forms if we are going to the previous page\n if (!next) {\n return super.beforePage(next);\n }\n return this.submitSubForm(true).then(() => super.beforePage(next));\n }\n /**\n * Submit the form before the whole form is triggered.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the form is submitted.\n */\n beforeSubmit() {\n var _a, _b, _c;\n const submission = this.dataValue;\n // Cancel triggered saveDraft\n if (((_a = this.subForm) === null || _a === void 0 ? void 0 : _a.draftEnabled) && ((_b = this.subForm.triggerSaveDraft) === null || _b === void 0 ? void 0 : _b.cancel)) {\n this.subForm.triggerSaveDraft.cancel();\n }\n const isAlreadySubmitted = submission && submission._id && submission.form;\n const isDraftSubmission = this.options.saveDraft && submission.state === 'draft';\n // This submission has already been submitted, so just return the reference data.\n if (isAlreadySubmitted && !((_c = this.subForm) === null || _c === void 0 ? void 0 : _c.wizard) && !isDraftSubmission) {\n this.dataValue = submission;\n return Promise.resolve(this.dataValue);\n }\n return this.submitSubForm(false)\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n isSubFormLazyLoad() {\n var _a, _b;\n return ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && this.component.lazyLoad;\n }\n isHidden() {\n if (!this.visible) {\n return true;\n }\n return !super.checkConditions(this.rootValue);\n }\n setValue(submission, flags = {}) {\n var _a;\n const changed = super.setValue(submission, flags);\n this.valueChanged = true;\n if (this.subForm) {\n const revisionPath = submission._frid ? '_frid' : '_vid';\n const shouldLoadOriginalRevision = this.useOriginalRevision\n && (lodash_1.default.isNumber(submission[revisionPath]) || lodash_1.default.isNumber(submission._fvid))\n && lodash_1.default.isNumber((_a = this.subForm.form) === null || _a === void 0 ? void 0 : _a[revisionPath])\n && submission._fvid !== this.subForm.form[revisionPath];\n if (shouldLoadOriginalRevision) {\n this.setFormRevision(submission._frid || submission._fvid);\n this.createSubForm().then(() => {\n this.attach(this.element);\n });\n }\n else {\n this.setSubFormValue(submission, flags);\n }\n }\n return changed;\n }\n setSubFormValue(submission, flags) {\n var _a, _b, _c, _d;\n const shouldLoadSubmissionById = submission\n && submission._id\n && this.subForm.formio\n && lodash_1.default.isEmpty(submission.data);\n const shouldLoadDraftById = this.options.saveDraft && lodash_1.default.isEmpty(submission.data) && lodash_1.default.get(this.subForm, 'submission._id');\n if (shouldLoadSubmissionById || shouldLoadDraftById) {\n const formId = submission.form || this.formObj.form || this.component.form;\n const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;\n const options = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.formio) === null || _b === void 0 ? void 0 : _b.base) && ((_d = (_c = this.root) === null || _c === void 0 ? void 0 : _c.formio) === null || _d === void 0 ? void 0 : _d.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n this.subForm.setUrl(submissionUrl, Object.assign(Object.assign({}, this.options), options));\n this.subForm.loadSubmission().catch((err) => {\n console.error(`Unable to load subform submission ${submission._id}:`, err);\n });\n }\n else {\n this.onSetSubFormValue(submission, flags);\n }\n }\n /**\n * Sets the subform value\n * @param {object|null|undefined} submission - The submission to set.\n * @param {object|null|undefined} flags - Any flags to apply when setting the submission.\n * @returns {void}\n */\n onSetSubFormValue(submission, flags) {\n this.subForm.setValue(submission, flags);\n }\n isEmpty(value = this.dataValue) {\n return value === null || lodash_1.default.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value === null || value === void 0 ? void 0 : value.data) && !(value === null || value === void 0 ? void 0 : value._id));\n }\n areAllComponentsEmpty(data) {\n let res = true;\n if (this.subForm) {\n this.subForm.everyComponent((comp) => {\n const componentValue = lodash_1.default.get(data, comp.key);\n res &= comp.isEmpty(componentValue);\n });\n }\n else {\n res = false;\n }\n return res;\n }\n getValue() {\n if (this.subForm) {\n return this.subForm.getValue();\n }\n return this.dataValue;\n }\n get errors() {\n let errors = super.errors;\n if (this.subForm) {\n errors = errors.concat(this.subForm.errors);\n }\n return errors;\n }\n updateSubFormVisibility() {\n if (this.subForm) {\n this.subForm.parentVisible = this.visible;\n }\n }\n /**\n * Determines if this form is a Nested Wizard\n * which means it should be a Wizard itself and should be a direct child of a Wizard's page\n * @returns {boolean} - TRUE if this form is a Nested Wizard, FALSE otherwise\n */\n get isNestedWizard() {\n var _a, _b, _c, _d, _e;\n return ((_b = (_a = this.subForm) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && ((_e = (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d._form) === null || _e === void 0 ? void 0 : _e.display) === 'wizard';\n }\n get visible() {\n return super.visible;\n }\n set visible(value) {\n const isNestedWizard = this.isNestedWizard;\n if (this._visible !== value) {\n this._visible = value;\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n this.clearOnHide();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.clearOnHide();\n isNestedWizard ? this.rebuild() : this.redraw();\n }\n if (!value && isNestedWizard) {\n this.root.redraw();\n }\n }\n get parentVisible() {\n return super.parentVisible;\n }\n set parentVisible(value) {\n if (this._parentVisible !== value) {\n this._parentVisible = value;\n this.clearOnHide();\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.redraw();\n }\n }\n isInternalEvent(event) {\n switch (event) {\n case 'focus':\n case 'blur':\n case 'componentChange':\n case 'componentError':\n case 'error':\n case 'formLoad':\n case 'languageChanged':\n case 'render':\n case 'checkValidity':\n case 'initialized':\n case 'submit':\n case 'submitButton':\n case 'nosubmit':\n case 'updateComponent':\n case 'submitDone':\n case 'submissionDeleted':\n case 'requestDone':\n case 'nextPage':\n case 'prevPage':\n case 'wizardNavigationClicked':\n case 'updateWizardNav':\n case 'restoreDraft':\n case 'saveDraft':\n case 'saveComponent':\n case 'pdfUploaded':\n return true;\n default:\n return false;\n }\n }\n createEmitter() {\n const emitter = new eventemitter3_1.default();\n const nativeEmit = emitter.emit;\n const that = this;\n emitter.emit = function (event, ...args) {\n const eventType = event.replace(`${that.options.namespace}.`, '');\n nativeEmit.call(this, event, ...args);\n if (!that.isInternalEvent(eventType)) {\n that.emit(eventType, ...args);\n }\n };\n return emitter;\n }\n deleteValue() {\n super.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n}\nexports[\"default\"] = FormComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/form/Form.js?");
5220
5220
 
5221
5221
  /***/ }),
5222
5222