/** * DevExtreme (ui/form/ui.form.layout_manager.js) * Version: 19.1.16 * Build date: Tue Oct 18 2022 * * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var _renderer = require("../../core/renderer"); var _renderer2 = _interopRequireDefault(_renderer); var _events_engine = require("../../events/core/events_engine"); var _events_engine2 = _interopRequireDefault(_events_engine); var _guid = require("../../core/guid"); var _guid2 = _interopRequireDefault(_guid); var _uiForm = require("./ui.form.items_runtime_info"); var _uiForm2 = _interopRequireDefault(_uiForm); var _component_registrator = require("../../core/component_registrator"); var _component_registrator2 = _interopRequireDefault(_component_registrator); var _type = require("../../core/utils/type"); var _dom = require("../../core/utils/dom"); var _dom2 = _interopRequireDefault(_dom); var _variable_wrapper = require("../../core/utils/variable_wrapper"); var _window = require("../../core/utils/window"); var _window2 = _interopRequireDefault(_window); var _string = require("../../core/utils/string"); var _string2 = _interopRequireDefault(_string); var _iterator = require("../../core/utils/iterator"); var _extend = require("../../core/utils/extend"); var _array = require("../../core/utils/array"); var _data = require("../../core/utils/data"); var _data2 = _interopRequireDefault(_data); var _remove_event = require("../../core/remove_event"); var _remove_event2 = _interopRequireDefault(_remove_event); var _click = require("../../events/click"); var _click2 = _interopRequireDefault(_click); var _ui = require("../widget/ui.errors"); var _ui2 = _interopRequireDefault(_ui); var _message = require("../../localization/message"); var _message2 = _interopRequireDefault(_message); var _style = require("../../core/utils/style"); var _style2 = _interopRequireDefault(_style); var _inflector = require("../../core/utils/inflector"); var _inflector2 = _interopRequireDefault(_inflector); var _ui3 = require("../widget/ui.widget"); var _ui4 = _interopRequireDefault(_ui3); var _validator = require("../validator"); var _validator2 = _interopRequireDefault(_validator); var _responsive_box = require("../responsive_box"); var _responsive_box2 = _interopRequireDefault(_responsive_box); var _themes = require("../themes"); var _themes2 = _interopRequireDefault(_themes); require("../text_box"); require("../number_box"); require("../check_box"); require("../date_box"); require("../button"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj } } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj) { return typeof obj } : function(obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj }, _typeof(obj) } var FORM_EDITOR_BY_DEFAULT = "dxTextBox"; var FIELD_ITEM_CLASS = "dx-field-item"; var FIELD_EMPTY_ITEM_CLASS = "dx-field-empty-item"; var FIELD_BUTTON_ITEM_CLASS = "dx-field-button-item"; var FIELD_ITEM_REQUIRED_CLASS = "dx-field-item-required"; var FIELD_ITEM_OPTIONAL_CLASS = "dx-field-item-optional"; var FIELD_ITEM_REQUIRED_MARK_CLASS = "dx-field-item-required-mark"; var FIELD_ITEM_OPTIONAL_MARK_CLASS = "dx-field-item-optional-mark"; var FIELD_ITEM_LABEL_CLASS = "dx-field-item-label"; var FIELD_ITEM_LABEL_ALIGN_CLASS = "dx-field-item-label-align"; var FIELD_ITEM_LABEL_CONTENT_CLASS = "dx-field-item-label-content"; var FIELD_ITEM_LABEL_TEXT_CLASS = "dx-field-item-label-text"; var FIELD_ITEM_LABEL_LOCATION_CLASS = "dx-field-item-label-location-"; var FIELD_ITEM_CONTENT_CLASS = "dx-field-item-content"; var FIELD_ITEM_CONTENT_LOCATION_CLASS = "dx-field-item-content-location-"; var FIELD_ITEM_CONTENT_WRAPPER_CLASS = "dx-field-item-content-wrapper"; var FIELD_ITEM_HELP_TEXT_CLASS = "dx-field-item-help-text"; var SINGLE_COLUMN_ITEM_CONTENT = "dx-single-column-item-content"; var LABEL_HORIZONTAL_ALIGNMENT_CLASS = "dx-label-h-align"; var LABEL_VERTICAL_ALIGNMENT_CLASS = "dx-label-v-align"; var FORM_LAYOUT_MANAGER_CLASS = "dx-layout-manager"; var LAYOUT_MANAGER_FIRST_ROW_CLASS = "dx-first-row"; var LAYOUT_MANAGER_FIRST_COL_CLASS = "dx-first-col"; var LAYOUT_MANAGER_LAST_COL_CLASS = "dx-last-col"; var LAYOUT_MANAGER_ONE_COLUMN = "dx-layout-manager-one-col"; var FLEX_LAYOUT_CLASS = "dx-flex-layout"; var INVALID_CLASS = "dx-invalid"; var LAYOUT_STRATEGY_FLEX = "flex"; var LAYOUT_STRATEGY_FALLBACK = "fallback"; var SIMPLE_ITEM_TYPE = "simple"; var TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper"; var DATA_OPTIONS = ["dataSource", "items"]; var EDITORS_WITH_ARRAY_VALUE = ["dxTagBox", "dxRangeSlider"]; var LayoutManager = _ui4.default.inherit({ _getDefaultOptions: function() { return (0, _extend.extend)(this.callBase(), { layoutData: {}, readOnly: false, colCount: 1, colCountByScreen: void 0, labelLocation: "left", onFieldDataChanged: null, onEditorEnterKey: null, customizeItem: null, alignItemLabels: true, minColWidth: 200, showRequiredMark: true, screenByWidth: null, showOptionalMark: false, requiredMark: "*", optionalMark: _message2.default.format("dxForm-optionalMark"), requiredMessage: _message2.default.getFormatter("dxForm-requiredMessage") }) }, _setOptionsByReference: function() { this.callBase(); (0, _extend.extend)(this._optionsByReference, { layoutData: true, validationGroup: true }) }, _init: function() { var layoutData = this.option("layoutData"); this.callBase(); this._itemWatchers = []; this._itemsRunTimeInfo = new _uiForm2.default; this._updateReferencedOptions(layoutData); this._initDataAndItems(layoutData) }, _dispose: function() { this.callBase(); this._cleanItemWatchers() }, _initDataAndItems: function(initialData) { this._syncDataWithItems(); this._updateItems(initialData) }, _syncDataWithItems: function() { var that = this; var userItems = that.option("items"); if ((0, _type.isDefined)(userItems)) { (0, _iterator.each)(userItems, function(index, item) { var value; if (item.dataField && void 0 === that._getDataByField(item.dataField)) { if (item.editorOptions) { value = item.editorOptions.value } that._updateFieldValue(item.dataField, value) } }) } }, _getDataByField: function(dataField) { return dataField ? this.option("layoutData." + dataField) : null }, _updateFieldValue: function(dataField, value) { var layoutData = this.option("layoutData"); var newValue = value; if (!(0, _variable_wrapper.isWrapped)(layoutData[dataField]) && (0, _type.isDefined)(dataField)) { this.option("layoutData." + dataField, newValue) } else { if ((0, _variable_wrapper.isWritableWrapped)(layoutData[dataField])) { newValue = (0, _type.isFunction)(newValue) ? newValue() : newValue; layoutData[dataField](newValue) } } this._triggerOnFieldDataChanged({ dataField: dataField, value: newValue }) }, _triggerOnFieldDataChanged: function(args) { this._createActionByOption("onFieldDataChanged")(args) }, _updateItems: function(layoutData) { var that = this; var userItems = this.option("items"); var isUserItemsExist = (0, _type.isDefined)(userItems); var customizeItem = that.option("customizeItem"); var items = isUserItemsExist ? userItems : this._generateItemsByData(layoutData); if ((0, _type.isDefined)(items)) { var processedItems = []; (0, _iterator.each)(items, function(index, item) { if (that._isAcceptableItem(item)) { item = that._processItem(item); customizeItem && customizeItem(item); if ((0, _type.isObject)(item) && false !== (0, _variable_wrapper.unwrap)(item.visible)) { processedItems.push(item) } } }); if (!that._itemWatchers.length || !isUserItemsExist) { that._updateItemWatchers(items) } this._items = processedItems; this._sortItems() } }, _cleanItemWatchers: function() { this._itemWatchers.forEach(function(dispose) { dispose() }); this._itemWatchers = [] }, _updateItemWatchers: function(items) { var that = this; var watch = that._getWatch(); items.forEach(function(item) { if ((0, _type.isObject)(item) && (0, _type.isDefined)(item.visible) && (0, _type.isFunction)(watch)) { that._itemWatchers.push(watch(function() { return (0, _variable_wrapper.unwrap)(item.visible) }, function() { that._updateItems(that.option("layoutData")); that.repaint() }, { skipImmediate: true })) } }) }, _generateItemsByData: function(layoutData) { var result = []; if ((0, _type.isDefined)(layoutData)) { (0, _iterator.each)(layoutData, function(dataField) { result.push({ dataField: dataField }) }) } return result }, _isAcceptableItem: function(item) { var itemField = item.dataField || item; var itemData = this._getDataByField(itemField); return !((0, _type.isFunction)(itemData) && !(0, _variable_wrapper.isWrapped)(itemData)) }, _processItem: function(item) { if ("string" === typeof item) { item = { dataField: item } } if ("object" === _typeof(item) && !item.itemType) { item.itemType = SIMPLE_ITEM_TYPE } if (!(0, _type.isDefined)(item.editorType) && (0, _type.isDefined)(item.dataField)) { var value = this._getDataByField(item.dataField); item.editorType = (0, _type.isDefined)(value) ? this._getEditorTypeByDataType((0, _type.type)(value)) : FORM_EDITOR_BY_DEFAULT } return item }, _getEditorTypeByDataType: function(dataType) { switch (dataType) { case "number": return "dxNumberBox"; case "date": return "dxDateBox"; case "boolean": return "dxCheckBox"; default: return "dxTextBox" } }, _sortItems: function() { (0, _array.normalizeIndexes)(this._items, "visibleIndex"); this._sortIndexes() }, _sortIndexes: function() { this._items.sort(function(itemA, itemB) { var indexA = itemA.visibleIndex; var indexB = itemB.visibleIndex; var result; if (indexA > indexB) { result = 1 } else { if (indexA < indexB) { result = -1 } else { result = 0 } } return result }) }, _initMarkup: function() { this._itemsRunTimeInfo.clear(); this.$element().addClass(FORM_LAYOUT_MANAGER_CLASS); this.callBase(); this._renderResponsiveBox() }, _hasBrowserFlex: function() { return _style2.default.styleProp(LAYOUT_STRATEGY_FLEX) === LAYOUT_STRATEGY_FLEX }, _renderResponsiveBox: function() { var that = this; var templatesInfo = []; if (that._items && that._items.length) { var colCount = that._getColCount(); var $container = (0, _renderer2.default)("
").appendTo(that.$element()); that._prepareItemsWithMerging(colCount); var layoutItems = that._generateLayoutItems(); that._extendItemsWithDefaultTemplateOptions(layoutItems, that._items); that._responsiveBox = that._createComponent($container, _responsive_box2.default, that._getResponsiveBoxConfig(layoutItems, colCount, templatesInfo)); if (!_window2.default.hasWindow()) { that._renderTemplates(templatesInfo) } } }, _extendItemsWithDefaultTemplateOptions: function(targetItems, sourceItems) { sourceItems.forEach(function(item) { if (!item.merged) { if ((0, _type.isDefined)(item.disabled)) { targetItems[item.visibleIndex].disabled = item.disabled } if ((0, _type.isDefined)(item.visible)) { targetItems[item.visibleIndex].visible = item.visible } } }) }, _itemStateChangedHandler: function(e) { this._refresh() }, _renderTemplate: function($container, item) { switch (item.itemType) { case "empty": this._renderEmptyItem($container); break; case "button": this._renderButtonItem(item, $container); break; default: this._renderFieldItem(item, $container) } }, _renderTemplates: function(templatesInfo) { var that = this; (0, _iterator.each)(templatesInfo, function(index, info) { that._renderTemplate(info.container, info.formItem) }) }, _getResponsiveBoxConfig: function(layoutItems, colCount, templatesInfo) { var that = this; var colCountByScreen = that.option("colCountByScreen"); var xsColCount = colCountByScreen && colCountByScreen.xs; return { onItemStateChanged: this._itemStateChangedHandler.bind(this), _layoutStrategy: that._hasBrowserFlex() ? LAYOUT_STRATEGY_FLEX : LAYOUT_STRATEGY_FALLBACK, onLayoutChanged: function onLayoutChanged() { var onLayoutChanged = that.option("onLayoutChanged"); var isSingleColumnMode = that.isSingleColumnMode(); if (onLayoutChanged) { that.$element().toggleClass(LAYOUT_MANAGER_ONE_COLUMN, isSingleColumnMode); onLayoutChanged(isSingleColumnMode) } }, onContentReady: function(e) { if (_window2.default.hasWindow()) { that._renderTemplates(templatesInfo) } if (that.option("onLayoutChanged")) { that.$element().toggleClass(LAYOUT_MANAGER_ONE_COLUMN, that.isSingleColumnMode(e.component)) } that._fireContentReadyAction() }, itemTemplate: function(e, itemData, itemElement) { if (!e.location) { return } var $itemElement = (0, _renderer2.default)(itemElement); var itemRenderedCountInPreviousRows = e.location.row * colCount; var item = that._items[e.location.col + itemRenderedCountInPreviousRows]; var $fieldItem = (0, _renderer2.default)("
").addClass(item.cssClass).appendTo($itemElement); templatesInfo.push({ container: $fieldItem, formItem: item }); $itemElement.toggleClass(SINGLE_COLUMN_ITEM_CONTENT, that.isSingleColumnMode(this)); if (0 === e.location.row) { $fieldItem.addClass(LAYOUT_MANAGER_FIRST_ROW_CLASS) } if (0 === e.location.col) { $fieldItem.addClass(LAYOUT_MANAGER_FIRST_COL_CLASS) } if (e.location.col === colCount - 1 || e.location.col + e.location.colspan === colCount) { $fieldItem.addClass(LAYOUT_MANAGER_LAST_COL_CLASS) } }, cols: that._generateRatio(colCount), rows: that._generateRatio(that._getRowsCount(), true), dataSource: layoutItems, screenByWidth: that.option("screenByWidth"), singleColumnScreen: xsColCount ? false : "xs" } }, _getColCount: function() { var colCount = this.option("colCount"); var colCountByScreen = this.option("colCountByScreen"); if (colCountByScreen) { var screenFactor = this.option("form").getTargetScreenFactor(); if (!screenFactor) { screenFactor = _window2.default.hasWindow() ? _window2.default.getCurrentScreenFactor(this.option("screenByWidth")) : "lg" } colCount = colCountByScreen[screenFactor] || colCount } if ("auto" === colCount) { if (this._cashedColCount) { return this._cashedColCount } this._cashedColCount = colCount = this._getMaxColCount() } return colCount < 1 ? 1 : colCount }, _getMaxColCount: function() { if (!_window2.default.hasWindow()) { return 1 } var minColWidth = this.option("minColWidth"); var width = this.$element().width(); var itemsCount = this._items.length; var maxColCount = Math.floor(width / minColWidth) || 1; return itemsCount < maxColCount ? itemsCount : maxColCount }, isCachedColCountObsolete: function() { return this._cashedColCount && this._getMaxColCount() !== this._cashedColCount }, _prepareItemsWithMerging: function(colCount) { var items = this._items.slice(0); var result = []; for (var i = 0; i < items.length; i++) { var item = items[i]; result.push(item); if (this.option("alignItemLabels") || item.alignItemLabels || item.colSpan) { item.col = this._getColByIndex(result.length - 1, colCount) } if (item.colSpan > 1 && item.col + item.colSpan <= colCount) { var itemsMergedByCol = []; for (var j = 0; j < item.colSpan - 1; j++) { itemsMergedByCol.push({ merged: true }) } result = result.concat(itemsMergedByCol) } else { delete item.colSpan } } this._items = result }, _getColByIndex: function(index, colCount) { return index % colCount }, _generateLayoutItems: function() { var items = this._items; var colCount = this._getColCount(); var result = []; for (var i = 0; i < items.length; i++) { var item = items[i]; if (!item.merged) { var generatedItem = { location: { row: parseInt(i / colCount), col: this._getColByIndex(i, colCount) } }; if ((0, _type.isDefined)(item.colSpan)) { generatedItem.location.colspan = item.colSpan } if ((0, _type.isDefined)(item.rowSpan)) { generatedItem.location.rowspan = item.rowSpan } result.push(generatedItem) } } return result }, _renderEmptyItem: function($container) { return $container.addClass(FIELD_EMPTY_ITEM_CLASS).html(" ") }, _getButtonHorizontalAlignment: function(item) { if ((0, _type.isDefined)(item.horizontalAlignment)) { return item.horizontalAlignment } if ((0, _type.isDefined)(item.alignment)) { _ui2.default.log("W0001", "dxForm", "alignment", "18.1", "Use the 'horizontalAlignment' option in button items instead."); return item.alignment } return "right" }, _getButtonVerticalAlignment: function(item) { switch (item.verticalAlignment) { case "center": return "center"; case "bottom": return "flex-end"; default: return "flex-start" } }, _renderButtonItem: function(item, $container) { var $button = (0, _renderer2.default)("
").appendTo($container); var defaultOptions = { validationGroup: this.option("validationGroup") }; $container.addClass(FIELD_BUTTON_ITEM_CLASS).css("textAlign", this._getButtonHorizontalAlignment(item)); $container.parent().css("justifyContent", this._getButtonVerticalAlignment(item)); var instance = this._createComponent($button, "dxButton", (0, _extend.extend)(defaultOptions, item.buttonOptions)); this._itemsRunTimeInfo.add({ item: item, widgetInstance: instance, guid: item.guid, $itemContainer: $container }); this._addItemClasses($container, item.col); return $button }, _addItemClasses: function($item, column) { $item.addClass(FIELD_ITEM_CLASS).addClass(this.option("cssItemClass")).addClass((0, _type.isDefined)(column) ? "dx-col-" + column : "") }, _renderFieldItem: function(item, $container) { var that = this; var name = that._getName(item); var id = that.getItemID(name); var isRequired = (0, _type.isDefined)(item.isRequired) ? item.isRequired : !!that._hasRequiredRuleInSet(item.validationRules); var labelOptions = that._getLabelOptions(item, id, isRequired); var $editor = (0, _renderer2.default)("
"); var helpID = item.helpText ? "dx-" + new _guid2.default : null; var $label; this._addItemClasses($container, item.col); $container.addClass(isRequired ? FIELD_ITEM_REQUIRED_CLASS : FIELD_ITEM_OPTIONAL_CLASS); if (labelOptions.visible && labelOptions.text) { $label = that._renderLabel(labelOptions).appendTo($container) } if (item.itemType === SIMPLE_ITEM_TYPE) { if (that._isLabelNeedBaselineAlign(item) && "top" !== labelOptions.location) { $container.addClass(FIELD_ITEM_LABEL_ALIGN_CLASS) } that._hasBrowserFlex() && $container.addClass(FLEX_LAYOUT_CLASS) } $editor.data("dx-form-item", item); that._appendEditorToField({ $fieldItem: $container, $label: $label, $editor: $editor, labelOptions: labelOptions }); var instance = that._renderEditor({ $container: $editor, dataField: item.dataField, name: item.name, editorType: item.editorType, editorOptions: item.editorOptions, template: that._getTemplateByFieldItem(item), isRequired: isRequired, helpID: helpID, labelID: labelOptions.labelID, id: id, validationBoundary: that.option("validationBoundary") }); this._itemsRunTimeInfo.add({ item: item, widgetInstance: instance, guid: item.guid, $itemContainer: $container }); var editorElem = $editor.children().first(); var $validationTarget = editorElem.hasClass(TEMPLATE_WRAPPER_CLASS) ? editorElem.children().first() : editorElem; if ($validationTarget && $validationTarget.data("dx-validation-target")) { that._renderValidator($validationTarget, item) } that._renderHelpText(item, $editor, helpID); that._attachClickHandler($label, $editor, item.editorType) }, _hasRequiredRuleInSet: function(rules) { var hasRequiredRule; if (rules && rules.length) { (0, _iterator.each)(rules, function(index, rule) { if ("required" === rule.type) { hasRequiredRule = true; return false } }) } return hasRequiredRule }, _getName: function(item) { return item.dataField || item.name }, _isLabelNeedBaselineAlign: function(item) { var largeEditors = ["dxTextArea", "dxRadioGroup", "dxCalendar", "dxHtmlEditor"]; return !!item.helpText && !this._hasBrowserFlex() || (0, _array.inArray)(item.editorType, largeEditors) !== -1 }, _isLabelNeedId: function(item) { var editorsRequiringIdForLabel = ["dxRadioGroup", "dxCheckBox", "dxLookup", "dxSlider", "dxRangeSlider", "dxSwitch", "dxHtmlEditor"]; return (0, _array.inArray)(item.editorType, editorsRequiringIdForLabel) !== -1 }, _getLabelOptions: function(item, id, isRequired) { var labelOptions = (0, _extend.extend)({ showColon: this.option("showColonAfterLabel"), location: this.option("labelLocation"), id: id, visible: true, isRequired: isRequired }, item ? item.label : {}); if (this._isLabelNeedId(item)) { labelOptions.labelID = "dx-label-".concat(new _guid2.default) } if (!labelOptions.text && item.dataField) { labelOptions.text = _inflector2.default.captionize(item.dataField) } if (labelOptions.text) { labelOptions.text += labelOptions.showColon ? ":" : "" } return labelOptions }, _renderLabel: function(options) { var text = options.text, id = options.id, location = options.location, alignment = options.alignment, isRequired = options.isRequired, _options$labelID = options.labelID, labelID = void 0 === _options$labelID ? null : _options$labelID; if ((0, _type.isDefined)(text) && text.length > 0) { var labelClasses = FIELD_ITEM_LABEL_CLASS + " " + FIELD_ITEM_LABEL_LOCATION_CLASS + location; var $label = (0, _renderer2.default)("