survey-creator-core
Version:
A framework-independent core package of the SurveyJS Survey Creator component. With Survey Creator, you can visually design complex, interactive JSON forms and surveys in a drag-and-drop interface.
1,101 lines (1,094 loc) • 181 kB
JavaScript
/*!
* SurveyJS Creator v2.5.4
* (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/
* Github: https://github.com/surveyjs/survey-creator
* License: https://surveyjs.io/Licenses#SurveyCreator
*/
import { Helpers, SvgRegistry, ComputedUpdater, Action, SurveyModel, settings, createDropdownActionModel, FunctionFactory, Serializer, ItemValue, matrixDropdownColumnTypes, surveyLocalization, ElementFactory, ActionContainer, Base, LocalizableString, EventBase, hasLicense, glc, QuestionCommentModel, TextAreaModel, CustomError, JsonObject, checkLibraryVersion } from 'survey-core';
import { getLocString, editorLocalization, listComponentCss as listComponentCss$1, SurveyHelper, defaultPropertyGridDefinition, settings as settings$1, PropertyGridModel, SurveyQuestionProperties, getLocaleStrings, UIPreset, SurveyCreatorModel, saveToFileHandler, PredefinedCreatorPresets, CreatorPresets, SurveyJSON5 } from 'survey-creator-core';
class CreatorPresetEditableBase {
get navigationPanelName() { return this.path + "_navigation"; }
constructor(preset) {
this.preset = preset;
this.children = [];
this.notifyCallback = (message) => { };
}
get path() { return this.preset.getPath(); }
getJsonPath(model) { return this.path; }
get fullPath() {
let prefix = this.parent ? this.parent.fullPath : "";
if (this.path && prefix) {
prefix += "_";
}
return prefix + this.path;
}
get pageName() { return "page_" + this.fullPath; }
getPageTitle(model) { return model.getPageByName(this.pageName).title; }
getPageShortTitle(model) { return model.getPageByName(this.pageName).navigationTitle; }
get mainPanelName() { return this.path + "_mainPanel"; }
getMainElementNames() { return [this.mainPanelName]; }
getMainPanelName() { return this.mainPanelName; }
getCustomQuestionCssSuffix(question) { return ""; }
createPages() {
const res = [];
const mainPage = this.createMainPage();
if (mainPage) {
res.push(mainPage);
}
this.children.forEach(item => {
const pages = item.createPages();
if (Array.isArray(pages)) {
pages.forEach(page => res.push(page));
}
});
return res;
}
get questionNames() { return []; }
validate(model) {
if (!this.validateCore(model))
return false;
for (let i = 0; i < this.children.length; i++) {
if (!this.children[i].validate(model))
return false;
}
return true;
}
validateCore(model) {
return true;
}
createMainPage() {
const res = this.createMainPageCore();
if (res) {
res.name = this.pageName;
}
return res;
}
getBoolVisibleIf(name, isTrue = true) { return "{" + name + "}=" + (isTrue ? "true" : "false"); }
getTextVisibleIf(name, val) { return "{" + name + "}='" + val + "'"; }
getNotEmptyVisibleIf(name) { return "{" + name + "} notempty"; }
createMainPageCore() { return undefined; }
getNavigationElementName() { return this.navigationPanelName; }
getJsonValue(model, creator, defaultJson) {
const page = model.getPageByName(this.pageName);
const core = page && page.isVisible ? this.getJsonValueCore(model, creator, defaultJson) : undefined;
let hasValue = !!core;
const res = hasValue ? core : {};
this.children.forEach(item => {
const val = item.getJsonValue(model, creator);
if (!!val) {
hasValue = true;
res[item.getJsonPath(model)] = val;
}
});
return hasValue ? res : undefined;
}
getDefaultJsonValue(creator) {
const json = this.getDefaultJsonValueCore(creator);
this.children.forEach(item => json[item.path] = item.getDefaultJsonValueCore(creator));
return json;
}
setJsonLocalizationStrings(model, locStrs) {
this.setJsonLocalizationStringsCore(model, locStrs);
this.children.forEach(item => item.setJsonLocalizationStrings(model, locStrs));
}
updateJsonLocalizationStrings(locStrs) {
this.updateJsonLocalizationStringsCore(locStrs);
this.children.forEach(item => item.updateJsonLocalizationStrings(locStrs));
}
dispose() {
this.disposeCore();
this.children.forEach(item => item.dispose());
}
setupQuestions(model, creatorSetup) {
this.setupQuestionsCore(model, creatorSetup);
this.children.forEach(item => {
item.setupQuestions(model, creatorSetup);
});
}
resetToDefaults(model, notify = true) {
this.restoreValuesFromDefault(model);
this.notifyCallback(this.getPageTitle(model) + " " + getLocString("presets.editor.resoredToDefault"));
this.children.forEach(item => {
item.resetToDefaults(model, notify);
});
}
setupOnCurrentPage(model, creator, active) {
this.setupOnCurrentPageCore(model, creator, active);
this.children.forEach(item => {
item.setupOnCurrentPage(model, creator, active);
});
}
updateOnValueChanged(model, name) {
this.updateOnValueChangedCore(model, name);
this.children.forEach(item => {
item.updateOnValueChanged(model, name);
});
}
updateOnMatrixDetailPanelVisibleChanged(model, creator, options) {
this.updateOnMatrixDetailPanelVisibleChangedCore(model, creator, options);
this.children.forEach(item => {
item.updateOnMatrixDetailPanelVisibleChanged(model, creator, options);
});
}
onGetMatrixRowActions(model, creator, options) {
this.onGetMatrixRowActionsCore(model, creator, options);
this.children.forEach(item => {
item.onGetMatrixRowActions(model, creator, options);
});
}
onGetQuestionTitleActions(model, creator, options) { }
onGetPanelTitleActions(model, creator, options) { }
onMatrixRowDragOver(model, creator, options) { }
onMatrixRowRemoving(model, creator, options) { }
onMatrixRowAdded(model, creator, options) { }
onMatrixCellValueChanged(model, creator, options) { }
setupQuestionsValue(model, json, creator) {
this.setupQuestionsValueCore(model, json, creator);
this.saveValuesAsDefault(model);
this.children.forEach(item => {
item.setupQuestionsValue(model, !!json ? json[item.path] : undefined, creator);
});
}
onLocaleChanged(model, json, creator) {
this.onLocaleChangedCore(model, json, creator);
this.children.forEach(item => {
item.setupQuestionsValue(model, !!json ? json[item.path] : undefined, creator);
});
}
saveValuesAsDefault(model) {
this.questionNames.forEach(name => model.getQuestionByName(name).defaultValue = model.getValue(name) && JSON.parse(JSON.stringify(model.getValue(name))));
}
restoreValuesFromDefault(model) {
this.questionNames.forEach(name => model.getQuestionByName(name).value = model.getQuestionByName(name).defaultValue && JSON.parse(JSON.stringify(model.getQuestionByName(name).defaultValue)));
}
setupQuestionsCore(model, creatorSetup) { }
resetToDefaultsCore(model) { }
setupQuestionsValueCore(model, json, creator) { }
onLocaleChangedCore(model, json, creator) { }
getJsonValueCore(model, creator, defaultJson) { return undefined; }
getDefaultJsonValueCore(creator) { return {}; }
setJsonLocalizationStringsCore(model, locStrs) { }
updateJsonLocalizationStringsCore(locStrs) { }
disposeCore() { }
setupOnCurrentPageCore(model, creator, active) { }
updateOnValueChangedCore(model, name) { }
updateOnMatrixDetailPanelVisibleChangedCore(model, creator, options) { }
onGetMatrixRowActionsCore(model, creator, options) { }
copyJson(json) {
return Helpers.getUnbindValue(json);
}
static updateModifiedText(locStrs, text, localizationName) {
if (!localizationName)
return undefined;
if (!text)
return;
const presetStrs = editorLocalization.presetStrings;
editorLocalization.presetStrings = undefined;
if (text !== editorLocalization.getString(localizationName)) {
CreatorPresetEditableBase.saveTextInLocStrs(locStrs, text, localizationName);
}
editorLocalization.presetStrings = presetStrs;
}
static saveTextInLocStrs(locStrs, text, localizationName) {
const paths = localizationName.split(".");
for (let i = 0; i < paths.length - 1; i++) {
const path = paths[i];
if (!locStrs[path]) {
locStrs[path] = {};
}
locStrs = locStrs[path];
}
locStrs[paths[paths.length - 1]] = text;
}
}
var presetsCss = {
root: "sps-root-modern",
container: "sps-container-modern",
header: "sps-title sps-container-modern__title",
body: "sps-body",
bodyEmpty: "sps-body sps-body--empty",
footer: "sps-footer sps-body__footer sps-clearfix",
title: "",
description: "",
logo: "sps-logo",
logoImage: "sps-logo__image",
headerText: "sps-header__text",
navigationButton: "",
bodyNavigationButton: "",
completedPage: "sps-completedpage",
navigation: {
complete: "sps-btn sps-btn--primary-brand sps-footer__complete-btn",
prev: "sps-btn sps-btn--secondary-brand sps-footer__prev-btn",
next: "sps-btn sps-btn--primary-brand sps-footer__next-btn",
start: "sps-btn sps-footer__start-btn",
preview: "sps-btn sps-footer__preview-btn",
edit: "sps-btn sps-footer__edit-btn"
},
list: JSON.parse(JSON.stringify(listComponentCss$1)),
panel: {
withFrame: "sps-panel--with-frame",
nested: "sps-panel--nested",
expandableAnimating: "",
header: "sps-panel__header",
title: "sps-title sps-panel__title",
titleBar: "sd-action-title-bar sps-action-title-bar",
contentEnter: "sps-panel__content--enter",
contentLeave: "sps-panel__content--leave",
titleExpandable: "sps-panel__title--expandable",
titleExpanded: "sps-panel__title--expanded",
titleCollapsed: "sps-panel__title--collapsed",
titleOnError: "sps-panel__title--error",
description: "sps-description sps-panel__description",
container: "sps-panel sps-row__panel",
content: "sps-panel__content",
icon: "sps-panel__icon",
iconExpanded: "sps-panel__icon--expanded",
footer: "sps-panel__footer",
requiredMark: "sps-panel__required-text",
collapsed: "sps-panel--collapsed",
expanded: "sps-panel--expanded",
},
paneldynamic: {
nested: "",
mainRoot: "sps-question sps-row__question",
root: "sps-paneldynamic",
navigation: "sps-paneldynamic__navigation",
title: "sps-title sps-question__title",
button: "sps-action-button sps-action-button--text",
buttonRemove: "sps-action-button--danger",
buttonAdd: "sps-paneldynamic__add-btn",
panelsContainer: "",
panelWrapper: "sps-paneldynamic__panel-wrapper",
panelWrapperList: "",
progressTop: "sps-paneldynamic__progress sps-paneldynamic__progress--top",
progressBottom: "sps-paneldynamic__progress sps-paneldynamic__progress--bottom",
buttonPrev: "sps-paneldynamic__prev-btn",
buttonNext: "sps-paneldynamic__next-btn",
progressContainer: "sps-paneldynamic__progress-container",
progress: "sps-progress",
progressBar: "sps-progress__bar",
progressText: "sps-paneldynamic__progress-text",
panelFooter: "sps-panel__footer",
separator: "sps-paneldynamic__separator",
footer: "sps-paneldynamic__footer",
footerButtonsContainer: "sps-paneldynamic__buttons-container",
},
progress: "sps-progress sps-body__progress",
progressBar: "sps-progress__bar",
progressText: "sps-progress__text",
progressTextInBar: "sps-hidden",
page: {
root: "sps-page sps-body__page",
title: "sps-title sps-page__title",
description: "sps-description sps-page__description"
},
pageTitle: "sps-title sps-page__title",
pageDescription: "sps-description sps-page__description",
row: "sps-row sps-clearfix",
rowEnter: "sps-row--enter",
rowLeave: "sps-row--leave",
rowDelayedEnter: "sps-row--delayed-fade-in",
rowMultiple: "sps-row--multiple",
question: {
withFrame: "sps-question--with-frame",
nested: "sps-question--nested",
mainRoot: "sps-question sps-row__question",
flowRoot: "sps-question sps-row__question sps-row__question--flow",
asCell: "sps-table__cell",
header: "sps-question__header",
headerLeft: "sps-question__header--location--left",
headerTop: "sps-question__header--location--top",
headerBottom: "sps-question__header--location--bottom",
content: "sps-question__content",
contentLeft: "sps-question__content--left",
titleLeftRoot: "sps-question--location--left",
titleOnAnswer: "sps-question__title--answer",
titleOnError: "sps-question__title--error",
title: "sps-title sps-question__title",
titleBar: "sd-action-title-bar sps-action-title-bar",
requiredMark: "sps-question__required-text",
number: "sps-question__num",
description: "sps-description sps-question__description",
descriptionUnderInput: "sps-question__description--under",
comment: "sps-comment",
required: "sps-question--required",
titleRequired: "sps-question__title--required",
indent: 0,
footer: "sps-question__footer",
formGroup: "sps-question__form-group",
hasError: "",
readOnly: "sd-question--readonly sps-question--disabled",
confirmDialog: "sps-popup--confirm sv-popup--confirm svc-creator-popup",
errorsContainerBottom: "sps-question__erbox--below-question",
},
checkbox: {
root: "sps-selectbase",
item: "sps-item sps-checkbox sps-selectbase__item",
itemSelectAll: "sps-checkbox--selectall",
itemNone: "sps-checkbox--none",
itemReadOnly: "sps-item--disabled sps-checkbox--disabled",
itemChecked: "sps-checkbox--checked",
itemHover: "sps-checkbox--allowhover",
itemInline: "sps-selectbase__item--inline",
label: "sps-selectbase__label",
// label: "sps-checkbox",
itemSvgIconId: "#icon-check-16x16",
labelChecked: "",
//itemControl: "sps-visuallyhidden sps-item__control",
itemControl: "sps-checkbox__control",
itemDecorator: "sps-checkbox__svg",
//itemDecorator: "sps-checkbox__hidden",
//controlLabel: "sps-item__control-label",
controlLabel: "sps-checkbox__caption",
materialDecorator: "sps-checkbox__rectangle",
//materialDecorator: "sps-item__decorator sps-checkbox__decorator",
other: "sps-comment sps-question__other",
column: "sps-selectbase__column"
},
radiogroup: {
root: "sps-selectbase",
item: "sps-item sps-radio sps-selectbase__item",
itemInline: "sps-selectbase__item--inline",
label: "sps-selectbase__label",
labelChecked: "",
itemReadOnly: "sps-item--disabled sps-radio--disabled",
itemChecked: "sps-radio--checked",
itemHover: "sps-radio--allowhover",
itemControl: "sps-visuallyhidden sps-item__control",
itemDecorator: "sps-item__svg sps-radio__svg",
controlLabel: "sps-item__control-label",
materialDecorator: "sps-item__decorator sps-radio__decorator",
other: "sps-comment sps-question__other",
clearButton: "sps-btn sps-selectbase__clear-btn",
column: "sps-selectbase__column"
},
boolean: {
mainRoot: "sps-question sps-row__question sps-question--boolean",
rootCheckbox: "sps-selectbase",
checkboxItem: "sps-checkbox",
checkboxItemChecked: "sps-checkbox--checked",
checkboxitemIndeterminate: "sps-checkbox--indeterminate",
checkboxItemReadOnly: "sps-checkbox--disabled",
svgIconId: "#icon-v2check",
checkboxLabel: "sps-selectbase__label",
controlCheckbox: "sps-checkbox__control",
checkboxControlLabel: "sps-checkbox__caption",
checkboxItemDecorator: "sps-checkbox__svg",
checkboxMaterialDecorator: "sps-checkbox__rectangle"
},
text: {
root: "sps-input sps-text",
controlReadOnly: "sps-input--readonly",
small: "sps-row__question--small",
content: "sps-question__content sps-text__content",
remainingCharacterCounter: "sps-remaining-character-counter",
onError: "sps-input--error"
},
comment: {
root: "sps-input sps-comment",
content: "sps-question__content sps-comment__content",
remainingCharacterCounter: "sps-remaining-character-counter",
small: "sps-row__question--small",
onError: "sps-input--error"
},
dropdown: {
root: "sps-selectbase",
popup: "sps-dropdown-popup svc-creator-popup",
small: "sps-row__question--small sd-row__question--small",
control: "sps-input sps-dropdown",
controlEmpty: "sps-dropdown--empty sd-dropdown--empty",
controlValue: "sps-dropdown__value",
filterStringInput: "sd-dropdown__filter-string-input sps-dropdown__filter-string-input",
other: "sps-comment sps-question__other",
onError: "sps-input--error",
selectWrapper: "sv-dropdown_select-wrapper sps-dropdown_select-wrapper",
chevronButtonIconId: "icon-chevron",
cleanButton: "sps-dropdown__clean-button sps-input__edit-button",
controlReadOnly: "sps-input--readonly sd-input--disabled sd-input--readonly",
hintPrefix: "sps-dropdown__hint-prefix sd-dropdown__hint-prefix",
hintSuffix: "sps-dropdown__hint-suffix sd-dropdown__hint-suffix"
},
tagbox: {
cleanItemButton: "sd-tagbox-item_clean-button sps-tagbox-item_clean-button",
cleanItemButtonSvg: "sd-tagbox-item_clean-button-svg sps-tagbox-item_clean-button-svg",
control: "sd-input sd-tagbox sd-dropdown sps-tagbox sps-dropdown",
controlValue: "sd-tagbox__value sd-dropdown__value sps-tagbox__value",
filterStringInput: "sd-dropdown__filter-string-input sps-dropdown__filter-string-input",
},
matrix: {
tableWrapper: "sps-matrix sps-table-wrapper",
root: "sps-table",
rowError: "sps-matrix__row--error",
cell: "sps-table__cell sps-matrix__cell",
headerCell: "sps-table__cell sps-table__cell--header",
label: "sps-item sps-radio sps-matrix__label",
itemValue: "sps-visuallyhidden sps-item__control sps-radio__control",
itemChecked: "sps-radio--checked",
itemReadOnly: "sps-item--disabled sps-radio--disabled",
itemHover: "sps-radio--allowhover",
materialDecorator: "sps-item__decorator sps-radio__decorator",
itemDecorator: "sps-item__svg sps-radio__svg",
cellText: "sps-matrix__text",
cellTextSelected: "sps-matrix__text--checked",
cellTextReadOnly: "sps-matrix__text--disabled",
},
matrixdropdown: {
tableWrapper: "sps-table-wrapper",
root: "sps-table",
cell: "sps-table__cell",
headerCell: "sps-table__cell sps-table__cell--header",
emptyCell: "sps-table__cell--empty",
rowEnter: "sps-table__row--enter",
rowLeave: "sps-table__row--leave",
},
matrixdynamic: {
mainRoot: "sps-question sps-question--matrixdynamic sd-element sd-question sd-row__question sd-element--complex sd-question--complex sd-question--table",
tableWrapper: "sps-table-wrapper",
root: "sps-table sps-matrixdynamic",
content: "sps-matrixdynamic__content sps-text__content",
cell: "sps-table__cell",
row: "sps-table__row",
rowDisabled: "sps-table__row-disabled",
rowReadOnly: "sps-table__row-readonly",
headerCell: "sps-table__cell sps-table__cell--header",
button: "sps-btn",
detailRow: "sps-table__row sps-table__row--detail",
detailButton: "sps-table__cell--detail-button sps-action-button",
detailButtonExpanded: "sps-table__cell--detail-button--expanded",
detailIcon: "sps-detail-panel__icon sps-action-button__icon",
detailIconExpanded: "sps-detail-panel__icon--expanded",
detailIconExpandedId: "icon-collapse-24x24",
detailIconId: "icon-expand-24x24",
detailPanelCell: "sps-table__cell sps-table__cell--detail-panel",
actionsCell: "sps-table__cell sps-table__cell--actions",
buttonAdd: "sps-matrixdynamic__add-btn sps-action-button sps-action-button--large",
buttonRemove: "sps-matrixdynamic__remove-btn",
iconAdd: "",
iconRemove: "xxx",
dragElementDecorator: "sps-drag-element__svg",
iconDragElement: "#icon-drag-24x24",
iconDrag: "sps-matrixdynamic__drag-element",
footer: "sps-matrixdynamic__footer",
dragDropGhostPositionTop: "sps-matrixdynamic__drag-drop-ghost-position-top",
dragDropGhostPositionBottom: "sps-matrixdynamic__drag-drop-ghost-position-bottom",
noRowsSection: "sps-matrixdynamic__placeholder",
noRowsText: "sps-matrixdynamic__placeholder-text",
cellQuestionWrapper: "sps-table__question-wrapper",
draggedRow: "sps-matrixdynamic__dragged-row",
emptyCell: "sps-table__cell--empty",
rowEmpty: "sps-table__row--empty",
rowEnter: "sps-table__row--enter",
rowLeave: "sps-table__row--leave",
},
actionBar: {
root: "sps-action-bar",
item: "sps-action-button",
itemPressed: "sps-action-button--pressed",
itemAsIcon: "sps-action-button--icon",
itemIcon: "sps-action-button__icon",
itemTitle: "sps-action-button__title",
}
};
class CreatorPresetEditableList extends CreatorPresetEditableBase {
constructor() {
super(...arguments);
//private replaceNonLettersWithDash(inputString) {
// return inputString?.replace(/[^a-zA-Z0-9]/g, "-");
//}
this.defaultIcon = "square-dashed-24x24";
}
get nameItems() { return this.path + "_items"; }
get nameMatrix() { return this.fullPath + "_matrix"; }
hasIcon(_) { return false; }
getMainElementNames() { return [this.nameItems]; }
get iconList() { return Object.keys(SvgRegistry.icons).map(name => "icon-" + name); }
getMatrixKeyColumnName(question) { return "name"; }
getDefaultItems(question) {
return this.defaultItems;
}
getDefaultItem(question, key) {
const keyColumn = this.getMatrixKeyColumnName(question);
return this.getDefaultItems(question).filter(i => i[keyColumn] == key)[0];
}
//private fillAutoName(question: QuestionMatrixDynamicModel, propName: string) {
// question.value?.filter(v =>v.isDefault === false && !v[propName]).forEach(v => v[propName] = this.replaceNonLettersWithDash(v.title));
//}
updateOnValueChangedCore(model, name) {
if (this.needToSetActions(name)) {
const matrix = model.getQuestionByName(name);
this.updateMatrixRowActions(model, matrix);
}
}
updateMatrixRowActions(model, matrix) {
matrix.renderedTable.rows.forEach(r => {
var _a, _b, _c;
if (!r.row)
return;
const iconActions = (_b = (_a = r.cells[1]) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.value.actions;
this.updateRowActions(matrix, r.row, iconActions);
const actions = (_c = r.cells[r.cells.length - 1].item) === null || _c === void 0 ? void 0 : _c.value.actions;
this.updateRowActions(matrix, r.row, actions);
});
}
updateRowActions(question, row, actions) {
if (!actions)
return;
const keyColumn = this.getMatrixKeyColumnName(question);
if (!question.value)
return;
const rowData = question.value.filter(r => { var _a; return ((_a = row.value) === null || _a === void 0 ? void 0 : _a[keyColumn]) == (r === null || r === void 0 ? void 0 : r[keyColumn]); })[0];
if (!rowData)
return;
actions.forEach(a => this.updateRowAction(question, row, rowData, keyColumn, a));
}
updateRowAction(question, row, rowData, keyColumn, action) {
if (action.id == "icon-action") {
action.iconName = rowData.iconName || this.defaultIcon;
}
if (action.id == "reset-to-default") {
const defaultItem = this.getDefaultItem(question, rowData[keyColumn]);
if (!defaultItem)
return;
const defaultData = {};
Object.keys(rowData).forEach(key => defaultData[key] = defaultItem[key]);
action.enabled = !Helpers.isTwoValueEquals(rowData, defaultData);
}
}
createResetAction(model, row, action) {
return {
id: "reset-to-default",
iconName: "icon-reset",
tooltip: getLocString("presets.items.restoreToDefault"),
location: "end",
visibleIndex: 15,
action: action
};
}
createEditAction(model, creator, question, row) {
return {
id: "edit-item",
iconName: "icon-edit",
tooltip: getLocString("presets.items.edit"),
location: "end",
visibleIndex: 13,
action: () => { this.editItem(model, creator, question, row); }
};
}
createIconAction(iconName, cssClass = "sps-matrixdynamic__row-icon") {
return {
id: "icon-action",
iconName: iconName,
innerCss: cssClass,
location: "start",
enabled: false
};
}
setupStandardActions(actions, question, row, allowExpand, isItemsMatrix) {
actions.forEach(a => {
if (a.id == "show-detail") {
a.location = "end";
a.iconName = "icon-expand-24x24";
a.title = new ComputedUpdater(() => row.isDetailPanelShowing ? getLocString("presets.items.collapse") : getLocString("presets.items.expand"));
a.tooltip = getLocString("presets.items.expand");
a.visibleIndex = 10;
a.visible = allowExpand;
}
if (a.id == "remove-row") {
a.visibleIndex = 20;
a.component = "sv-action-bar-item";
a.action = () => question.removeRowUI(row);
a.iconName = isItemsMatrix ? "icon-add_24x24" : "icon-remove_24x24";
a.tooltip = isItemsMatrix ? getLocString("presets.items.add") : getLocString("presets.items.delete");
}
});
}
editItem(model, creator, question, row, options) {
let survey;
let resetAction;
const itemKey = this.getMatrixKeyColumnName(question);
const resetActionParams = {
id: "reset-to-default",
title: getLocString("presets.editor.resetToDefault"),
css: "sps-action--grow",
innerCss: "sps-btn sps-btn--secondary-alert",
visibleIndex: 15,
action: (a) => {
const defaultItem = this.getDefaultItem(question, survey.getValue(itemKey));
survey.data = defaultItem;
resetAction.enabled = false;
this.notifyCallback(getLocString("presets.editor.itemRestoredToDefault"));
}
};
resetAction = new Action(resetActionParams);
survey = this.showDetailPanelInPopup(question, row, model.rootElement, { actions: [resetAction], title: options === null || options === void 0 ? void 0 : options.description, removeOnCancel: options === null || options === void 0 ? void 0 : options.isNew });
resetAction.enabled = !Helpers.isTwoValueEquals(survey.data, this.getDefaultItem(question, survey.getValue(itemKey)));
survey.onValueChanged.add(() => resetAction.enabled = true);
const keyQuestion = survey.getQuestionByName(itemKey);
if (this.getDefaultItem(question, keyQuestion.value)) {
keyQuestion.readOnly = true;
}
}
resetItem(model, question, row) {
const name = row.getValue("name");
const defaultItems = this.getDefaultItem(question, name);
if (defaultItems) {
const value = question.value;
const itemRow = value.filter(v => v.name == name)[0];
Object.keys(itemRow).forEach((key) => {
itemRow[key] = defaultItems[key];
});
question.value = value;
}
this.notifyCallback(getLocString("presets.editor.itemRestoredToDefault"));
}
restoreItems(questionItems, questionHiddenItems, rowIndex) {
const rowData = questionHiddenItems.value[rowIndex];
const value = questionItems.value ? [...questionItems.value] : [];
value.push(rowData);
questionItems.value = value;
}
getMatrix(model) {
return model.getQuestionByName(this.nameMatrix);
}
isItemsMatrix(name) {
return name === this.nameMatrix;
}
needToSetActions(name) {
return this.isItemsMatrix(name);
}
onGetMatrixRowActionsCore(model, creator, options) {
var _a, _b;
if (this.needToSetActions(options.question.name)) {
const question = options.question;
const allowExpand = question.detailElements.filter(e => e.visible).length > 0;
if (this.hasIcon(options.question.name)) {
const keyColumn = this.getMatrixKeyColumnName(options.question);
const iconName = ((_b = (_a = question.value) === null || _a === void 0 ? void 0 : _a.filter(v => v[keyColumn] == options.row.getValue(keyColumn))[0]) === null || _b === void 0 ? void 0 : _b.iconName) || this.defaultIcon;
options.actions.push(this.createIconAction(iconName));
}
const resetAction = this.createResetAction(model, options.row, (action) => {
this.resetItem(model, question, options.row);
action.enabled = false;
});
options.actions.push(resetAction);
options.actions.push(this.createEditAction(model, creator, question, options.row));
this.setupStandardActions(options.actions, question, options.row, allowExpand, question.name == this.nameMatrix);
this.updateRowActions(question, options.row, options.actions);
}
}
onMatrixRowDragOver(model, creator, options) {
if (this.isItemsMatrix(options.fromMatrix.name) && this.isItemsMatrix(options.toMatrix.name)) {
options.allow = true;
}
}
onMatrixRowRemoving(model, creator, options) {
if (this.isItemsMatrix(options.question.name) && options.question.name != this.nameMatrix) {
const rowData = options.question.value[options.rowIndex];
const hiddenItems = this.getMatrix(model);
const value = hiddenItems.value ? [...hiddenItems.value] : [];
value.push(rowData);
hiddenItems.value = value;
}
}
getExistingKeys(model, key) {
const items = model.getQuestionByName(this.nameItems).value || [];
const unsorted = model.getQuestionByName(this.nameMatrix).value || [];
return [...items, ...unsorted];
}
getDefaultValueForRow(model, question, key) {
return SurveyHelper.getNewName(this.getExistingKeys(model, key).map(i => i[key]).filter(v => !!v).map(r => ({ name: r })), key);
}
setDefaultValueForRow(model, question, row) {
const key = this.getMatrixKeyColumnName(question);
const value = this.getDefaultValueForRow(model, question, key);
row.getQuestionByName(key).value = value;
row.getQuestionByName("title").value = value;
}
onMatrixRowAdded(model, creator, options) {
var _a, _b;
if (this.isItemsMatrix(options.question.name)) {
this.setDefaultValueForRow(model, options.question, options.row);
this.editItem(model, creator, options.question, options.row, {
description: getLocString("presets.items.newItem") + " " + (((_b = (_a = options.question.data) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.title) || this.getPageShortTitle(model)),
isNew: true
});
}
}
onMatrixCellValueChanged(model, creator, options) {
if (this.needToSetActions(options.question.name)) {
const renderedRow = options.question.renderedTable.rows.find(r => r.row == options.row);
if (!renderedRow)
return;
const actions = renderedRow.cells[renderedRow.cells.length - 1].item.value.actions;
if (!actions)
return;
this.updateRowActions(options.question, options.row, actions);
}
}
showDetailPanelInPopup(matrix, row, rootElement, options) {
var _a;
const index = matrix.visibleRows.findIndex(r => r === row);
const data = matrix.value[index];
const survey = new SurveyModel({ elements: matrix.toJSON().detailElements });
survey.fitToContainer = false;
survey.showNavigationButtons = false;
survey.data = data;
survey.css = presetsCss;
survey.enterKeyAction = "loseFocus";
survey.questionErrorLocation = "bottom";
if (settings.showDialog) {
const popupModel = (_a = settings.showDialog) === null || _a === void 0 ? void 0 : _a.call(settings, {
componentName: "survey",
data: { survey: survey, model: survey },
onApply: () => {
if (survey.validate()) {
const newValue = [...matrix.value];
const newData = {};
survey.getAllQuestions().forEach(q => {
if (q.visible) {
newData[q.name] = survey.data[q.name];
}
});
const newRowValue = Object.assign(Object.assign({}, matrix.value[index]), newData);
newValue[index] = newRowValue;
matrix.value = newValue;
this.updateMatrixRowActions(matrix.survey, matrix);
return true;
}
else {
return false;
}
},
onCancel: () => {
if (options.removeOnCancel) {
matrix.removeRowUI(row);
}
return true;
},
cssClass: "sps-popup svc-property-editor svc-creator-popup",
title: options.title || getLocString("presets.editor.edit"),
displayMode: "popup"
}, rootElement);
if (survey.getAllQuestions().filter(q => !q.startWithNewLine).length > 0) {
popupModel.width = "100%";
}
if (popupModel.footerToolbar) {
const defaultActionBarCss = popupModel.footerToolbar.cssClasses;
defaultActionBarCss.item = "sps-btn";
popupModel.footerToolbar.cssClasses = defaultActionBarCss;
popupModel.footerToolbar.getActionById("apply").innerCss = "sps-btn--primary-brand";
popupModel.footerToolbar.getActionById("cancel").innerCss = "sps-btn--secondary-brand";
if (options.actions) {
popupModel.footerToolbar.actions.unshift(...options.actions);
}
}
survey.getAllPanels().forEach(q => q.visible = !q.visible);
survey.getAllQuestions().forEach(q => {
q.visible = !q.visible;
if (q.isRequired) {
q.requiredErrorText = getLocString("presets.editor.required");
}
});
}
return survey;
}
}
var listComponentCss = {
root: "sps-list__container",
itemsContainer: "sps-list",
itemsContainerFiltering: "sps-list--filtering",
emptyContainer: "sps-list__empty-container",
emptyText: "sps-list__empty-text",
filter: "sps-list__filter",
filterIcon: "sps-list__filter-icon",
filterInput: "sps-list__input",
searchClearButtonIcon: "sps-list__filter-clear-button",
loadingIndicator: "sps-list__loading-indicator",
item: "sps-list__item",
itemSelected: "sps-list__item--selected",
itemGroup: "sps-list__item--group",
itemGroupSelected: "sps-list__item--group-selected",
itemWithIcon: "sps-list__item--with-icon",
itemDisabled: "sps-list__item--disabled",
itemFocused: "sps-list__item--focused",
itemHovered: "sps-list__item--hovered",
itemTextWrap: "sps-list__item-text--wrap",
itemIcon: "sps-list__item-icon",
itemMarkerIcon: "sps-list-item__marker-icon",
itemSeparator: "sps-list__item-separator",
itemBody: "sps-list__item-body",
};
class CreatorPresetEditableCaregorizedListConfigurator extends CreatorPresetEditableList {
get defaultCategoriesMap() {
return this.defaultCategories.reduce((acc, i) => { acc[i.category] = i; return acc; }, {});
}
getDefaultItems(question) {
return (question === null || question === void 0 ? void 0 : question.name) === this.nameCategories ? this.defaultCategories : this.defaultItems;
}
get nameInnerMatrix() { return "items"; }
get nameCategories() { return this.fullPath + "_categories"; }
getMainElementNames() { return [this.nameCategories]; }
getMatrixKeyColumnName(question) {
return question.name === this.nameCategories ? "category" : "name";
}
get questionNames() {
return [this.nameCategories];
}
setupCategoryActions(model, creator, question, row, actions) {
actions.forEach(a => {
if (a.id == "remove-row") {
a.iconName = "icon-delete_24x24";
a.tooltip = getLocString("presets.items.delete");
a.innerCss = "sps-action-button sps-action-button--icon sps-action-button--danger";
}
if (a.id == "reset-to-default") {
a.action = () => { this.resetCategory(model, row); };
}
});
}
ejectRowData(question, row, remove) {
const value = question.value;
const rowDataIndex = question.visibleRows.indexOf(row);
const rowData = value[rowDataIndex];
if (remove) {
value.splice(rowDataIndex, 1);
question.value = value;
}
return rowData;
}
moveToCategory(model, question, row, categoryName, remove = false) {
const rowData = this.ejectRowData(question, row, remove);
const categories = this.getQuestionCategories(model);
const catValue = categories.value;
const general = this.findOrCreateCategory(catValue, categoryName);
general[this.nameInnerMatrix].push(rowData);
categories.value = catValue;
return categories.visibleRows.find(r => r.getValue("category") == categoryName);
}
itemMenuCategoriesEnabled(model) {
return true;
}
setSubitemsToAction(action, items) {
action.setSubItems({ items: items, cssClasses: listComponentCss });
action.markerIconName = "icon-chevronright-24x24";
}
getItemMenuActionsCore(model, question, row) {
const categoriesQuestion = this.getQuestionCategories(model);
const categories = categoriesQuestion.value;
const actions = [];
const isUnsorted = question.name == this.nameMatrix;
const hasCategories = this.itemMenuCategoriesEnabled(model);
if (!isUnsorted) {
actions.push(new Action({
id: "remove-from",
title: getLocString("presets.items.removeFrom").replace("{0}", question.title),
action: () => {
const rowDataIndex = question.visibleRows.indexOf(row);
question.removeRow(rowDataIndex);
}
}));
}
else {
if (hasCategories) {
actions.push(new Action({
id: "move-to",
title: getLocString("presets.items.moveTo"),
css: "sps-list__item--label",
enabled: false
}));
}
else {
actions.push(new Action({
id: "restore-item",
title: getLocString("presets.toolbox.addToToolbox"),
action: () => {
const rowDataIndex = question.visibleRows.indexOf(row);
question.removeRow(rowDataIndex);
}
}));
}
}
if (!hasCategories)
return actions;
const currentCategory = categories.filter(c => (c[this.nameInnerMatrix] || []).filter(i => { var _a; return i.name == ((_a = row.value) === null || _a === void 0 ? void 0 : _a.name); }).length > 0)[0];
const moveToCategories = categories.filter((i) => i.category != (currentCategory === null || currentCategory === void 0 ? void 0 : currentCategory.category)).map((i) => new Action({
id: "to-" + i.category,
title: i.title,
action: () => {
this.moveToCategory(model, question, row, i.category, true);
}
}));
if (!isUnsorted) {
actions.push(new Action({
id: "categories",
title: getLocString("presets.items.categoriesLabel"),
css: "sps-list__item--label",
enabled: false,
needSeparator: true
}));
const catGroup = new Action({
id: "move-to-categories",
title: getLocString("presets.items.moveToCategory")
});
this.setSubitemsToAction(catGroup, moveToCategories);
actions.push(catGroup);
}
else {
actions.push(...moveToCategories);
}
actions.push(new Action({
id: "move-to-new-category",
title: getLocString("presets.items.moveToNewCategory"),
needSeparator: isUnsorted,
action: () => {
const newCatRow = this.moveToCategory(model, question, row, this.getDefaultValueForRow(model, question, "category"), true);
this.editItem(model, null, categoriesQuestion, newCatRow, {
description: getLocString("presets.items.newCategory") + " " + this.getPageShortTitle(model),
isNew: true
});
}
}));
return actions;
}
getItemMenuActions(model, question, row) {
const actions = this.getItemMenuActionsCore(model, question, row);
if (!this.getDefaultItem(question, row.value.name)) {
actions.push(new Action({
id: "remove-custom-item",
title: getLocString("presets.toolbox.deleteCustomItem"),
css: "sps-list__item--alert",
needSeparator: true,
action: () => {
this.ejectRowData(question, row, true);
}
}));
}
return actions;
}
replaceRemoveAction(model, question, row, actions) {
const originalAction = actions.filter(a => a.id == "remove-row")[0];
if (originalAction) {
originalAction.visible = false;
const addAction = createDropdownActionModel({
id: "context-menu",
iconName: "more-circle-24x24",
tooltip: getLocString("presets.items.more"),
location: "end",
visibleIndex: 20
}, {
items: [],
showPointer: false,
verticalPosition: "bottom",
horizontalPosition: "center",
cssClass: "sps-popup-menu sps-popup-menu--context",
cssClasses: listComponentCss,
searchEnabled: false
});
addAction.popupModel.onVisibilityChanged.add((_, opt) => {
if (opt.isVisible) {
const listModel = opt.model.contentComponentData.model;
listModel.actions = this.getItemMenuActions(model, question, row);
listModel.flushUpdates();
}
});
actions.push(addAction);
}
}
getQuestionCategories(model) { return model.getQuestionByName(this.nameCategories); }
isItemsMatrix(name) {
return super.isItemsMatrix(name) || name === this.nameInnerMatrix;
}
resetCategory(model, row) {
var _a;
const category = row.getValue("category");
const defaultItems = (_a = this.defaultCategories.filter(i => i.category == category)[0]) === null || _a === void 0 ? void 0 : _a[this.nameInnerMatrix];
if (!defaultItems)
return;
const categoriesQuestion = this.getQuestionCategories(model);
const hiddenItemsQuestion = this.getMatrix(model);
const hiddenValue = hiddenItemsQuestion.value || [];
const value = categoriesQuestion.value;
const categoryRow = value.filter(v => v.category == category)[0];
categoryRow[this.nameInnerMatrix].forEach(i => {
if (!defaultItems.some(di => di.name == i.name)) {
hiddenValue.push(i);
}
});
categoryRow[this.nameInnerMatrix] = defaultItems;
function clearItemFromDefault(items) {
if (!items)
return;
defaultItems.forEach(di => {
const index = items.findIndex(i => i.name == di.name);
if (index >= 0)
items.splice(index, 1);
});
}
value.filter(v => v.category != category).forEach(v => {
defaultItems.forEach(di => {
clearItemFromDefault(v[this.nameInnerMatrix]);
});
});
clearItemFromDefault(hiddenValue);
hiddenItemsQuestion.value = hiddenValue;
categoriesQuestion.value = value;
this.notifyCallback(getLocString("presets.editor.categoryRestoredToDefault"));
}
findOrCreateCategory(categories, category) {
let generalCategory = categories.filter(c => c.category == category)[0];
if (!generalCategory) {
generalCategory = { category: category || "general", title: category || "General", [this.nameInnerMatrix]: [] };
categories.push(generalCategory);
}
return generalCategory;
}
needToSetActions(name) {
return this.isItemsMatrix(name) || name === this.nameCategories;
}
onGetMatrixRowActionsCore(model, creator, options) {
super.onGetMatrixRowActionsCore(model, creator, options);
if (options.question.name === this.nameCategories) {
this.setupCategoryActions(model, creator, options.question, options.row, options.actions);
}
if (this.isItemsMatrix(options.question.name)) {
this.replaceRemoveAction(model, options.question, options.row, options.actions);
}
}
getExistingKeys(model, key) {
const cats = model.getQuestionByName(this.nameCategories).value || [];
const unsorted = model.getQuestionByName(this.nameMatrix).value || [];
return [...cats, ...cats.map(c => c.items).flat().filter(key => !!key), ...unsorted];
}
onMatrixRowRemoving(model, creator, options) {
super.onMatrixRowRemoving(model, creator, options);
if (options.question.name == this.nameCategories) {
const items = options.question.value[options.rowIndex][this.nameInnerMatrix];
if (items) {
const hiddenItems = this.getMatrix(model);
const value = hiddenItems.value ? hiddenItems.value.concat(items) : items;
hiddenItems.value = value;
}
}
if (options.question.name == this.nameMatrix) {
const rowData = options.question.value[options.rowIndex];
const defaultCategory = this.defaultCategories.filter(c => c[this.nameInnerMatrix].filter(i => i.name == rowData.name).length > 0)[0];
this.moveToCategory(model, options.question, options.row, defaultCategory === null || defaultCategory === void 0 ? void 0 : defaultCategory.category);
}
}
onMatrixRowAdded(model, creator, options) {
super.onMatrixRowAdded(model, creator, options);
if (options.question.name == this.nameCategories) {
this.setDefaultValueForRow(model, options.question, options.row);
this.editItem(model, creator, options.question, options.row, {
description: getLocString("presets.items.newCategory") + " " + this.getPageShortTitle(model),
isNew: true
});
}
}
}
const LocCategoriesName = "toolboxCategories";
function validateToolboxJson(params) {
const value = params[0];
if (!value || !value.type)
return true;
const obj = Serializer.createClas