UNPKG

survey-analytics

Version:

SurveyJS analytics Library.

1,108 lines (1,097 loc) 545 kB
/*! * surveyjs - SurveyJS Dashboard library v2.0.3 * Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ import { D as DocumentHelper, l as localization, e as createImagesContainer, f as createLinksContainer, b as createCommercialLicenseLink, s as svgTemplate } from './shared.mjs'; export { d as surveyStrings } from './shared.mjs'; import { ItemValue, settings, hasLicense, Serializer, EventBase, Event } from 'survey-core'; import { TabulatorFull } from 'tabulator-tables'; class TableExtensions { constructor(table) { this.table = table; this.renderedExtensions = []; } render(targetNode, location, options) { var extensions = TableExtensions.extensions[location]; if (!!extensions) { extensions = this.sortExtensions(extensions); extensions.forEach((extension) => { if (!!extension.render && this.table.allowExtension(extension)) { var action = extension.render(this.table, options); if (!!action) { targetNode.appendChild(action); this.renderedExtensions.push(extension); } } }); } } destroy() { this.renderedExtensions.forEach((extension) => { if (!!extension.destroy) extension.destroy(); }); this.renderedExtensions = []; } static registerExtension(extension) { if (!this.extensions[extension.location]) this.extensions[extension.location] = []; this.extensions[extension.location].push(extension); } static removeExtension(extension) { if (!extension) { return; } const extensions = TableExtensions.extensions[extension.location]; const index = extensions.indexOf(extension); if (index >= 0) { extensions.splice(index, 1); } } static unregisterExtension(location, actionName) { if (!actionName) { return; } if (!!location) { const extension = TableExtensions.findExtension(location, actionName); TableExtensions.removeExtension(extension); } else { Object.keys(this.extensions).forEach((location) => TableExtensions.unregisterExtension(location, actionName)); } } static findExtension(location, actionName) { if (!this.extensions[location]) return null; var extension = this.extensions[location].filter(function (extension) { return extension.name == actionName; })[0]; return extension || null; } sortExtensions(extensions) { if (!Array.isArray(extensions)) return; return [] .concat(extensions.filter((extension) => extension.visibleIndex >= 0)) .sort((firstExtension, secondExtension) => { return firstExtension.visibleIndex - secondExtension.visibleIndex; }); } } TableExtensions.extensions = {}; TableExtensions.registerExtension({ location: "row", name: "details", visibleIndex: 0, render: (_table, options) => { const btn = DocumentHelper.createSvgButton("detail"); btn.title = localization.getString("showMinorColumns"); btn.className += " sa-table__row-extension"; btn.onclick = () => { options.row.toggleDetails(); }; return btn; }, }); TableExtensions.registerExtension({ location: "row", name: "select", visibleIndex: -1, render: function (_table, opt) { var row = opt.row; var checkbox = DocumentHelper.createElement("input", "sa-table__row-extension", { type: "checkbox", }); checkbox.checked = row.getIsSelected(); checkbox.onchange = function () { row.toggleSelect(); }; return checkbox; }, }); TableExtensions.registerExtension({ location: "header", name: "filter", visibleIndex: 0, render: function (table) { const input = DocumentHelper.createInput("sa-table__global-filter sa-table__header-extension", localization.getString("filterPlaceholder")); input.onchange = (event) => { table.applyFilter(event.target.value); }; return input; }, }); TableExtensions.registerExtension({ location: "header", name: "showcolumn", visibleIndex: 2, destroy: function () { this.onDestroy(); }, render: function (table) { const dropdown = DocumentHelper.createElement("select", "sa-table__show-column sa-table__header-extension"); function update() { var hiddenColumns = table.columns.filter((column) => !column.isVisible); if (hiddenColumns.length == 0) { dropdown.style.display = "none"; return; } dropdown.style.display = "inline-block"; dropdown.innerHTML = ""; var option = DocumentHelper.createElement("option", "", { text: localization.getString("showColumn"), disabled: true, selected: true, }); dropdown.appendChild(option); hiddenColumns.forEach((column) => { var text = column.displayName || column.name; if (!!text && text.length > 20) { text = text.substring(0, 20) + "..."; } var option = DocumentHelper.createElement("option", "", { text: text, title: column.displayName, value: column.name, }); dropdown.appendChild(option); }); } dropdown.onchange = (e) => { const val = e.target.value; e.stopPropagation(); if (!val) return; table.setColumnVisibility(val, true); }; update(); var onVisibilityChangedCallback = () => { update(); }; table.onColumnsVisibilityChanged.add(onVisibilityChangedCallback); this.onDestroy = () => { table.onColumnsVisibilityChanged.remove(onVisibilityChangedCallback); }; return dropdown; }, }); TableExtensions.registerExtension({ location: "header", name: "showentries", visibleIndex: 3, render: function (table) { function getEntriesDropdown(table) { const el = DocumentHelper.createElement("select"); var optionsValues = table.paginationSizeSelector || ["1", "5", "10", "25", "50", "75", "100"]; optionsValues.forEach(function (val) { var option = DocumentHelper.createElement("option", "", { value: val, text: val, }); el.appendChild(option); }); el.value = String(table.getPageSize()); el.onchange = () => { table.setPageSize(Number(el.value)); }; return el; } const selectorContainer = DocumentHelper.createElement("div", "sa-table__entries"); const spaceSpan = DocumentHelper.createElement("span", "sa-table__header-space"); const showSpan = DocumentHelper.createElement("span", "sa-table__entries-label sa-table__entries-label--right", { innerText: localization.getString("showLabel"), }); const entriesSpan = DocumentHelper.createElement("span", "sa-table__entries-label sa-table__entries-label--left", { innerText: localization.getString("entriesLabel"), }); selectorContainer.appendChild(spaceSpan); selectorContainer.appendChild(showSpan); selectorContainer.appendChild(getEntriesDropdown(table)); selectorContainer.appendChild(entriesSpan); return selectorContainer; }, }); TableExtensions.registerExtension({ location: "header", name: "removerows", visibleIndex: -1, render: function (table) { var btn = DocumentHelper.createElement("button", "sa-table__btn sa-table__btn--green sa-table__header-extension ", { innerText: localization.getString("removeRows") }); btn.onclick = function () { table.getCreatedRows().forEach(function (row) { if (row.getIsSelected()) { row.remove(); } }); }; return btn; }, }); TableExtensions.registerExtension({ location: "header", name: "changelocale", visibleIndex: 1, render: function (table) { var locales = table.getLocales(); if (table.options.disableLocaleSwitch || locales.length < 2) return null; const el = (DocumentHelper.createElement("select", "sa-table__header-extension", {})); var optionsValues = [localization.getString("changeLocale")].concat(locales); optionsValues.forEach(function (val) { var option = DocumentHelper.createElement("option", "", { value: val, text: localization.localeNames[val] || localization.getString(val) || val, }); el.appendChild(option); }); el.onchange = () => { table.locale = el.value; }; return el; }, }); var QuestionLocation; (function (QuestionLocation) { QuestionLocation[QuestionLocation["Column"] = 0] = "Column"; QuestionLocation[QuestionLocation["Row"] = 1] = "Row"; })(QuestionLocation || (QuestionLocation = {})); var ColumnDataType; (function (ColumnDataType) { ColumnDataType[ColumnDataType["Text"] = 0] = "Text"; ColumnDataType[ColumnDataType["FileLink"] = 1] = "FileLink"; ColumnDataType[ColumnDataType["Image"] = 2] = "Image"; })(ColumnDataType || (ColumnDataType = {})); TableExtensions.registerExtension({ location: "column", name: "drag", visibleIndex: 0, render: function (table, options) { const btn = DocumentHelper.createElement("button", "sa-table__svg-button sa-table__drag-button"); btn.appendChild(DocumentHelper.createSvgElement("drag")); btn.onmousedown = (e) => { table.enableColumnReorder(); }; return btn; }, }); TableExtensions.registerExtension({ location: "column", name: "sort", visibleIndex: 1, render: function (table, options) { const descTitle = localization.getString("descOrder"); const ascTitle = localization.getString("ascOrder"); var btn = DocumentHelper.createSvgButton("sorting"); btn.title = ""; var direction = "asc"; btn.onclick = () => { if (direction == "asc") { btn.title = descTitle; direction = "desc"; } else { btn.title = ascTitle; direction = "asc"; } table.sortByColumn(options.columnName, direction); }; btn.ondrag = (e) => { e.stopPropagation(); }; return btn; }, }); TableExtensions.registerExtension({ location: "column", name: "hide", visibleIndex: 2, render: function (table, options) { var btn = DocumentHelper.createSvgButton("hide"); btn.title = localization.getString("hideColumn"); btn.onclick = () => { table.setColumnVisibility(options.columnName, false); }; return btn; }, }); TableExtensions.registerExtension({ location: "column", name: "movetodetails", visibleIndex: 3, render: function (table, options) { const button = DocumentHelper.createSvgButton("movetodetails"); button.title = localization.getString("moveToDetail"); button.onclick = (e) => { e.stopPropagation(); table.setColumnLocation(options.columnName, QuestionLocation.Row); }; return button; }, }); TableExtensions.registerExtension({ location: "column", name: "filter", visibleIndex: 4, render: function (table, options) { var el = DocumentHelper.createInput("sa-table__filter", localization.getString("filterPlaceholder")); el.onclick = (e) => e.stopPropagation(); el.onchange = (e) => { table.applyColumnFilter(options.columnName, el.value); }; return el; }, }); TableExtensions.registerExtension({ location: "column", name: "makepublic", visibleIndex: -1, render: function (table, options) { const button = DocumentHelper.createElement("button"); const makePrivateSvg = DocumentHelper.createSvgElement("makeprivate"); const makePublicSvg = DocumentHelper.createSvgElement("makepublic"); const column = table.getColumnByName(options.columnName); updateState(column); button.appendChild(makePrivateSvg); button.appendChild(makePublicSvg); button.onclick = (e) => { e.stopPropagation(); column.isPublic = !column.isPublic; updateState(column); table.onPermissionsChangedCallback && table.onPermissionsChangedCallback(table); }; function updateState(column) { if (column.isPublic) { button.className = "sa-table__svg-button"; button.title = localization.getString("makePrivateColumn"); makePrivateSvg.style.display = "none"; makePublicSvg.style.display = "block"; } else { button.className = "sa-table__svg-button sa-table__svg-button--active"; button.title = localization.getString("makePublicColumn"); makePrivateSvg.style.display = "block"; makePublicSvg.style.display = "none"; } } return button; }, }); class Details { constructor(table, row, targetNode) { this.table = table; this.row = row; this.targetNode = targetNode; this.location = "details"; this.createShowAsColumnButton = (columnName) => { const button = DocumentHelper.createElement("button", "sa-table__btn sa-table__btn--gray"); button.appendChild(document.createTextNode(localization.getString("showAsColumn"))); button.onclick = (e) => { e.stopPropagation(); this.table.setColumnLocation(columnName, QuestionLocation.Column); }; return button; }; this.detailsTable = DocumentHelper.createElement("table", "sa-table__detail-table"); this.table.onColumnsLocationChanged.add(() => { this.close(); }); } open() { this.detailsTable.innerHTML = ""; var rows = []; this.table.columns .filter((column) => column.location === QuestionLocation.Row && column) .forEach((column) => { var row = DocumentHelper.createElement("tr", "sa-table__detail"); var td1 = DocumentHelper.createElement("td"); td1.appendChild(document.createTextNode(column.displayName)); var td2 = DocumentHelper.createElement("td"); td2.textContent = this.row.getRowData()[column.name]; if (column.dataType === ColumnDataType.Image) { td2.innerHTML = "<image src='" + td2.textContent + "'/>"; } var td3 = DocumentHelper.createElement("td"); td3.appendChild(this.createShowAsColumnButton(column.name)); row.appendChild(td1); row.appendChild(td2); row.appendChild(td3); rows.push(row); }); var row = DocumentHelper.createElement("tr", "sa-table__detail"); var td = DocumentHelper.createElement("td", "", { colSpan: 3 }); var extensions = new TableExtensions(this.table); extensions.render(td, "details", { row: this.row }); if (td.children.length != 0) { row.appendChild(td); rows.push(row); } rows.forEach((row) => { this.detailsTable.appendChild(row); }); this.targetNode.appendChild(this.detailsTable); } close() { if (!!this.detailsTable.parentNode) { this.detailsTable.parentNode.removeChild(this.detailsTable); } } } class BaseColumn { constructor(question, table) { this.question = question; this.table = table; this.isVisible = true; this.isPublic = true; this.location = QuestionLocation.Column; this.dataType = this.getDataType(); } get name() { if (!this.nameValue) { this.name = this.getName(); } return this.nameValue; } set name(val) { this.nameValue = val; } get displayName() { if (!this.displayNameValue) { this.displayName = this.getDisplayName(); } return this.displayNameValue; } set displayName(val) { this.displayNameValue = val; } getDisplayName() { return this.table.useNamesAsTitles ? this.question.name : (this.question.title || "").trim() || this.question.name; } getName() { return this.question.name; } getDataType() { return ColumnDataType.Text; } getDisplayValueCore(data) { return data[this.name]; } setupReadyChangedCallback(table, question) { if (!!question) { const onReadyChangedCallback = (sender, options) => { if (options.isReady) { table.refresh(!table.isInitTableDataProcessing); sender.onReadyChanged.remove(onReadyChangedCallback); } }; if (!question.isReady) { question.onReadyChanged.add(onReadyChangedCallback); } } } getDisplayValue(data, table, options) { let displayValue = this.getDisplayValueCore(data); const question = this.question; if (!!question) { if (options.useValuesAsLabels) { displayValue = question.value; } else { displayValue = question.displayValue; } } return displayValue; } formatDisplayValue(displayValue) { return typeof displayValue === "string" ? displayValue : JSON.stringify(displayValue) || ""; } getCellData(table, data) { const displayValue = this.getDisplayValue(data, table, table.options); this.setupReadyChangedCallback(table, this.question); return { question: this.question, displayValue: this.formatDisplayValue(displayValue) }; } toJSON() { return { name: this.name, displayName: this.displayName, dataType: this.dataType, isVisible: this.isVisible, isPublic: this.isPublic, location: this.location }; } fromJSON(data) { Object.keys(data).forEach(key => { this[key] = data[key]; }); } } class DefaultColumn extends BaseColumn { getDisplayValue(data, table, options) { return this.getDisplayValueCore(data); } } class CommentColumn extends BaseColumn { getName() { return `${this.question.name}${settings.commentPrefix}`; } getDisplayName() { return this.question.commentText; } getDisplayValue(data, table, options) { return this.question.comment; } } class OtherColumn extends CommentColumn { getDisplayName() { return this.question.otherText; } } class MatrixColumn extends BaseColumn { constructor(question, row, table) { var _a; super(question, table); this.row = row; this.valueName = this.question.name; this.valuePath = (_a = this.row) === null || _a === void 0 ? void 0 : _a.value; } getName() { var _a; return this.question.name + "." + ((_a = this.row) === null || _a === void 0 ? void 0 : _a.value); } getDisplayName() { const table = this.table; const question = this.question; const row = this.row; return (table.useNamesAsTitles ? question.name : (question.title || "").trim() || question.name) + " - " + (table.useNamesAsTitles ? row === null || row === void 0 ? void 0 : row.value : row === null || row === void 0 ? void 0 : row.locText.textOrHtml); } getDisplayValue(data, table, options) { let displayValue = data[this.valueName]; if (this.valuePath && typeof displayValue === "object") { displayValue = displayValue[this.valuePath]; if (displayValue !== undefined) { const choiceValue = ItemValue.getItemByValue(this.question.columns, displayValue); if (!!choiceValue) { displayValue = options.useValuesAsLabels ? choiceValue.value : choiceValue.locText.textOrHtml; } } } return displayValue; } } class ImageColumn extends BaseColumn { getDataType() { return ColumnDataType.Image; } } class FileColumn extends BaseColumn { getDataType() { return ColumnDataType.FileLink; } getDisplayValue(data, table, options) { let displayValue = this.getDisplayValueCore(data); if (Array.isArray(displayValue)) { displayValue = Table.showFilesAsImages ? createImagesContainer(displayValue).outerHTML : createLinksContainer(displayValue).outerHTML; } return displayValue; } } class MatrixDropdownColumn extends BaseColumn { constructor(question, row, col, table) { super(question, table); this.row = row; this.col = col; this.rowValue = this.row.value; this.colName = this.col.name; } getName() { return this.question.name + "." + this.row.value + "." + this.col.name; } getDisplayName() { const table = this.table; const question = this.question; return (this.table.useNamesAsTitles ? question.name : (question.title || "").trim() || question.name) + " - " + (table.useNamesAsTitles ? this.row.value : this.row.locText.textOrHtml) + " - " + (table.useNamesAsTitles ? this.col.name : this.col.locTitle.textOrHtml); } getDisplayValue(data, table, options) { let displayValue = data[this.question.name]; const question = this.question; if (this.rowValue && this.colName && typeof displayValue === "object") { let [rowId, colId] = [this.rowValue, this.colName]; displayValue = question.value; if (!options.useValuesAsLabels) { displayValue = question.displayValue; rowId = question.rows.filter(row => row.value === this.rowValue)[0].text; colId = question.getColumnByName(this.colName).title; } displayValue = (displayValue[rowId] && displayValue[rowId][colId]) || ""; } return displayValue; } } class CustomQuestionColumn extends BaseColumn { getCellData(table, data) { this.setupReadyChangedCallback(table, this.question.contentQuestion); return super.getCellData(table, data); } } class CompositeQuestionColumn extends BaseColumn { getCellData(table, data) { const questionList = []; this.question.contentPanel.addQuestionsToList(questionList); questionList.forEach((question) => { this.setupReadyChangedCallback(table, question); }); return super.getCellData(table, data); } } class DefaultColumnsBuilder { createColumn(question, table) { return new BaseColumn(question, table); } buildColumnsCore(question, table) { const columns = []; columns.push(this.createColumn(question, table)); return columns; } buildColumns(question, table) { const columns = this.buildColumnsCore(question, table); if (question.hasComment) { columns.push(new CommentColumn(question, table)); } if (question.hasOther && question["getStoreOthersAsComment"]()) { columns.push(new OtherColumn(question, table)); } return columns; } } class ColumnsBuilderFactory { constructor() { this.columnsBuilders = {}; this.defaultColumnsBuilder = new DefaultColumnsBuilder(); } registerBuilderColumn(type, columnsBuilder) { this.columnsBuilders[type] = columnsBuilder; } getColumnsBuilder(type) { return this.columnsBuilders[type] || this.defaultColumnsBuilder; } } ColumnsBuilderFactory.Instance = new ColumnsBuilderFactory(); class MatrixColumnsBuilder extends DefaultColumnsBuilder { buildColumnsCore(questionBase, table) { const question = questionBase; const columns = []; question.rows.forEach(row => { columns.push(new MatrixColumn(question, row, table)); }); return columns; } } ColumnsBuilderFactory.Instance.registerBuilderColumn("matrix", new MatrixColumnsBuilder()); class ImageColumnsBuilder extends DefaultColumnsBuilder { createColumn(question, table) { return new ImageColumn(question, table); } } ColumnsBuilderFactory.Instance.registerBuilderColumn("signaturepad", new ImageColumnsBuilder()); class FileColumnsBuilder extends DefaultColumnsBuilder { createColumn(question, table) { return new FileColumn(question, table); } } ColumnsBuilderFactory.Instance.registerBuilderColumn("file", new FileColumnsBuilder()); class MatrixDropdownColumnBuilder extends DefaultColumnsBuilder { buildColumns(questionBase, table) { const question = questionBase; const columns = []; question.rows.forEach(row => { question.columns.forEach(col => { columns.push(new MatrixDropdownColumn(question, row, col, table)); }); }); return columns; } } ColumnsBuilderFactory.Instance.registerBuilderColumn("matrixdropdown", new MatrixDropdownColumnBuilder()); class CustomColumnsBuilder extends DefaultColumnsBuilder { createColumn(question, table) { return new CustomQuestionColumn(question, table); } } ColumnsBuilderFactory.Instance.registerBuilderColumn("custom", new CustomColumnsBuilder()); class CompositeColumnsBuilder extends DefaultColumnsBuilder { createColumn(question, table) { return new CompositeQuestionColumn(question, table); } } ColumnsBuilderFactory.Instance.registerBuilderColumn("composite", new CompositeColumnsBuilder()); // export type GetDataFn = (params: { filter?: any, limit?: number, offset?: number, callback?: (response: { data: Array<Object>, total: number, error?: any }) => void }) => Promise<{ data: Array<Object>, total: number, error?: any }> | void; class TableEvent extends EventBase { } class Table { constructor(_survey, data, _options = {}, _columnsData = []) { this._survey = _survey; this.data = data; this._options = _options; this._columnsData = _columnsData; this.haveCommercialLicense = false; this.currentPageSize = 5; this._rows = []; /** * Sets pagination selector content. */ this.paginationSizeSelector = [1, 5, 10, 25, 50, 100]; this.onColumnsVisibilityChanged = new TableEvent(); this.onColumnsLocationChanged = new TableEvent(); this.onRowRemoved = new TableEvent(); this.buildColumns = (survey) => { let columns = []; this._survey.getAllQuestions().forEach((question) => { if (!this.isNonValueQuestion(question)) { const builder = ColumnsBuilderFactory.Instance.getColumnsBuilder(question.getTemplate()); columns = columns.concat(builder.buildColumns(question, this)); } }); return columns; }; /** * Fires when table state changed. */ this.onStateChanged = new TableEvent(); if (!this._options) { this._options = {}; } this._columns = this.buildColumns(_survey); this.initTableData(data); localization.currentLocale = this._survey.locale; this._columns = this.buildColumns(_survey); if (_columnsData.length !== 0) { this.updateColumnsFromData(this._columnsData); } this.extensions = new TableExtensions(this); const f = hasLicense; this.haveCommercialLicense = (!!f && f(4)) || Table.haveCommercialLicense || (!!_options && (typeof _options.haveCommercialLicense !== "undefined" ? _options.haveCommercialLicense : false)); } getTableData() { return [].concat(this.tableData || []); } getData() { return this.data; } get survey() { return this._survey; } get options() { return this._options; } render(targetNode) { if (typeof targetNode === "string") { targetNode = document.getElementById(targetNode); } targetNode.innerHTML = ""; if (!this.haveCommercialLicense) { targetNode.appendChild(createCommercialLicenseLink()); } } enableColumnReorder() { this.isColumnReorderEnabled = true; } disableColumnReorder() { this.isColumnReorderEnabled = false; } getPageNumber() { return this.currentPageNumber; } setPageNumber(value) { this.currentPageNumber = value; } /** * Returns current page size. */ getPageSize() { return this.currentPageSize; } /** * Sets current page size. */ setPageSize(value) { this.currentPageSize = value; this.onStateChanged.fire(this, this.state); } getCreatedRows() { return [].concat(this._rows); } clearCreatedRows() { this._rows.forEach((row) => { row.destroy(); }); this._rows = []; } get useNamesAsTitles() { return this._options && this._options.useNamesAsTitles === true; } isNonValueQuestion(question) { return Serializer.isDescendantOf(question.getType(), "nonvalue"); } isColumnVisible(column) { if (column.location !== QuestionLocation.Column) return false; return column.isVisible; } get columns() { return [].concat(this._columns); } set columns(columns) { this._columns = columns; this.refresh(true); this.onStateChanged.fire(this, this.state); } get isInitTableDataProcessing() { return this.isInitTableDataProcessingValue; } initTableData(data) { if (!Array.isArray(data)) { this.tableData = undefined; return; } this.isInitTableDataProcessingValue = true; this.tableData = (data || []).map((item) => this.processLoadedDataItem(item)); this.isInitTableDataProcessingValue = false; } processLoadedDataItem(item) { var dataItem = {}; this._survey.data = item; this._columns.forEach((column) => { const opt = column.getCellData(this, item); if (typeof this._options.onGetQuestionValue === "function") { this._options.onGetQuestionValue(opt); } dataItem[column.name] = opt.displayValue; }); return dataItem; } moveColumn(from, to) { var deletedColumns = this._columns.splice(from, 1); this._columns.splice(to, 0, deletedColumns[0]); this.onStateChanged.fire(this, this.state); } setColumnLocation(columnName, location) { this.getColumnByName(columnName).location = location; this.onColumnsLocationChanged.fire(this, { columnName: columnName, location: location, }); this.onStateChanged.fire(this, this.state); } getColumnByName(columnName) { return this._columns.filter((column) => column.name === columnName)[0]; } setColumnVisibility(columnName, isVisible) { var column = this.getColumnByName(columnName); column.isVisible = isVisible; this.onColumnsVisibilityChanged.fire(this, { columnName: columnName, columnVisibility: isVisible, }); this.onStateChanged.fire(this, this.state); } setColumnWidth(columnName, width) { var column = this.getColumnByName(columnName); column.width = width; this.onStateChanged.fire(this, this.state); } removeRow(row) { var index = this._rows.indexOf(row); this._rows.splice(index, 1); this.onRowRemoved.fire(this, { row: row }); } /** * Returns current locale of the table. * If locales more than one, the language selection dropdown will be added in the toolbar */ get locale() { return localization.currentLocale; } /** * Sets locale for table. */ set locale(newLocale) { this._survey.locale = newLocale; localization.currentLocale = newLocale; this.refresh(true); this.onStateChanged.fire(this, this.state); } getLocales() { return [].concat(this._survey.getUsedLocales()); } refresh(hard = false) { if (hard) { this.initTableData(this.data); } if (this.isRendered) { this.currentPageNumber = this.getPageNumber(); const targetNode = this.renderResult; this.destroy(); this.render(targetNode); this.setPageSize(this.currentPageSize); this.setPageNumber(this.currentPageNumber); } } destroy() { this.clearCreatedRows(); this.extensions.destroy(); this.renderResult.innerHTML = ""; this.renderResult = undefined; } get isRendered() { return !!this.renderResult; } /** * Vizualization panel state getter. */ get state() { return { locale: localization.currentLocale, elements: JSON.parse(JSON.stringify(this._columns)), pageSize: this.currentPageSize, }; } /** * Vizualization panel state setter. */ set state(newState) { if (!newState) return; if (typeof newState.locale !== "undefined") { localization.currentLocale = newState.locale; this._survey.locale = newState.locale; this.initTableData(this.data); } if (typeof newState.elements !== "undefined") this.updateColumnsFromData(newState.elements); if (typeof newState.pageSize !== "undefined") this.currentPageSize = newState.pageSize; } updateColumnsFromData(columnsData) { const columns = this._columns; columns.forEach(column => { const el = columnsData.filter(el => column.name === el.name)[0]; if (!!el) { column.fromJSON(el); column.visibleIndex = columnsData.indexOf(el); } }); columnsData.forEach(el => { let column = columns.filter(column => column.name === el.name)[0]; if (!column) { column = new DefaultColumn(undefined, this); column.fromJSON(el); column.visibleIndex = columnsData.indexOf(el); columns.push(column); } }); this._columns = this._columns.sort((col1, col2) => col1.visibleIndex - col2.visibleIndex); } /** * Gets table permissions. */ get permissions() { return this._columns.map((column) => { return { name: column.name, isPublic: column.isPublic, }; }); } /** * Sets table permissions. */ set permissions(permissions) { const updatedElements = this._columns.map((column) => { permissions.forEach((permission) => { if (permission.name === column.name) column.isPublic = permission.isPublic; }); return column; }); this._columns = [].concat(updatedElements); this.onPermissionsChangedCallback && this.onPermissionsChangedCallback(this); } get allowSorting() { return this.options.allowSorting === undefined || this.options.allowSorting === true; } allowExtension(extension) { if (extension.location === "column" && extension.name === "sort") { return this.allowSorting; } return true; } } Table.showFilesAsImages = false; Table.haveCommercialLicense = false; class TableRow { constructor(table, extensionsContainer, detailsContainer) { this.table = table; this.extensionsContainer = extensionsContainer; this.detailsContainer = detailsContainer; this.detailedRowClass = "sa-table__detail-row"; this.isDetailsExpanded = false; this.onToggleDetails = new Event(); this.onColumnLocationChangedCallback = () => { this.closeDetails(); }; this.details = new Details(table, this, detailsContainer); this.extensions = new TableExtensions(table); table.onColumnsLocationChanged.add(this.onColumnLocationChangedCallback); } render() { this.extensions.render(this.extensionsContainer, "row", { row: this }); } openDetails() { this.details.open(); this.getElement().className += " " + this.detailedRowClass; this.onToggleDetails.fire(this, { isExpanded: true }); this.isDetailsExpanded = true; } closeDetails() { this.details.close(); this.getElement().classList.remove(this.detailedRowClass); this.onToggleDetails.fire(this, { isExpanded: false }); this.isDetailsExpanded = false; } toggleDetails() { if (this.isDetailsExpanded) { this.closeDetails(); } else this.openDetails(); } getIsSelected() { return this.isSelected; } toggleSelect() { this.isSelected = !this.isSelected; } remove() { this.table.removeRow(this); this.destroy(); } destroy() { this.table.onColumnsLocationChanged.remove(this.onColumnLocationChangedCallback); this.extensions.destroy(); } } const ARIAL_FONT = "AAEAAAAXAQAABABwRFNJRyQ9+ecABX+MAAAafEdERUZeI11yAAV1GAAAAKZHU1VC1fDdzAAFdcAAAAmqSlNURm0qaQYABX9sAAAAHkxUU0iAZfo8AAAceAAABo5PUy8yDN8yawAAAfgAAABWUENMVP17PkMABXTgAAAANlZETVhQkmr1AAAjCAAAEZRjbWFw50BqOgAA0cQAABdqY3Z0IJYq0nYAAPqgAAAGMGZwZ23MeVmaAADpMAAABm5nYXNwABgACQAFdNAAAAAQZ2x5Zg73j+wAARr8AAPnYmhkbXi+u8OXAAA0nAAAnShoZWFkzpgmkgAAAXwAAAA2aGhlYRIzEv8AAAG0AAAAJGhtdHgONFhAAAACUAAAGihrZXJuN2E5NgAFAmAAABVgbG9jYQ5haTIAAQDQAAAaLG1heHALRwyoAAAB2AAAACBuYW1lwPJlOwAFF8AAABsNcG9zdI/p134ABTLQAABB/3ByZXBS/sTpAADvoAAACv8AAQAAAAMAAObouupfDzz1CBsIAAAAAACi4ycqAAAAALnVtPb6r/1nEAAIDAAAAAkAAQABAAAAAAABAAAHPv5OAEMQAPqv/iYQAAABAAAAAAAAAAAAAAAAAAAGigABAAAGigEAAD8AdgAHAAIAEAAvAFYAAAQNCv8AAwACAAEDiAGQAAUAAAWaBTMAAAEbBZoFMwAAA9EAZgISCAUCCwYEAgICAgIEAAB6h4AAAAAAAAAIAAAAAE1vbm8AQAAg//wF0/5RATMHPgGyQAAB////AAAAAAYAAQAAAAAAAjkAAAI5AAACOQCwAtcAXgRzABUEcwBJBx0AdwVWAFgBhwBaAqoAfAKqAHwDHQBABKwAcgI5AKoCqgBBAjkAugI5AAAEcwBVBHMA3wRzADwEcwBWBHMAGgRzAFUEcwBNBHMAYQRzAFMEcwBVAjkAuQI5AKoErABwBKwAcgSsAHAEcwBaCB8AbwVW//0FVgCWBccAZgXHAJ4FVgCiBOMAqAY5AG0FxwCkAjkAvwQAADcFVgCWBHMAlgaqAJgFxwCcBjkAYwVWAJ4GOQBYBccAoQVWAFwE4wAwBccAoQVWAAkHjQAZBVYACQVWAAYE4wApAjkAiwI5AAACOQAnA8EANgRz/+ECqgBZBHMASgRzAIYEAABQBHMARgRzAEsCOQATBHMAQgRzAIcBxwCIAcf/ogQAAIgBxwCDBqoAhwRzAIcEcwBEBHMAhwRzAEgCqgCFBAAAPwI5ACQEcwCDBAAAGgXHAAYEAAAPBAAAIQQAACgCrAA5AhQAvAKsAC8ErABXBVb//QVW//0FxwBoBVYAogXHAJwGOQBjBccAoQRzAEoEcwBKBHMASgRzAEoEcwBKBHMASgQAAFAEcwBLBHMASwRzAEsEcwBLAjkAvQI5ACMCOf/lAjkACQRzAIcEcwBEBHMARARzAEQEcwBEBHMARARzAIMEcwCDBHMAgwRzAIMEcwBJAzMAgARzAGsEcwAbBHMAUQLNAG0ETAABBOMAmQXlAAMF5QADCAAA4QKqAN4CqgA9BGQATggAAAEGOQBTBbQAmgRkAE4EZABNBGQATQRz//0EnACgA/QAOAW0AHoGlgChBGQAAAIxAAAC9gAvAuwALQYlAH8HHQBEBOMAgQTjAJ4CqgDoBKwAcgRkAFQEcwAuBGQAMwTlABoEcwCGBHMAjAgAAO8FVv/9BVb//QY5AGMIAACBB40AUgRz//wIAAAAAqoAUwKqAEcBxwCAAccAbARkAE4D9AAvBAAAIQVWAAYBVv45BHP/5AKqAFwCqgBcBAAAFwQAABcEcwBJAjkAuQHHAGwCqgBHCAAAJQVW//0FVgCiBVb//QVWAKIFVgCiAjkAjQI5/+ACOQAEAjkAFQY5AGMGOQBjBjkAYwXHAKEFxwChBccAoQI5AMYCqgAZAqoABgKqAB0CqgAuAqoA5QKqAKICqgBrAqoAOgKqALcCqgAoBHMAAAHHAAMFVgBcBAAAPwTjACkEAAAoAhQAvAXH//0EcwBJBVYABgQAACEFVgCeBHMAhwSsAHIErAChAqoAawKqABkCqgAhBqwAawasAGsGrAAhBHMAAAY5AG0EcwBCAjkAsQVWAFwEAAA/BccAZgQAAFAFxwBmBAAAUARzAEYEa//hAqoB8QVW//0EcwBKBVb//QRzAEoFxwCeBOsARwXH//0FVgCiBHMASwVWAKIEcwBLBHMAlgHHAEIEcwCWAlUAiARzAJoCrACDBccAnARzAIcFxwCcBHMAhwY5AGMEcwBEBccAoQKqAIUFxwChAqoAPAVWAFwEAAA/BOMAMAI5ACQE4wAwAwAAIwXHAKEEcwCDBccAoQRzAIME4wApBAAAKATjACkEAAAoBGgApAY5AGAGYgBVBKAASAR0AEgDkQBiBPAARAMpAC4FMABIBGv/4QQAALAC6wBSCMAAMwgAAE8EAACZCAAATwQAAJkIAABPBAAAmAQAAJgH1QFqBcAAngSrAHIE1QCdBKwAcQTVAiIE1QEFBav/6QUAAckFqwJ+Bav/6QWrAn4Fq//pBasCfgWr/+kFq//pBav/6QWr/+kFq//pBasBwAWrAn4FqwHABasBwAWr/+kFq//pBav/6QWrAn4FqwHABasBwAWr/+kFq//pBav/6QWrAn4FqwHABasBwAWr/+kFq//pBav/6QWr/+kFq//pBav/6QWr/+kFq//pBav/6QWr/+kFq//pBav/6QWr/+kFq//pBav/6QWr/+kFqwLWBasAZgWr/+oF1f//BNUAkggAAAAH6wEwB+sBIAfrATAH6wEgBNUAsgTVAIAE1QAqCCsBmAhrAbgHVQAQBgAA9AYAAG8EQAA6BUAANwTAAD8EFQBABAAAJQYAAFUF4QC/A40AiQTV/9kBgACAAtUAhgcVAGEClgAPBNUAkgLWAIMC1gCDBNUAsgLWAHAFVv/9BHMASgXHAGYEAABQBccAZgQAAFAFVgCiBHMASwVWAKIEcwBLBVYAogRzAEsGOQBtBHMAQgY5AG0EcwBCBjkAbQRzAEIFxwCkBHMAhwXHAB8EcwAGAjn/zgI5/84COf/kAjn/5AI5//YCOf/1AjkAowHHAGYEAAA3Acf/ogVWAJYEAACIBAAAhgRzAJYBx//6BccAnARzAIcFyQClBHMAiwY5AGMEcwBEBjkAYwRzAEQFxwChAqoAawVWAFwEAAA/BOMAMAI5AAwFxwChBHMAgwXHAKEEcwCDBccAoQRzAIMFxwChBHMAgweNABkFxwAGBVYABgQAACEBxwCJBVb//QRzAEoIAAABBx0ARAY5AFME4wCBAjkAuQeNABkFxwAGB40AGQXHAAYHjQAZBccABgVWAAYEAAAhAccAigKq/+EEcwAbBM0AWgasAGsGrAAiBqwAIgasAEoCqgDiAqoAawKqAN4Cqv/qBVf//wZG/6cGtP+oAxL/qAYy/6cG2P+nBgX/pwHH/3gFVv/9BVYAlgVY//4FVgCiBOMAKQXHAKQCOQC/BVYAlgVYAAsGqgCYBccAnAUzAG0GOQBjBccApAVWAJ4E8gCUBOMAMAVWAAYFVgAJBq8AfwX7AGECOQAEBVYABgSgAEgDkQBiBHMAiwHHAGsEYACIBJoAjAQAABkDhwBIBHMAiwRzAFwBxwCJBAAAhgQAABgEnACgBAAAGgOVAFwEcwBEBI0AgwPbAFYEYACIBDMAEQW0AHoGPwBXAcf/yQRgAIgEcwBIBGAAiAY/AFcFVwCiBusAMgRVAKEFwABkBVYAXAI5AL8COQAEBAAANwh1AA0IFQCkBtUAMQSpAKEFFQAKBcAAoAVW//0FQACnBVYAlgRVAKEFawAABVYAogdjAAcE1QBOBcAAoQXAAKEEqQChBUAAEgaqAJgFxwCkBjkAYwXAAKAFVgCeBccAZgTjADAFFQAKBhUAUgVWAAkF6wCfBVUAVwdVAKEHgAChBlUAAAcVAKgFQAClBcAAVQgVAKQFxwAaBHMASgSVAFsEQACIAusAiASrAAAEcwBLBVr/+wOrADIEeACHBHgAhwOAAIYEqwAYBYAAjARrAIgEcwBEBFUAiARzAIcEAABQA6oAJgQAACEGlQBLBAAADwSVAIoEKwBFBmsAjQaVAI0FAAAoBcAAiwQrAIQEFQAwBgAAiQRVAB8EcwBLBHMAAALrAIkEFQBLBAAAPwHHAIgCOQAJAcf/ogdAABMGgACDBHMAAAOAAIYEAAAhBGsAiAPpAKEDSgCICAAAQQiVAKAFhQAtAqoBAQKqAB4CqgAxAqoAMQKqAQECqgB+AqoAfgKqAIwCqgCMAqoBAQKqABACqgEBAqoBIQMQAH0CqgCMAjMA0gKqAwsCqv8EAjkAuQSBAGkEVgAyAzEAGQQRAC0E0QCWAfkAmwMPAF8EygCbBLgAjAH5AJsEEwAoA7AAUAO0ADwEygCbBM8AUAH5AJsC0gA8BJgAWgQ8ABkEiABuBF8AcwOxABkD1AAKBGYAlgQTACgFjgBkBSQAKAPyAJsD8gCbA/IAmwHjAFoDVgBaBoYAmwH5/6wEEwAoBBMAKAO0/1cDtP9XBEgALQWOAGQFjgBkBY4AZAWOAGQEgQBpBIEAaQSBAGkEVgAyAzEAGQQRAC0E0QCWAksAAANKAAAEuACMAksAAAQTACgDsABQA7QAPATPAFAC0gA8BJgAWgSIAG4EXwBzA9QACgRmAJYEEwAoBY4AZAUkACgB+QCbBFYAMgOwAFAEXwBzBJsAPAAA/9wAAP8lAAD/3AAA/lECjQCrAo0AoALaAEMDTQB5Aaj/ugGcAEYB5QBGAZwARgGcAEYBrQBIAZwARgGxAEYBUQBGBDUBfAQ1AS4ENQC3BDUAgQQ1ASwENQC+BDUArwQ1AIEENQCaBDUA2wQ1AIUCjQDBBDUAswYAAQAGAAEAAkIANgYAAQAENQCeBDUAmAQ1AMsGAAEABgABAAYAAQAGAAEABgABAAGxAEYGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAUb/7oGAAEABgABAAYAAQAFtQA6BbUAOgH0/7oB9P+6BgABAAYAAQAGAAEABgABAASBADYENQA2BD3/ugQ9/7oD6QBKA+kASgZ/ABQHdgAUAyf/ugQe/7oGfwAUB3YAFAMn/7oEHv+6BRsAMgS1ACQGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEAAc8AMAGxAEYBsQBGAbEAQAGxAEYGAAEABgABAAAA/9wAAP5RAAD/FgAA/xYAAP8WAAD/FgAA/xYAAP8WAAD/FgAA/xYAAP8WAAD/3AAA/xYAAP/cAAD/IAAA/9wEcwBKCAAAAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQACjQB/Ao0AXQYAAQAE7gAVA00AeQGoAA4B1v/cAagAVgHWABADdQAyA3UAMgGoAC0B1gATBRsAMgS1ACQB9P+6AfT/ugGoAJMB1gATBbUAOgW1ADoB9P+6AfT/ugJCAAADAP/3BbUAOgW1ADoB9P+6AfT/ugW1ADoFtQA6AfT/ugH0/7oEgQA2BDUANgQ9/7oEPf+6BIEANgQ1ADYEPf+6BD3/ugSBADYENQA2BD3/ugQ9/7oCswBfArMAXwKzAF8CswBfA+kASgPpAEoD6QBKA+kASgaSAD4GkgA+BD//ugQ//7oGkgA+BpIAPgQ//7oEP/+6CMkAPgjJAD4Gxf+6BsX/ugjJAD4IyQA+BsX/ugbF/7oEp/+6BKf/ugSn/7oEp/+6BKf/ugSn/7oEp/+6BKf/ugRaACoDmgA2BDX/ugMn/7oEWgAqA5oANgQ1/7oDJ/+6Bk8AJwZPACcCJP+6Ahr/ugSnAEYEpwBGAiT/ugIa/7oEzwAtBM8ALQMn/7oDJ/+6BA0ARwQNAEcBqP+6Aaj/ugK0ACMCtAAjAyf/ugMn/7oENQBFBDUARQH0/7oB9P+6AkIANgMA//cDmv+6Ayf/ugN1ADIDdQAyBRsAMgS1ACQFGwAyBLUAJAH0/7oB9P+6BFoAQATOAEkEWgAmBM4AOQRaAFMEzgBKBFoAUwTOAEoGAAEABgABAAGcAEYBnABGBgABAAYAAQAGAAEAAVEARgGxAEYGAAEABgABAAGtAEgB5QBGBgABAAYAAQAGAAEAAbEARgGxAEYBsQBGAbEARgGxAEABzwAwBgABAAGcAEYBnABGBgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEAAo0AygKNAMcCjQDGBgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEABgABAAYAAQAGAAEAAQD/uggA/7oQAP+6BtwAYwU/AEQG1QChBVsAgwAA/dwAAPwvAAD8pgAA/lQAAPzXAAD9cwAA/ikAAP4NAAD9EQAA/GcAAP2dAAD79QAA/HIAAP7VAAD+1QAA/wIEGwCgBqwAawasABkAAP62AAD9cwAA/ggAAPymAAD+UwAA/REAAPvIAAD69AAA+q8AAPxyAAD7qgAA+2oAAPzxAAD8fQAA+90AAPzBAAD7mAAA/eoAAP6EAAD9wgAA/PEAAP1fAAD+dgAA/rwAAPzrAAD9bAAA/VgAAPyQAAD9FQAA/CwAAPwTAAD8EgAA+5YAAPuWAccAiAVW//0EcwBKBVb//QRzAEoFVv/9BHMASgVW//0EcwBKBVb//QRzAEoFVv/9BHMASgVW//0EcwBKBVb//QRzAEoFVv/9BHMASgVW//0EcwBKBVb//QRzAEoFVv/9BHMASgVWAKIEcwBLBVYAogRzAEsFVgCiBHMASwVWAKIEcwBLBVYAogRzAEsFVgCiBHMASwVWAKIEcwBLBVYAogRzAEsCOQBjAccAHwI5ALoBxwB8BjkAYwRzAEQGOQBjBHMARAY5AGMEcwBEBjkAYwRzAEQGOQBjBHMARAY5AGMEcwBEBjkAYwRzAEQG3ABjBT8ARAbcAGMFPwBEBtwAYwU/AEQG3ABjBT8ARAbcAGMFPwBEBccAoQRzAIMFxwChBHMAgwbVAKEFWwCDBtUAoQVbAIMG1QChBVsAgwbVAKEFWwCDBtUAoQVbAIMFVgAGBAAAIQVWAAYEAAAhBVYABgQAACEFVv/9BHMASgI5/+IBx/+wBjkAYwRzAEQFxwChBHMAgwXHAKEEcwCDBccAoQRzAIMFxwChBHMAgwXHAKEEcwCDAAD+/gAA/v4AAP7+AAD+/gRV//0C6wAMB2MABwVa//sEqQChA4AAhgSpAKEDgACGBccApARrAIgEc//9BAAAFARz//0EAAAUBVYACQQAAA8FVQBXBCsARQVVAKEEcwCHBgUAYwRzAFUGOQBgBHMARAW1ADoB9P+6AiT/ugIa/7oEpwBGAfQAngH0ABAB9AAbAfQAEAH0AGsB9P/5Aif/zgGoAA8BqP/1AqoApAKqAKQBqAAOAagAVgGoAFYAAP/PAagADwHW/78BqP/1Adb/zQGoAB0B1v/1AagAkwHWABMDdQAyA3UAMgN1ADIDdQAyBRsAMgS1ACQFtQA6BbUAOgH0/7oB9P+6BbUAOgW1ADoB9P+6AfT/ugW1ADoFtQA6AfT/ugH0/7oFtQA6BbUAOgH0/7oB9P+6BbUAOgW1ADoB9P+6AfT/ugW1ADoFtQA6AfT/ugH0/7oFtQA6BbUAOgH0/7oB9P+6BIEANgQ1ADYEPf+6BD3/ugSBADYENQA2BD3/ugQ9/7oEgQA2BDUANgQ9/7oEPf+6BIEANgQ1ADYEPf+6BD3/ugSBADYENQA2BD3/ugQ9/7oEgQA2BDUANgQ9/7oEPf+6ArMAMgKzADICswBfArMAXwKzAF8CswBfArMAMgKzADICswBfArMAXwKzAF8CswBfArMAXwKzAF8CswA4ArMAOAKzAEkCswBJA+kASgPpAEoD6QBK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