UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,144 lines (1,140 loc) • 53.3 kB
/** * DevExtreme (cjs/__internal/ui/form/m_form.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("../../../ui/validation_summary"); require("../../../ui/validation_group"); require("../../ui/form/m_form.layout_manager"); var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _visibility_change = require("../../../common/core/events/visibility_change"); var _message = _interopRequireDefault(require("../../../common/core/localization/message")); var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator")); var _config = _interopRequireDefault(require("../../../core/config")); var _element = require("../../../core/element"); var _guid = _interopRequireDefault(require("../../../core/guid")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _resize_observer = _interopRequireDefault(require("../../../core/resize_observer")); var _common = require("../../../core/utils/common"); var _deferred = require("../../../core/utils/deferred"); var _extend = require("../../../core/utils/extend"); var _iterator = require("../../../core/utils/iterator"); var _type = require("../../../core/utils/type"); var _window = require("../../../core/utils/window"); var _editor = _interopRequireDefault(require("../../../ui/editor/editor")); var _tab_panel = _interopRequireDefault(require("../../../ui/tab_panel")); var _themes = require("../../../ui/themes"); var _validation_engine = _interopRequireDefault(require("../../../ui/validation_engine")); var _widget = _interopRequireWildcard(require("../../core/widget/widget")); var _m_drop_down_editor = require("../../ui/drop_down_editor/m_drop_down_editor"); var _m_label = require("../../ui/form/components/m_label"); var _constants = require("../../ui/form/constants"); var _m_form2 = _interopRequireDefault(require("../../ui/form/m_form.item_options_actions")); var _m_form3 = _interopRequireDefault(require("../../ui/form/m_form.items_runtime_info")); var _m_formLayout_manager = require("../../ui/form/m_form.layout_manager.utils"); var _m_form4 = require("../../ui/form/m_form.utils"); var _m_scrollable = _interopRequireDefault(require("../../ui/scroll_view/m_scrollable")); var _m_text_editor = require("../../ui/text_box/m_text_editor.base"); var _m_constants = require("../../ui/toolbar/m_constants"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) { return null } var r = new WeakMap, t = new WeakMap; return (_getRequireWildcardCache = function(e) { return e ? t : r })(e) } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) { return e } if (null === e || "object" != typeof e && "function" != typeof e) { return { default: e } } var t = _getRequireWildcardCache(r); if (t && t.has(e)) { return t.get(e) } var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) { if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u] } } return n.default = e, t && t.set(e, n), n } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const ITEM_OPTIONS_FOR_VALIDATION_UPDATING = ["items", "isRequired", "validationRules", "visible"]; class Form extends _widget.default { _init() { super._init(); this._dirtyFields = new Set; this._cachedColCountOptions = []; this._itemsRunTimeInfo = new _m_form3.default; this._groupsColCount = []; this._attachSyncSubscriptions() } _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { formID: `dx-${new _guid.default}`, formData: {}, colCount: 1, screenByWidth: _window.defaultScreenFactorFunc, labelLocation: "left", readOnly: false, onFieldDataChanged: null, customizeItem: null, onEditorEnterKey: null, minColWidth: 200, alignItemLabels: true, alignItemLabelsInAllGroups: true, alignRootItemLabels: true, showColonAfterLabel: true, showRequiredMark: true, showOptionalMark: false, requiredMark: "*", optionalMark: _message.default.format("dxForm-optionalMark"), requiredMessage: _message.default.getFormatter("dxForm-requiredMessage"), showValidationSummary: false, scrollingEnabled: false, stylingMode: (0, _config.default)().editorStylingMode, labelMode: "outside", isDirty: false }) } _defaultOptionsRules() { return super._defaultOptionsRules().concat([{ device: () => (0, _themes.isMaterialBased)(), options: { labelLocation: "top" } }, { device: () => (0, _themes.isMaterial)(), options: { showColonAfterLabel: false } }]) } _setOptionsByReference() { super._setOptionsByReference(); (0, _extend.extend)(this._optionsByReference, { formData: true, validationGroup: true }) } _getGroupColCount($element) { return parseInt($element.attr(_constants.GROUP_COL_COUNT_ATTR)) } _applyLabelsWidthByCol($container, index) { let options = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}; let labelMarkOptions = arguments.length > 3 ? arguments[3] : void 0; const fieldItemClass = options.inOneColumn ? _constants.FIELD_ITEM_CLASS : _constants.FORM_FIELD_ITEM_COL_CLASS + index; const cssExcludeTabbedSelector = options.excludeTabbed ? `:not(.${_constants.FIELD_ITEM_TAB_CLASS})` : ""; (0, _m_label.setLabelWidthByMaxLabelWidth)($container, `.${fieldItemClass}${cssExcludeTabbedSelector}`, labelMarkOptions) } _applyLabelsWidth($container, excludeTabbed, inOneColumn, colCount, labelMarkOptions) { colCount = inOneColumn ? 1 : colCount || this._getGroupColCount($container); const applyLabelsOptions = { excludeTabbed: excludeTabbed, inOneColumn: inOneColumn }; let i; for (i = 0; i < colCount; i++) { this._applyLabelsWidthByCol($container, i, applyLabelsOptions, labelMarkOptions) } } _getGroupElementsInColumn($container, columnIndex, colCount) { const cssColCountSelector = (0, _type.isDefined)(colCount) ? `.${_constants.GROUP_COL_COUNT_CLASS}${colCount}` : ""; const groupSelector = `.${_constants.FORM_FIELD_ITEM_COL_CLASS}${columnIndex} > .${_constants.FIELD_ITEM_CONTENT_CLASS} > .${_constants.FORM_GROUP_CLASS}${cssColCountSelector}`; return $container.find(groupSelector) } _applyLabelsWidthWithGroups($container, colCount, excludeTabbed, labelMarkOptions) { const { alignRootItemLabels: alignRootItemLabels } = this.option(); if (true === alignRootItemLabels) { const $rootSimpleItems = $container.find(`.${_constants.ROOT_SIMPLE_ITEM_CLASS}`); for (let colIndex = 0; colIndex < colCount; colIndex++) { this._applyLabelsWidthByCol($rootSimpleItems, colIndex, excludeTabbed, labelMarkOptions) } } const alignItemLabelsInAllGroups = this.option("alignItemLabelsInAllGroups"); if (alignItemLabelsInAllGroups) { this._applyLabelsWidthWithNestedGroups($container, colCount, excludeTabbed, labelMarkOptions) } else { const $groups = this.$element().find(`.${_constants.FORM_GROUP_CLASS}`); let i; for (i = 0; i < $groups.length; i++) { this._applyLabelsWidth($groups.eq(i), excludeTabbed, void 0, void 0, labelMarkOptions) } } } _applyLabelsWidthWithNestedGroups($container, colCount, excludeTabbed, labelMarkOptions) { const applyLabelsOptions = { excludeTabbed: excludeTabbed }; let colIndex; let groupsColIndex; let groupColIndex; let $groupsByCol; for (colIndex = 0; colIndex < colCount; colIndex++) { $groupsByCol = this._getGroupElementsInColumn($container, colIndex); this._applyLabelsWidthByCol($groupsByCol, 0, applyLabelsOptions, labelMarkOptions); for (groupsColIndex = 0; groupsColIndex < this._groupsColCount.length; groupsColIndex++) { $groupsByCol = this._getGroupElementsInColumn($container, colIndex, this._groupsColCount[groupsColIndex]); const groupColCount = this._getGroupColCount($groupsByCol); for (groupColIndex = 1; groupColIndex < groupColCount; groupColIndex++) { this._applyLabelsWidthByCol($groupsByCol, groupColIndex, applyLabelsOptions, labelMarkOptions) } } } } _labelLocation() { const { labelLocation: labelLocation } = this.option(); return labelLocation } _alignLabelsInColumn(_ref) { let { layoutManager: layoutManager, inOneColumn: inOneColumn, $container: $container, excludeTabbed: excludeTabbed, items: items } = _ref; if (!(0, _window.hasWindow)() || "top" === this._labelLocation()) { return } const labelMarkOptions = (0, _m_formLayout_manager.convertToLabelMarkOptions)(layoutManager._getMarkOptions()); if (inOneColumn) { this._applyLabelsWidth($container, excludeTabbed, true, void 0, labelMarkOptions) } else if (this._checkGrouping(items)) { this._applyLabelsWidthWithGroups($container, layoutManager._getColCount(), excludeTabbed, labelMarkOptions) } else { this._applyLabelsWidth($container, excludeTabbed, false, layoutManager._getColCount(), labelMarkOptions) } } _prepareFormData() { if (!(0, _type.isDefined)(this.option("formData"))) { this.option("formData", {}) } } _setStylingModeClass() { const { stylingMode: stylingMode } = this.option(); if ("underlined" === stylingMode) { this.$element().addClass(_constants.FORM_UNDERLINED_CLASS) } } _initMarkup() { _validation_engine.default.addGroup(this._getValidationGroup(), false); this._clearCachedInstances(); this._prepareFormData(); this.$element().addClass(_constants.FORM_CLASS); this._setStylingModeClass(); super._initMarkup(); this.setAria("role", "form", this.$element()); if (this.option("scrollingEnabled")) { this._renderScrollable() } this._renderLayout(); this._renderValidationSummary(); this._lastMarkupScreenFactor = this._targetScreenFactor || this._getCurrentScreenFactor(); this._attachResizeObserverSubscription() } _attachResizeObserverSubscription() { if ((0, _window.hasWindow)()) { const formRootElement = this.$element().get(0); _resize_observer.default.unobserve(formRootElement); _resize_observer.default.observe(formRootElement, (() => { this._resizeHandler() })) } } _resizeHandler() { if (this._cachedLayoutManagers.length) { (0, _iterator.each)(this._cachedLayoutManagers, ((_, layoutManager) => { var _layoutManager$option; null === (_layoutManager$option = layoutManager.option("onLayoutChanged")) || void 0 === _layoutManager$option || _layoutManager$option(layoutManager.isSingleColumnMode()) })) } } _getCurrentScreenFactor() { return (0, _window.hasWindow)() ? (0, _window.getCurrentScreenFactor)(this.option("screenByWidth")) : "lg" } _clearCachedInstances() { this._itemsRunTimeInfo.clear(); this._cachedLayoutManagers = [] } _alignLabels(layoutManager, inOneColumn) { this._alignLabelsInColumn({ $container: this.$element(), layoutManager: layoutManager, excludeTabbed: true, items: this.option("items"), inOneColumn: inOneColumn }); (0, _visibility_change.triggerResizeEvent)(this.$element().find(`.${_m_constants.TOOLBAR_CLASS}`)) } _clean() { this._clearValidationSummary(); super._clean(); this._groupsColCount = []; this._cachedColCountOptions = []; this._lastMarkupScreenFactor = void 0; _resize_observer.default.unobserve(this.$element().get(0)) } _renderScrollable() { const useNativeScrolling = this.option("useNativeScrolling"); this._scrollable = new _m_scrollable.default(this.$element(), { useNative: !!useNativeScrolling, useSimulatedScrollbar: !useNativeScrolling, useKeyboard: false, direction: "both", bounceEnabled: false }) } _getContent() { var _this$_scrollable; return this.option("scrollingEnabled") ? (0, _renderer.default)(null === (_this$_scrollable = this._scrollable) || void 0 === _this$_scrollable ? void 0 : _this$_scrollable.content()) : this.$element() } _clearValidationSummary() { var _this$_$validationSum; null === (_this$_$validationSum = this._$validationSummary) || void 0 === _this$_$validationSum || _this$_$validationSum.remove(); this._$validationSummary = void 0; this._validationSummary = void 0 } _renderValidationSummary() { this._clearValidationSummary(); if (this.option("showValidationSummary")) { this._$validationSummary = (0, _renderer.default)("<div>").addClass(_constants.FORM_VALIDATION_SUMMARY).appendTo(this._getContent()); this._validationSummary = this._$validationSummary.dxValidationSummary({ validationGroup: this._getValidationGroup() }).dxValidationSummary("instance") } } _prepareItems(items, parentIsTabbedItem, currentPath, isTabs) { if (items) { const result = []; for (let i = 0; i < items.length; i++) { let item = items[i]; const path = (0, _m_form4.concatPaths)(currentPath, (0, _m_form4.createItemPathByIndex)(i, isTabs)); const itemRunTimeInfo = { item: item, itemIndex: i, path: path }; const guid = this._itemsRunTimeInfo.add(itemRunTimeInfo); if ((0, _type.isString)(item)) { item = { dataField: item } } if ((0, _type.isObject)(item)) { const preparedItem = _extends({}, item); itemRunTimeInfo.preparedItem = preparedItem; preparedItem.guid = guid; this._tryPrepareGroupItemCaption(preparedItem); this._tryPrepareGroupItem(preparedItem); this._tryPrepareTabbedItem(preparedItem, path); this._tryPrepareItemTemplate(preparedItem); if (parentIsTabbedItem) { preparedItem.cssItemClass = _constants.FIELD_ITEM_TAB_CLASS } if (preparedItem.items) { preparedItem.items = this._prepareItems(preparedItem.items, parentIsTabbedItem, path) } result.push(preparedItem) } else { result.push(item) } } return result } } _tryPrepareGroupItemCaption(item) { if ("group" === item.itemType) { item._prepareGroupCaptionTemplate = captionTemplate => { if (item.captionTemplate) { item.groupCaptionTemplate = this._getTemplate(captionTemplate) } item.captionTemplate = this._itemGroupTemplate.bind(this, item) }; item._prepareGroupCaptionTemplate(item.captionTemplate) } } _tryPrepareGroupItem(item) { if ("group" === item.itemType) { item.alignItemLabels = (0, _common.ensureDefined)(item.alignItemLabels, true); item._prepareGroupItemTemplate = itemTemplate => { if (item.template) { item.groupContentTemplate = this._getTemplate(itemTemplate) } item.template = this._itemGroupTemplate.bind(this, item) }; item._prepareGroupItemTemplate(item.template) } } _tryPrepareTabbedItem(item, path) { if ("tabbed" === item.itemType) { item.template = this._itemTabbedTemplate.bind(this, item); item.tabs = this._prepareItems(item.tabs, true, path, true) } } _tryPrepareItemTemplate(item) { if (item.template) { item.template = this._getTemplate(item.template) } } _checkGrouping(items) { if (items) { for (let i = 0; i < items.length; i++) { const item = items[i]; if ("group" === item.itemType) { return true } } } } _renderLayout() { const that = this; let items = that.option("items"); const $content = that._getContent(); items = that._prepareItems(items); that._rootLayoutManager = that._renderLayoutManager($content, this._createLayoutManagerOptions(items, { isRoot: true, colCount: that.option("colCount"), alignItemLabels: that.option("alignItemLabels"), screenByWidth: this.option("screenByWidth"), colCountByScreen: this.option("colCountByScreen"), onLayoutChanged(inOneColumn) { that._alignLabels.bind(that)(that._rootLayoutManager, inOneColumn) }, onContentReady(e) { that._alignLabels(e.component, e.component.isSingleColumnMode()) } })) } _tryGetItemsForTemplate(item) { return item.items || [] } _itemTabbedTemplate(item, e, $container) { const $tabPanel = (0, _renderer.default)("<div>").appendTo($container); const tabPanelOptions = (0, _extend.extend)({}, item.tabPanelOptions, { dataSource: item.tabs, onItemRendered: args => { var _item$tabPanelOptions, _item$tabPanelOptions2; null === (_item$tabPanelOptions = item.tabPanelOptions) || void 0 === _item$tabPanelOptions || null === (_item$tabPanelOptions2 = _item$tabPanelOptions.onItemRendered) || void 0 === _item$tabPanelOptions2 || _item$tabPanelOptions2.call(_item$tabPanelOptions, args); (0, _visibility_change.triggerShownEvent)(args.itemElement) }, itemTemplate: (itemData, e, container) => { const $container = (0, _renderer.default)(container); const alignItemLabels = (0, _common.ensureDefined)(itemData.alignItemLabels, true); const layoutManager = this._renderLayoutManager($container, this._createLayoutManagerOptions(this._tryGetItemsForTemplate(itemData), { colCount: itemData.colCount, alignItemLabels: alignItemLabels, screenByWidth: this.option("screenByWidth"), colCountByScreen: itemData.colCountByScreen, cssItemClass: itemData.cssItemClass, onLayoutChanged: inOneColumn => { this._alignLabelsInColumn({ $container: $container, layoutManager: layoutManager, items: itemData.items, inOneColumn: inOneColumn }) } })); if (this._itemsRunTimeInfo) { this._itemsRunTimeInfo.extendRunTimeItemInfoByKey(itemData.guid, { layoutManager: layoutManager }) } if (alignItemLabels) { this._alignLabelsInColumn({ $container: $container, layoutManager: layoutManager, items: itemData.items, inOneColumn: layoutManager.isSingleColumnMode() }) } } }); const tryUpdateTabPanelInstance = (items, instance) => { if (Array.isArray(items)) { items.forEach((item => this._itemsRunTimeInfo.extendRunTimeItemInfoByKey(item.guid, { widgetInstance: instance }))) } }; const tabPanel = this._createComponent($tabPanel, _tab_panel.default, tabPanelOptions); (0, _renderer.default)($container).parent().addClass(_constants.FIELD_ITEM_CONTENT_HAS_TABS_CLASS); tabPanel.on("optionChanged", (e => { if ("dataSource" === e.fullName) { tryUpdateTabPanelInstance(e.value, e.component) } })); tryUpdateTabPanelInstance([{ guid: item.guid }, ...item.tabs ?? []], tabPanel) } _itemGroupCaptionTemplate(item, $group, id) { if (item.groupCaptionTemplate) { const $captionTemplate = (0, _renderer.default)("<div>").addClass(_constants.FORM_GROUP_CUSTOM_CAPTION_CLASS).attr("id", id).appendTo($group); item._renderGroupCaptionTemplate = () => { const data = { component: this, caption: item.caption, name: item.name }; item.groupCaptionTemplate.render({ model: data, container: (0, _element.getPublicElement)($captionTemplate) }) }; item._renderGroupCaptionTemplate(); return } if (item.caption) { (0, _renderer.default)("<span>").addClass(_constants.FORM_GROUP_CAPTION_CLASS).text(item.caption).attr("id", id).appendTo($group) } } _itemGroupContentTemplate(item, $group) { const $groupContent = (0, _renderer.default)("<div>").addClass(_constants.FORM_GROUP_CONTENT_CLASS).appendTo($group); if (item.groupContentTemplate) { item._renderGroupContentTemplate = () => { $groupContent.empty(); const data = { formData: this.option("formData"), component: this }; item.groupContentTemplate.render({ model: data, container: (0, _element.getPublicElement)($groupContent) }) }; item._renderGroupContentTemplate() } else { var _this$_itemsRunTimeIn; const layoutManager = this._renderLayoutManager($groupContent, this._createLayoutManagerOptions(this._tryGetItemsForTemplate(item), { colCount: item.colCount, colCountByScreen: item.colCountByScreen, alignItemLabels: item.alignItemLabels, cssItemClass: item.cssItemClass })); null === (_this$_itemsRunTimeIn = this._itemsRunTimeInfo) || void 0 === _this$_itemsRunTimeIn || _this$_itemsRunTimeIn.extendRunTimeItemInfoByKey(item.guid, { layoutManager: layoutManager }); const colCount = layoutManager._getColCount(); if (!this._groupsColCount.includes(colCount)) { this._groupsColCount.push(colCount) } $group.addClass(_constants.GROUP_COL_COUNT_CLASS + colCount); $group.attr(_constants.GROUP_COL_COUNT_ATTR, colCount) } } _itemGroupTemplate(item, options, $container) { const { id: id } = options.editorOptions.inputAttr; const $group = (0, _renderer.default)("<div>").toggleClass(_constants.FORM_GROUP_WITH_CAPTION_CLASS, (0, _type.isDefined)(item.caption) && item.caption.length).addClass(_constants.FORM_GROUP_CLASS).appendTo($container); const groupAria = { role: "group", labelledby: id }; this.setAria(groupAria, $group); (0, _renderer.default)($container).parent().addClass(_constants.FIELD_ITEM_CONTENT_HAS_GROUP_CLASS); this._itemGroupCaptionTemplate(item, $group, id); this._itemGroupContentTemplate(item, $group) } _createLayoutManagerOptions(items, extendedLayoutManagerOptions) { return (0, _m_form4.convertToLayoutManagerOptions)({ form: this, formOptions: this.option(), $formElement: this.$element(), items: items, validationGroup: this._getValidationGroup(), extendedLayoutManagerOptions: extendedLayoutManagerOptions, onFieldDataChanged: args => { if (!this._isDataUpdating) { this._triggerOnFieldDataChanged(args) } }, onContentReady: args => { var _extendedLayoutManage; this._itemsRunTimeInfo.addItemsOrExtendFrom(args.component._itemsRunTimeInfo); null === (_extendedLayoutManage = extendedLayoutManagerOptions.onContentReady) || void 0 === _extendedLayoutManage || _extendedLayoutManage.call(extendedLayoutManagerOptions, args) }, onDisposing: _ref2 => { let { component: component } = _ref2; const nestedItemsRunTimeInfo = component.getItemsRunTimeInfo(); this._itemsRunTimeInfo.removeItemsByItems(nestedItemsRunTimeInfo) }, onFieldItemRendered: () => { var _this$_validationSumm; null === (_this$_validationSumm = this._validationSummary) || void 0 === _this$_validationSumm || _this$_validationSumm.refreshValidationGroup() } }) } _renderLayoutManager($parent, layoutManagerOptions) { const baseColCountByScreen = { lg: layoutManagerOptions.colCount, md: layoutManagerOptions.colCount, sm: layoutManagerOptions.colCount, xs: 1 }; this._cachedColCountOptions.push({ colCountByScreen: (0, _extend.extend)(baseColCountByScreen, layoutManagerOptions.colCountByScreen) }); const $element = (0, _renderer.default)("<div>"); $element.appendTo($parent); const instance = this._createComponent($element, "dxLayoutManager", layoutManagerOptions); instance.on("autoColCountChanged", (() => { this._clearAutoColCountChangedTimeout(); this.autoColCountChangedTimeoutId = setTimeout((() => !this._disposed && this._refresh()), 0) })); this._cachedLayoutManagers.push(instance); return instance } _getValidationGroup() { return this.option("validationGroup") || this } _createComponent($element, type, config) { config = config || {}; this._extendConfig(config, { readOnly: this.option("readOnly") }); return super._createComponent($element, type, config) } _attachSyncSubscriptions() { const that = this; that.on("optionChanged", (args => { const optionFullName = args.fullName; if ("formData" === optionFullName) { if (!(0, _type.isDefined)(args.value)) { that._options.silent("formData", args.value = {}) } that._triggerOnFieldDataChangedByDataSet(args.value) } if (that._cachedLayoutManagers.length) { (0, _iterator.each)(that._cachedLayoutManagers, ((index, layoutManager) => { if ("formData" === optionFullName) { that._isDataUpdating = true; layoutManager.option("layoutData", args.value); that._isDataUpdating = false } if ("readOnly" === args.name || "disabled" === args.name) { layoutManager.option(optionFullName, args.value) } })) } })) } _optionChanged(args) { const splitFullName = args.fullName.split("."); if (splitFullName.length > 1 && -1 !== splitFullName[0].search("items") && this._itemsOptionChangedHandler(args)) { return } if (splitFullName.length > 1 && -1 !== splitFullName[0].search("formData") && this._formDataOptionChangedHandler(args)) { return } this._defaultOptionChangedHandler(args) } _defaultOptionChangedHandler(args) { switch (args.name) { case "formData": if (!this.option("items")) { this._invalidate() } else if ((0, _type.isEmptyObject)(args.value)) { this._clear() } break; case "onFieldDataChanged": case "alignRootItemLabels": case "readOnly": case "isDirty": break; case "items": case "colCount": case "onEditorEnterKey": case "labelLocation": case "labelMode": case "alignItemLabels": case "showColonAfterLabel": case "customizeItem": case "alignItemLabelsInAllGroups": case "showRequiredMark": case "showOptionalMark": case "requiredMark": case "optionalMark": case "requiredMessage": case "scrollingEnabled": case "formID": case "colCountByScreen": case "screenByWidth": case "stylingMode": this._invalidate(); break; case "showValidationSummary": this._renderValidationSummary(); break; case "minColWidth": { const { colCount: colCount } = this.option(); if ("auto" === colCount) { this._invalidate() } break } case "width": super._optionChanged(args); this._rootLayoutManager.option(args.name, args.value); this._alignLabels(this._rootLayoutManager, this._rootLayoutManager.isSingleColumnMode()); break; case "validationGroup": _validation_engine.default.removeGroup(args.previousValue || this); this._invalidate(); break; default: super._optionChanged(args) } } _itemsOptionChangedHandler(args) { const nameParts = args.fullName.split("."); const { value: value } = args; const itemPath = this._getItemPath(nameParts); const item = this.option(itemPath); const optionNameWithoutPath = args.fullName.replace(`${itemPath}.`, ""); const simpleOptionName = optionNameWithoutPath.split(".")[0].replace(/\[\d+]/, ""); const itemAction = this._tryCreateItemOptionAction(simpleOptionName, item, item[simpleOptionName], args.previousValue, itemPath); let result = this._tryExecuteItemOptionAction(itemAction) || this._tryChangeLayoutManagerItemOption(args.fullName, value); if (!result && item) { this._changeItemOption(item, optionNameWithoutPath, value); const items = this._generateItemsFromData(this.option("items")); this.option("items", items); result = true } return result } _formDataOptionChangedHandler(args) { const nameParts = args.fullName.split("."); const { value: value } = args; const dataField = nameParts.slice(1).join("."); const editor = this.getEditor(dataField); if (editor) { editor.option("value", value) } else { this._triggerOnFieldDataChanged({ dataField: dataField, value: value }) } return true } _tryCreateItemOptionAction(optionName, item, value, previousValue, itemPath) { if ("tabs" === optionName) { this._itemsRunTimeInfo.removeItemsByPathStartWith(`${itemPath}.tabs`); value = this._prepareItems(value, true, itemPath, true) } return (0, _m_form2.default)(optionName, { item: item, value: value, previousValue: previousValue, itemsRunTimeInfo: this._itemsRunTimeInfo }) } _tryExecuteItemOptionAction(action) { return null === action || void 0 === action ? void 0 : action.tryExecute() } _updateValidationGroupAndSummaryIfNeeded(fullName) { const optionName = (0, _m_form4.getOptionNameFromFullName)(fullName); if (ITEM_OPTIONS_FOR_VALIDATION_UPDATING.includes(optionName)) { _validation_engine.default.addGroup(this._getValidationGroup(), false); if (this.option("showValidationSummary")) { var _this$_validationSumm2; null === (_this$_validationSumm2 = this._validationSummary) || void 0 === _this$_validationSumm2 || _this$_validationSumm2.refreshValidationGroup() } } } _setLayoutManagerItemOption(layoutManager, optionName, value, path) { if (this._updateLockCount > 0) { !layoutManager._updateLockCount && layoutManager.beginUpdate(); const key = this._itemsRunTimeInfo.findKeyByPath(path); this.postponedOperations.add(key, (() => { !layoutManager._disposed && layoutManager.endUpdate(); return (0, _deferred.Deferred)().resolve() })) } const contentReadyHandler = e => { e.component.off("contentReady", contentReadyHandler); if ((0, _m_form4.isFullPathContainsTabs)(path)) { const tabPath = (0, _m_form4.tryGetTabPath)(path); const tabLayoutManager = this._itemsRunTimeInfo.findGroupOrTabLayoutManagerByPath(tabPath); if (tabLayoutManager) { this._alignLabelsInColumn({ items: tabLayoutManager.option("items"), layoutManager: tabLayoutManager, $container: tabLayoutManager.$element(), inOneColumn: tabLayoutManager.isSingleColumnMode() }) } } else { this._alignLabels(this._rootLayoutManager, this._rootLayoutManager.isSingleColumnMode()) } }; layoutManager.on("contentReady", contentReadyHandler); layoutManager.option(optionName, value); this._updateValidationGroupAndSummaryIfNeeded(optionName) } _tryChangeLayoutManagerItemOption(fullName, value) { const nameParts = fullName.split("."); const optionName = (0, _m_form4.getOptionNameFromFullName)(fullName); if ("items" === optionName && nameParts.length > 1) { const itemPath = this._getItemPath(nameParts); const layoutManager = this._itemsRunTimeInfo.findGroupOrTabLayoutManagerByPath(itemPath); if (layoutManager) { this._itemsRunTimeInfo.removeItemsByItems(layoutManager.getItemsRunTimeInfo()); const items = this._prepareItems(value, false, itemPath); this._setLayoutManagerItemOption(layoutManager, optionName, items, itemPath); return true } } else if (nameParts.length > 2) { const endPartIndex = nameParts.length - 2; const itemPath = this._getItemPath(nameParts.slice(0, endPartIndex)); const layoutManager = this._itemsRunTimeInfo.findGroupOrTabLayoutManagerByPath(itemPath); if (layoutManager) { const fullOptionName = (0, _m_form4.getFullOptionName)(nameParts[endPartIndex], optionName); if ("editorType" === optionName) { if (layoutManager.option(fullOptionName) !== value) { return false } } if ("visible" === optionName) { const formItems = this.option((0, _m_form4.getFullOptionName)(itemPath, "items")); if (null !== formItems && void 0 !== formItems && formItems.length) { const layoutManagerItems = layoutManager.option("items"); formItems.forEach(((item, index) => { const layoutItem = layoutManagerItems[index]; layoutItem.visibleIndex = item.visibleIndex })) } } this._setLayoutManagerItemOption(layoutManager, fullOptionName, value, itemPath); return true } } return false } _tryChangeLayoutManagerItemOptions(itemPath, options) { let result; this.beginUpdate(); (0, _iterator.each)(options, ((optionName, optionValue) => { result = this._tryChangeLayoutManagerItemOption((0, _m_form4.getFullOptionName)(itemPath, optionName), optionValue); if (!result) { return false } })); this.endUpdate(); return result } _getItemPath(nameParts) { let itemPath = nameParts[0]; let i; for (i = 1; i < nameParts.length; i++) { if (-1 !== nameParts[i].search(/items\[\d+]|tabs\[\d+]/)) { itemPath += `.${nameParts[i]}` } else { break } } return itemPath } _triggerOnFieldDataChanged(args) { this._updateIsDirty(args.dataField); this._createActionByOption("onFieldDataChanged")(args) } _triggerOnFieldDataChangedByDataSet(data) { if (data && (0, _type.isObject)(data)) { Object.keys(data).forEach((key => { this._triggerOnFieldDataChanged({ dataField: key, value: data[key] }) })) } } _updateFieldValue(dataField, value) { if ((0, _type.isDefined)(this.option("formData"))) { const editor = this.getEditor(dataField); this.option(`formData.${dataField}`, value); if (editor) { const editorValue = editor.option("value"); if (editorValue !== value) { editor.option("value", value) } } } } _generateItemsFromData(items) { const formData = this.option("formData"); const result = []; if (!items && (0, _type.isDefined)(formData)) { (0, _iterator.each)(formData, (dataField => { result.push({ dataField: dataField }) })) } if (items) { (0, _iterator.each)(items, ((index, item) => { if ((0, _type.isObject)(item)) { result.push(item) } else { result.push({ dataField: item }) } })) } return result } _getItemByField(field, items) { const that = this; const fieldParts = (0, _type.isObject)(field) ? field : that._getFieldParts(field); const { fieldName: fieldName } = fieldParts; const { fieldPath: fieldPath } = fieldParts; let resultItem; if (items.length) { (0, _iterator.each)(items, ((index, item) => { const { itemType: itemType } = item; if (fieldPath.length) { const path = fieldPath.slice(); item = that._getItemByFieldPath(path, fieldName, item) } else if ("group" === itemType && !(item.caption || item.name) || "tabbed" === itemType && !item.name) { const subItemsField = that._getSubItemField(itemType); item.items = that._generateItemsFromData(item.items); item = that._getItemByField({ fieldName: fieldName, fieldPath: fieldPath }, item[subItemsField]) } if ((0, _m_form4.isEqualToDataFieldOrNameOrTitleOrCaption)(item, fieldName)) { resultItem = item; return false } })) } return resultItem } _getFieldParts(field) { let fieldName = field; let separatorIndex = fieldName.indexOf("."); const resultPath = []; while (-1 !== separatorIndex) { resultPath.push(fieldName.substr(0, separatorIndex)); fieldName = fieldName.substr(separatorIndex + 1); separatorIndex = fieldName.indexOf(".") } return { fieldName: fieldName, fieldPath: resultPath.reverse() } } _getItemByFieldPath(path, fieldName, item) { const that = this; const { itemType: itemType } = item; const subItemsField = that._getSubItemField(itemType); const isItemWithSubItems = "group" === itemType || "tabbed" === itemType || item.title; let result; do { if (isItemWithSubItems) { const name = item.name || item.caption || item.title; const isGroupWithName = (0, _type.isDefined)(name); const nameWithoutSpaces = (0, _m_form4.getTextWithoutSpaces)(name); let pathNode; item[subItemsField] = that._generateItemsFromData(item[subItemsField]); if (isGroupWithName) { pathNode = path.pop() } if (!path.length) { result = that._getItemByField(fieldName, item[subItemsField]); if (result) { break } } if (!isGroupWithName || isGroupWithName && nameWithoutSpaces === pathNode) { if (path.length) { result = that._searchItemInEverySubItem(path, fieldName, item[subItemsField]) } } } else { break } } while (path.length && !(0, _type.isDefined)(result)); return result } _getSubItemField(itemType) { return "tabbed" === itemType ? "tabs" : "items" } _searchItemInEverySubItem(path, fieldName, items) { const that = this; let result; (0, _iterator.each)(items, ((index, groupItem) => { result = that._getItemByFieldPath(path.slice(), fieldName, groupItem); if (result) { return false } })); if (!result) { result = false } return result } _changeItemOption(item, option, value) { if ((0, _type.isObject)(item)) { item[option] = value } } _dimensionChanged() { const currentScreenFactor = this._getCurrentScreenFactor(); if (this._lastMarkupScreenFactor !== currentScreenFactor) { if (this._isColCountChanged(this._lastMarkupScreenFactor, currentScreenFactor)) { this._targetScreenFactor = currentScreenFactor; this._refresh(); this._targetScreenFactor = void 0 } this._lastMarkupScreenFactor = currentScreenFactor } } _isColCountChanged(oldScreenSize, newScreenSize) { let isChanged = false; (0, _iterator.each)(this._cachedColCountOptions, ((index, item) => { if (item.colCountByScreen[oldScreenSize] !== item.colCountByScreen[newScreenSize]) { isChanged = true; return false } })); return isChanged } _refresh() { const editorSelector = `.${_m_text_editor.TEXTEDITOR_CLASS}.${_widget.FOCUSED_STATE_CLASS}:not(.${_m_drop_down_editor.DROP_DOWN_EDITOR_CLASS}) .${_m_text_editor.TEXTEDITOR_INPUT_CLASS}`; _events_engine.default.trigger(this.$element().find(editorSelector), "change"); super._refresh() } _updateIsDirty(dataField) { const editor = this.getEditor(dataField); if (!editor) { return } if (editor.option("isDirty")) { this._dirtyFields.add(dataField) } else { this._dirtyFields.delete(dataField) } this.option("isDirty", !!this._dirtyFields.size) } updateRunTimeInfoForEachEditor(editorAction) { this._itemsRunTimeInfo.each(((_, itemRunTimeInfo) => { const { widgetInstance: widgetInstance } = itemRunTimeInfo; if ((0, _type.isDefined)(widgetInstance) && _editor.default.isEditor(widgetInstance)) { editorAction(widgetInstance) } })) } _clear() { this.updateRunTimeInfoForEachEditor((editor => { editor.clear(); editor.option("isValid", true) })); _validation_engine.default.resetGroup(this._getValidationGroup()) } _updateData(data, value, isComplexData) { const that = this; const _data = isComplexData ? value : data; if ((0, _type.isObject)(_data)) { (0, _iterator.each)(_data, ((dataField, fieldValue) => { that._updateData(isComplexData ? `${data}.${dataField}` : dataField, fieldValue, (0, _type.isObject)(fieldValue)) })) } else if ((0, _type.isString)(data)) { that._updateFieldValue(data, value) } } registerKeyHandler(key, handler) { super.registerKeyHandler(key, handler); this._itemsRunTimeInfo.each(((_, itemRunTimeInfo) => { if ((0, _type.isDefined)(itemRunTimeInfo.widgetInstance)) { itemRunTimeInfo.widgetInstance.registerKeyHandler(key, handler) } })) } _focusTarget() { return this.$element().find(`.${_constants.FIELD_ITEM_CONTENT_CLASS} [tabindex]`).first() } _visibilityChanged() { this._alignLabels(this._rootLayoutManager, this._rootLayoutManager.isSingleColumnMode()) } _clearAutoColCountChangedTimeout() { if (this.autoColCountChangedTimeoutId) { clearTimeout(this.autoColCountChangedTimeoutId); this.autoColCountChangedTimeoutId = void 0 } } _dispose() { this._clearAutoColCountChangedTimeout(); _validation_engine.default.removeGroup(this._getValidationGroup()); super._dispose() } clear() { this._clear() } resetValues() {