UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,087 lines (1,082 loc) • 102 kB
/** * DevExtreme (ui/grid_core/ui.grid_core.editing.js) * Version: 18.2.18 * 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 _dom_adapter = require("../../core/dom_adapter"); var _dom_adapter2 = _interopRequireDefault(_dom_adapter); var _window = require("../../core/utils/window"); var _events_engine = require("../../events/core/events_engine"); var _events_engine2 = _interopRequireDefault(_events_engine); var _guid = require("../../core/guid"); var _guid2 = _interopRequireDefault(_guid); var _type = require("../../core/utils/type"); var _type2 = _interopRequireDefault(_type); var _iterator = require("../../core/utils/iterator"); var _extend = require("../../core/utils/extend"); var _uiGrid_core = require("./ui.grid_core.modules"); var _uiGrid_core2 = _interopRequireDefault(_uiGrid_core); var _click = require("../../events/click"); var _click2 = _interopRequireDefault(_click); var _pointer = require("../../events/pointer"); var _pointer2 = _interopRequireDefault(_pointer); var _uiGrid_core3 = require("./ui.grid_core.utils"); var _utils = require("../../events/utils"); var _dialog = require("../dialog"); var _dialog2 = _interopRequireDefault(_dialog); var _message = require("../../localization/message"); var _message2 = _interopRequireDefault(_message); var _button = require("../button"); var _button2 = _interopRequireDefault(_button); var _popup = require("../popup"); var _popup2 = _interopRequireDefault(_popup); var _ui = require("../widget/ui.errors"); var _ui2 = _interopRequireDefault(_ui); var _devices = require("../../core/devices"); var _devices2 = _interopRequireDefault(_devices); var _form = require("../form"); var _form2 = _interopRequireDefault(_form); var _hold = require("../../events/hold"); var _hold2 = _interopRequireDefault(_hold); var _deferred = require("../../core/utils/deferred"); var _deferred2 = _interopRequireDefault(_deferred); var _common = require("../../core/utils/common"); var _common2 = _interopRequireDefault(_common); var _icon = require("../../core/utils/icon"); var _icon2 = _interopRequireDefault(_icon); var _ui3 = require("../scroll_view/ui.scrollable"); var _ui4 = _interopRequireDefault(_ui3); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj } } var EDIT_FORM_CLASS = "edit-form", EDIT_FORM_ITEM_CLASS = "edit-form-item", FOCUS_OVERLAY_CLASS = "focus-overlay", READONLY_CLASS = "readonly", EDIT_POPUP_CLASS = "edit-popup", FORM_BUTTONS_CONTAINER_CLASS = "form-buttons-container", ADD_ROW_BUTTON_CLASS = "addrow-button", LINK_CLASS = "dx-link", EDITOR_CELL_CLASS = "dx-editor-cell", ROW_SELECTED = "dx-selection", EDIT_ROW = "dx-edit-row", EDIT_BUTTON_CLASS = "dx-edit-button", COMMAND_EDIT_CLASS = "dx-command-edit", COMMAND_EDIT_WITH_ICONS_CLASS = COMMAND_EDIT_CLASS + "-with-icons", SCROLLABLE_CONTAINER_CLASS = "dx-scrollable-container", BUTTON_CLASS = "dx-button", INSERT_INDEX = "__DX_INSERT_INDEX__", ROW_CLASS = "dx-row", ROW_REMOVED = "dx-row-removed", ROW_INSERTED = "dx-row-inserted", ROW_MODIFIED = "dx-row-modified", CELL_MODIFIED = "dx-cell-modified", CELL_HIGHLIGHT_OUTLINE = "dx-highlight-outline", EDITING_NAMESPACE = "dxDataGridEditing", DATA_ROW_CLASS = "dx-data-row", CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled", EDITORS_INPUT_SELECTOR = "input:not([type='hidden'])", FOCUSABLE_ELEMENT_SELECTOR = "[tabindex], " + EDITORS_INPUT_SELECTOR, EDIT_MODE_BATCH = "batch", EDIT_MODE_ROW = "row", EDIT_MODE_CELL = "cell", EDIT_MODE_FORM = "form", EDIT_MODE_POPUP = "popup", DATA_EDIT_DATA_INSERT_TYPE = "insert", DATA_EDIT_DATA_UPDATE_TYPE = "update", DATA_EDIT_DATA_REMOVE_TYPE = "remove", POINTER_EVENTS_NONE_CLASS = "dx-pointer-events-none", POINTER_EVENTS_TARGET_CLASS = "dx-pointer-events-target", EDIT_MODES = [EDIT_MODE_BATCH, EDIT_MODE_ROW, EDIT_MODE_CELL, EDIT_MODE_FORM, EDIT_MODE_POPUP], ROW_BASED_MODES = [EDIT_MODE_ROW, EDIT_MODE_FORM, EDIT_MODE_POPUP], CELL_BASED_MODES = [EDIT_MODE_BATCH, EDIT_MODE_CELL], FORM_BASED_MODES = [EDIT_MODE_FORM, EDIT_MODE_POPUP], MODES_WITH_DELAYED_FOCUS = [EDIT_MODE_ROW, EDIT_MODE_FORM]; var EDIT_LINK_CLASS = { save: "dx-link-save", cancel: "dx-link-cancel", edit: "dx-link-edit", undelete: "dx-link-undelete", "delete": "dx-link-delete", add: "dx-link-add" }, EDIT_ICON_CLASS = { save: "save", cancel: "revert", edit: "edit", undelete: "revert", "delete": "trash", add: "add" }, METHOD_NAMES = { edit: "editRow", "delete": "deleteRow", undelete: "undeleteRow", save: "saveEditData", cancel: "cancelEditData", add: "addRowByRowIndex" }, ACTION_OPTION_NAMES = { add: "allowAdding", edit: "allowUpdating", "delete": "allowDeleting" }, BUTTON_NAMES = ["edit", "save", "cancel", "delete", "undelete"]; var _getEditMode = function(that) { var editMode = that.option("editing.mode"); if (EDIT_MODES.indexOf(editMode) !== -1) { return editMode } return EDIT_MODE_ROW }; var _isRowEditMode = function(that) { var editMode = _getEditMode(that); return ROW_BASED_MODES.indexOf(editMode) !== -1 }; var getDocumentClickEventName = function() { return "desktop" === _devices2.default.real().deviceType ? _pointer2.default.down : _click2.default.name }; var EditingController = _uiGrid_core2.default.ViewController.inherit(function() { var getDefaultEditorTemplate = function(that) { return function(container, options) { var $editor = (0, _renderer2.default)("<div>").appendTo(container); that.getController("editorFactory").createEditor($editor, (0, _extend.extend)({}, options.column, { value: options.value, setValue: options.setValue, row: options.row, parentType: "dataRow", width: null, readOnly: !options.setValue, isOnForm: options.isOnForm, id: options.id })) } }; var getEditingTexts = function(options) { var editingTexts = options.component.option("editing.texts") || {}; return { save: editingTexts.saveRowChanges, cancel: editingTexts.cancelRowChanges, edit: editingTexts.editRow, undelete: editingTexts.undeleteRow, "delete": editingTexts.deleteRow, add: editingTexts.addRowToNode } }; var getButtonIndex = function(buttons, name) { var result = -1; buttons.some(function(button, index) { if (getButtonName(button) === name) { result = index; return true } }); return result }; var getButtonName = function(button) { return _type2.default.isObject(button) ? button.name : button }; return { init: function() { var that = this; that._editRowIndex = -1; that._editData = []; that._editColumnIndex = -1; that._columnsController = that.getController("columns"); that._dataController = that.getController("data"); that._rowsView = that.getView("rowsView"); that._editForm = null; if (!that._dataChangedHandler) { that._dataChangedHandler = that._handleDataChanged.bind(that); that._dataController.changed.add(that._dataChangedHandler) } if (!that._saveEditorHandler) { that.createAction("onInitNewRow", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowInserting", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowInserted", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onEditingStart", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowUpdating", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowUpdated", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowRemoving", { excludeValidators: ["disabled", "readOnly"] }); that.createAction("onRowRemoved", { excludeValidators: ["disabled", "readOnly"] }); that._saveEditorHandler = that.createAction(function(e) { var isEditorPopup, isDomElement, isFocusOverlay, isAddRowButton, isCellEditMode, $target, event = e.event; if (!_isRowEditMode(that) && !that._editCellInProgress) { $target = (0, _renderer2.default)(event.target); isEditorPopup = $target.closest(".dx-dropdowneditor-overlay").length; isDomElement = $target.closest((0, _window.getWindow)().document).length; isAddRowButton = $target.closest("." + that.addWidgetPrefix(ADD_ROW_BUTTON_CLASS)).length; isFocusOverlay = $target.hasClass(that.addWidgetPrefix(FOCUS_OVERLAY_CLASS)); isCellEditMode = _getEditMode(that) === EDIT_MODE_CELL; if (!isEditorPopup && !isFocusOverlay && !(isAddRowButton && isCellEditMode && that.isEditing()) && isDomElement) { that._closeEditItem.bind(that)($target) } } }); _events_engine2.default.on(_dom_adapter2.default.getDocument(), getDocumentClickEventName(), that._saveEditorHandler) } that._updateEditColumn(); that._updateEditButtons() }, getUpdatedData: function(data) { var key = this._dataController.keyOf(data), editData = this._editData, editIndex = (0, _uiGrid_core3.getIndexByKey)(key, editData); if (editData[editIndex]) { return (0, _uiGrid_core3.createObjectWithChanges)(data, editData[editIndex].data) } return data }, getInsertedData: function() { return this._editData.filter(function(editData) { return editData.data && editData.type === DATA_EDIT_DATA_INSERT_TYPE }).map(function(editData) { return editData.data }) }, getRemovedData: function() { return this._editData.filter(function(editData) { return editData.oldData && editData.type === DATA_EDIT_DATA_REMOVE_TYPE }).map(function(editData) { return editData.oldData }) }, _needToCloseEditableCell: function($targetElement) { var isDataRow = $targetElement.closest("." + DATA_ROW_CLASS).length, $targetCell = $targetElement.closest("." + ROW_CLASS + "> td"), rowsView = this.getView("rowsView"), rowIndex = rowsView.getRowIndex($targetCell.parent()), columnIndex = rowsView.getCellElements(rowIndex).index($targetCell), visibleColumns = this._columnsController.getVisibleColumns(), allowEditing = visibleColumns[columnIndex] && visibleColumns[columnIndex].allowEditing; return this.isEditing() && (!isDataRow || isDataRow && !allowEditing && !this.isEditCell(rowIndex, columnIndex)) }, _closeEditItem: function($targetElement) { if (this._needToCloseEditableCell($targetElement)) { this.closeEditCell() } }, _handleDataChanged: function(args) { var that = this, editForm = that._editForm; if ("standard" === that.option("scrolling.mode")) { that.resetRowAndPageIndices() } if ("prepend" === args.changeType) { (0, _iterator.each)(that._editData, function(_, editData) { editData.rowIndex += args.items.length; if (editData.type === DATA_EDIT_DATA_INSERT_TYPE) { editData.key.rowIndex += args.items.length; editData.key.dataRowIndex += args.items.filter(function(item) { return "data" === item.rowType }).length } }) } if ("refresh" === args.changeType && _getEditMode(that) === EDIT_MODE_POPUP && editForm && editForm.option("visible")) { editForm.repaint() } }, _isDefaultButtonVisible: function(button, options) { var result = true, isRowMode = _isRowEditMode(this), isEditRow = options.row && options.row.rowIndex === this._getVisibleEditRowIndex() && isRowMode; switch (button.name) { case "edit": result = !isEditRow && this.allowUpdating(options) && isRowMode; break; case "save": case "cancel": result = isEditRow; break; case "delete": result = !isEditRow && this.allowDeleting(options) && !options.row.removed; break; case "undelete": result = this.allowDeleting(options) && options.row.removed } return result }, _isButtonVisible: function(button, options) { var visible = button.visible; if (!_type2.default.isDefined(visible)) { return this._isDefaultButtonVisible(button, options) } return _type2.default.isFunction(visible) ? visible.call(button, { component: options.component, row: options.row, column: options.column }) : visible }, _getButtonConfig: function(button, options) { var _this = this; var config = _type2.default.isObject(button) ? button : {}, buttonName = getButtonName(button), editingTexts = getEditingTexts(options), methodName = METHOD_NAMES[buttonName], editingOptions = this.option("editing"), actionName = ACTION_OPTION_NAMES[buttonName], allowAction = actionName ? editingOptions[actionName] : true; return (0, _extend.extend)({ name: buttonName, text: editingTexts[buttonName], cssClass: EDIT_LINK_CLASS[buttonName], onClick: function(e) { var event = e.event; event.stopPropagation(); event.preventDefault(); setTimeout(function() { options.row && allowAction && _this[methodName] && _this[methodName](options.row.rowIndex) }) } }, config) }, _getEditingButtons: function(options) { var _this2 = this; var buttonIndex, haveCustomButtons = !!options.column.buttons, buttons = (options.column.buttons || []).slice(); if (haveCustomButtons) { buttonIndex = getButtonIndex(buttons, "edit"); if (buttonIndex >= 0) { if (getButtonIndex(buttons, "save") < 0) { buttons.splice(buttonIndex + 1, 0, "save") } if (getButtonIndex(buttons, "cancel") < 0) { buttons.splice(getButtonIndex(buttons, "save") + 1, 0, "cancel") } } buttonIndex = getButtonIndex(buttons, "delete"); if (buttonIndex >= 0 && getButtonIndex(buttons, "undelete") < 0) { buttons.splice(buttonIndex + 1, 0, "undelete") } } else { buttons = BUTTON_NAMES.slice() } return buttons.map(function(button) { return _this2._getButtonConfig(button, options) }) }, _renderEditingButtons: function($container, buttons, options) { var _this3 = this; buttons.forEach(function(button) { if (_this3._isButtonVisible(button, options)) { _this3._createButton($container, button, options) } }) }, _getEditCommandCellTemplate: function() { var _this4 = this; return function(container, options) { var buttons, $container = (0, _renderer2.default)(container); if ("data" === options.rowType) { options.rtlEnabled = _this4.option("rtlEnabled"); buttons = _this4._getEditingButtons(options); _this4._renderEditingButtons($container, buttons, options); options.watch && options.watch(function() { return buttons.map(function(button) { return _this4._isButtonVisible(button, options) }) }, function() { $container.empty(); _this4._renderEditingButtons($container, buttons, options) }) } else { (0, _uiGrid_core3.setEmptyText)($container) } } }, correctEditRowIndexAfterExpand: function(key) { if (this._editRowIndex > this._dataController.getRowIndexByKey(key)) { this._editRowIndex++ } }, correctEditRowIndex: function(getRowIndexCorrection) { this._editRowIndex += getRowIndexCorrection(this._getVisibleEditRowIndex()) }, isRowEditMode: function() { return _isRowEditMode(this) }, isFormEditMode: function() { var editMode = _getEditMode(this); return FORM_BASED_MODES.indexOf(editMode) !== -1 }, getEditMode: function() { return _getEditMode(this) }, getFirstEditableColumnIndex: function() { var columnIndex, columnsController = this.getController("columns"), firstFormItem = this._firstFormItem; if (_getEditMode(this) === EDIT_MODE_FORM && firstFormItem) { var $editFormElements = this._rowsView.getCellElements(this._editRowIndex); columnIndex = this._rowsView._getEditFormEditorVisibleIndex($editFormElements, firstFormItem.column) } else { var visibleColumns = columnsController.getVisibleColumns(); (0, _iterator.each)(visibleColumns, function(index, column) { if (column.allowEditing) { columnIndex = index; return false } }) } return columnIndex }, getFirstEditableCellInRow: function(rowIndex) { var rowsView = this.getView("rowsView"); return rowsView && rowsView._getCellElement(rowIndex ? rowIndex : 0, this.getFirstEditableColumnIndex()) }, getFocusedCellInRow: function(rowIndex) { return this.getFirstEditableCellInRow(rowIndex) }, getIndexByKey: function(key, items) { return (0, _uiGrid_core3.getIndexByKey)(key, items) }, hasChanges: function(rowIndex) { var that = this, result = false; for (var i = 0; i < that._editData.length; i++) { if (that._editData[i].type && (!_type2.default.isDefined(rowIndex) || that._dataController.getRowIndexByKey(that._editData[i].key) === rowIndex)) { result = true; break } } return result }, dispose: function() { this.callBase(); clearTimeout(this._inputFocusTimeoutID); _events_engine2.default.off(_dom_adapter2.default.getDocument(), getDocumentClickEventName(), this._saveEditorHandler) }, optionChanged: function(args) { if ("editing" === args.name) { if (this._editPopup && this._editPopup.option("visible") && 0 === args.fullName.indexOf("editing.form")) { var rowIndex = this._getVisibleEditRowIndex(); if (rowIndex >= 0) { this._showEditPopup(rowIndex) } } else { this.init() } args.handled = true } else { this.callBase(args) } }, publicMethods: function() { return ["insertRow", "addRow", "removeRow", "deleteRow", "undeleteRow", "editRow", "editCell", "closeEditCell", "saveEditData", "cancelEditData", "hasEditData"] }, refresh: function() { if (_getEditMode(this) === EDIT_MODE_CELL) { return } if (_getEditMode(this) !== EDIT_MODE_BATCH) { this.init() } else { this._editRowIndex = -1; this._editColumnIndex = -1 } }, isEditing: function() { return this._editRowIndex > -1 }, isEditRow: function(rowIndex) { var editMode = _getEditMode(this); return this._getVisibleEditRowIndex() === rowIndex && ROW_BASED_MODES.indexOf(editMode) !== -1 }, getEditRowKey: function() { var items = this._dataController.items(), item = items[this._getVisibleEditRowIndex()]; return item && item.key }, getEditRowIndex: function() { return this._getVisibleEditRowIndex() }, getEditFormRowIndex: function() { var editMode = _getEditMode(this); return editMode === EDIT_MODE_FORM || editMode === EDIT_MODE_POPUP ? this._getVisibleEditRowIndex() : -1 }, isEditCell: function(rowIndex, columnIndex) { var hasEditData = !!(Array.isArray(this._editData) && this._editData.length); return hasEditData && this._getVisibleEditRowIndex() === rowIndex && this._editColumnIndex === columnIndex }, getPopupContent: function() { var editMode = _getEditMode(this), popupVisible = this._editPopup && this._editPopup.option("visible"); if (editMode === EDIT_MODE_POPUP && popupVisible) { return this._$popupContent } }, getEditForm: function() { return this._editForm }, _needInsertItem: function(editData, changeType) { var that = this, dataSource = that._dataController.dataSource(), scrollingMode = that.option("scrolling.mode"), pageIndex = dataSource.pageIndex(), beginPageIndex = dataSource.beginPageIndex ? dataSource.beginPageIndex() : pageIndex, endPageIndex = dataSource.endPageIndex ? dataSource.endPageIndex() : pageIndex; if ("standard" !== scrollingMode) { switch (changeType) { case "append": return editData.key.pageIndex === endPageIndex; case "prepend": return editData.key.pageIndex === beginPageIndex; case "refresh": editData.key.rowIndex = 0; editData.key.dataRowIndex = 0; editData.key.pageIndex = 0; break; default: return editData.key.pageIndex >= beginPageIndex && editData.key.pageIndex <= endPageIndex } } return editData.key.pageIndex === pageIndex }, _generateNewItem: function(key) { var item = { key: key }; if (key && key[INSERT_INDEX]) { item[INSERT_INDEX] = key[INSERT_INDEX] } return item }, processItems: function(items, changeType) { var i, key, item, editData, that = this; that.update(changeType); editData = that._editData; for (i = 0; i < editData.length; i++) { key = editData[i].key; item = that._generateNewItem(key); if (editData[i].type === DATA_EDIT_DATA_INSERT_TYPE && that._needInsertItem(editData[i], changeType, items, item)) { items.splice(key.dataRowIndex, 0, item) } } return items }, processDataItem: function(item, options, generateDataValues) { var data, editMode, editData, editIndex, that = this, columns = options.visibleColumns, key = item.data[INSERT_INDEX] ? item.data.key : item.key; editIndex = (0, _uiGrid_core3.getIndexByKey)(key, that._editData); if (editIndex >= 0) { editMode = _getEditMode(that); editData = that._editData[editIndex]; data = editData.data; item.isEditing = false; switch (editData.type) { case DATA_EDIT_DATA_INSERT_TYPE: if (editMode === EDIT_MODE_POPUP) { item.visible = false } item.inserted = true; item.key = key; item.data = data; break; case DATA_EDIT_DATA_UPDATE_TYPE: item.modified = true; item.oldData = item.data; item.data = (0, _uiGrid_core3.createObjectWithChanges)(item.data, data); item.modifiedValues = generateDataValues(data, columns, true); break; case DATA_EDIT_DATA_REMOVE_TYPE: if (editMode === EDIT_MODE_BATCH) { item.data = (0, _uiGrid_core3.createObjectWithChanges)(item.data, data) } item.removed = true } } }, insertRow: function() { _ui2.default.log("W0002", "dxDataGrid", "insertRow", "15.2", "Use the 'addRow' method instead"); return this.addRow() }, _initNewRow: function(options, insertKey) { this.executeAction("onInitNewRow", options); var dataController = this._dataController, rows = dataController.items(), row = rows[insertKey.rowIndex]; if (row && (!row.isEditing && "detail" === row.rowType || "detailAdaptive" === row.rowType)) { insertKey.rowIndex++ } insertKey.dataRowIndex = dataController.getRowIndexDelta() + rows.filter(function(row, index) { return index < insertKey.rowIndex && ("data" === row.rowType || "group" === row.rowType) }).length }, _getInsertIndex: function() { var maxInsertIndex = 0; this._editData.forEach(function(editItem) { if (editItem.type === DATA_EDIT_DATA_INSERT_TYPE && editItem.key[INSERT_INDEX] > maxInsertIndex) { maxInsertIndex = editItem.key[INSERT_INDEX] } }); return maxInsertIndex + 1 }, addRow: function(parentKey) { var $firstCell, that = this, dataController = that._dataController, store = dataController.store(), key = store && store.key(), rowsView = that.getView("rowsView"), param = { data: {} }, parentRowIndex = dataController.getRowIndexByKey(parentKey), insertKey = { pageIndex: dataController.pageIndex(), rowIndex: parentRowIndex >= 0 ? parentRowIndex + 1 : rowsView ? rowsView.getTopVisibleItemIndex(true) : 0, parentKey: parentKey }, oldEditRowIndex = that._getVisibleEditRowIndex(), editMode = _getEditMode(that); if (!store) { dataController.fireError("E1052", this.component.NAME); return } if (editMode === EDIT_MODE_CELL && that.hasChanges()) { that.saveEditData() } that.refresh(); var insertIndex = that._getInsertIndex(); if (editMode !== EDIT_MODE_BATCH && insertIndex > 1) { return } if (!key) { param.data.__KEY__ = String(new _guid2.default) } that._initNewRow(param, insertKey); editMode = _getEditMode(that); if (editMode !== EDIT_MODE_BATCH) { that._editRowIndex = insertKey.rowIndex + that._dataController.getRowIndexOffset() } insertKey[INSERT_INDEX] = insertIndex; that._addEditData({ key: insertKey, data: param.data, type: DATA_EDIT_DATA_INSERT_TYPE }); dataController.updateItems({ changeType: "update", rowIndices: [oldEditRowIndex, insertKey.rowIndex] }); if (editMode === EDIT_MODE_POPUP) { that._showEditPopup(insertKey.rowIndex) } else { $firstCell = that.getFirstEditableCellInRow(insertKey.rowIndex); that._editCellInProgress = true; that._delayedInputFocus($firstCell, function() { that._editCellInProgress = false; var $cell = that.getFirstEditableCellInRow(insertKey.rowIndex); $cell && _events_engine2.default.trigger($cell, _click2.default.name) }) } that._afterInsertRow({ key: insertKey, data: param.data }) }, _isEditingStart: function(options) { this.executeAction("onEditingStart", options); return options.cancel }, _beforeEditCell: function(rowIndex, columnIndex, item) { var that = this; if (_getEditMode(that) === EDIT_MODE_CELL && !item.inserted && that.hasChanges()) { var d = new _deferred.Deferred; that.saveEditData().always(function() { d.resolve(that.hasChanges()) }); return d } }, _beforeUpdateItems: function() {}, _getVisibleEditRowIndex: function() { return this._editRowIndex >= 0 ? this._editRowIndex - this._dataController.getRowIndexOffset() : -1 }, editRow: function(rowIndex) { var $editingCell, that = this, dataController = that._dataController, items = dataController.items(), item = items[rowIndex], params = { data: item && item.data, cancel: false }, oldEditRowIndex = that._getVisibleEditRowIndex(); if (!item) { return } if (rowIndex === oldEditRowIndex) { return true } if (!item.inserted) { params.key = item.key } if (that._isEditingStart(params)) { return } that.init(); that._pageIndex = dataController.pageIndex(); that._editRowIndex = (items[0].inserted ? rowIndex - 1 : rowIndex) + that._dataController.getRowIndexOffset(); that._addEditData({ data: {}, key: item.key, oldData: item.data }); var rowIndices = [oldEditRowIndex, rowIndex], editMode = _getEditMode(that); that._beforeUpdateItems(rowIndices, rowIndex, oldEditRowIndex); if (editMode === EDIT_MODE_POPUP) { that._showEditPopup(rowIndex) } else { dataController.updateItems({ changeType: "update", rowIndices: rowIndices }) } if (MODES_WITH_DELAYED_FOCUS.indexOf(editMode) !== -1) { $editingCell = that.getFocusedCellInRow(that._getVisibleEditRowIndex()); that._delayedInputFocus($editingCell, function() { $editingCell && that.component.focus($editingCell) }) } }, _showEditPopup: function(rowIndex) { var that = this, isMobileDevice = "desktop" !== _devices2.default.current().deviceType, popupOptions = (0, _extend.extend)({ showTitle: false, fullScreen: isMobileDevice, toolbarItems: [{ toolbar: "bottom", location: "after", widget: "dxButton", options: that._getSaveButtonConfig() }, { toolbar: "bottom", location: "after", widget: "dxButton", options: that._getCancelButtonConfig() }], contentTemplate: that._getPopupEditFormTemplate(rowIndex) }, that.option("editing.popup")); if (!that._editPopup) { var $popupContainer = (0, _renderer2.default)("<div>").appendTo(that.component.$element()).addClass(that.addWidgetPrefix(EDIT_POPUP_CLASS)); that._editPopup = that._createComponent($popupContainer, _popup2.default, {}); that._editPopup.on("hiding", that._getEditPopupHiddenHandler()); that._editPopup.on("shown", function(e) { _events_engine2.default.trigger(e.component.$content().find(FOCUSABLE_ELEMENT_SELECTOR).not("." + SCROLLABLE_CONTAINER_CLASS).first(), "focus") }) } that._editPopup.option(popupOptions); that._editPopup.show() }, _getEditPopupHiddenHandler: function() { var that = this; return function(e) { if (that.isEditing()) { that.cancelEditData() } } }, _getPopupEditFormTemplate: function(rowIndex) { var that = this, row = that.component.getVisibleRows()[rowIndex], templateOptions = { row: row, rowType: row.rowType, key: row.key }; return function(container) { var formTemplate = that.getEditFormTemplate(), scrollable = that._createComponent((0, _renderer2.default)("<div>").appendTo(container), _ui4.default); that._$popupContent = scrollable.$content(); formTemplate(that._$popupContent, templateOptions, true) } }, _getSaveButtonConfig: function() { return { text: this.option("editing.texts.saveRowChanges"), onClick: this.saveEditData.bind(this) } }, _getCancelButtonConfig: function() { return { text: this.option("editing.texts.cancelRowChanges"), onClick: this.cancelEditData.bind(this) } }, _removeEditDataItem: function(index) { if (index >= 0) { this._editData.splice(index, 1) } }, editCell: function(rowIndex, columnIndex) { var that = this, columnsController = that._columnsController, dataController = that._dataController, items = dataController.items(), item = items[rowIndex], params = { data: item && item.data, cancel: false }, oldEditRowIndex = that._getVisibleEditRowIndex(), visibleColumns = columnsController.getVisibleColumns(), oldColumn = visibleColumns[that._editColumnIndex]; if (_type2.default.isString(columnIndex)) { columnIndex = columnsController.columnOption(columnIndex, "index"); columnIndex = columnsController.getVisibleIndex(columnIndex) } var column = params.column = visibleColumns[columnIndex]; if (column && item && ("data" === item.rowType || "detailAdaptive" === item.rowType) && !item.removed && !_isRowEditMode(that)) { if (that.isEditCell(rowIndex, columnIndex)) { return true } var editRowIndex = rowIndex + dataController.getRowIndexOffset(); return (0, _deferred.when)(that._beforeEditCell(rowIndex, columnIndex, item)).done(function(cancel) { if (cancel) { return } if (that._prepareEditCell(params, item, columnIndex, editRowIndex)) { _common2.default.deferRender(function() { that._repaintEditCell(column, oldColumn, oldEditRowIndex) }) } else { that._processCanceledEditingCell() } }) } return false }, _processCanceledEditingCell: function() {}, _prepareEditCell: function(params, item, editColumnIndex, editRowIndex) { var that = this; if (!item.inserted) { params.key = item.key } if (that._isEditingStart(params)) { return false } that._editRowIndex = editRowIndex; that._editColumnIndex = editColumnIndex; that._pageIndex = that._dataController.pageIndex(); that._addEditData({ data: {}, key: item.key, oldData: item.data }); return true }, _repaintEditCell: function(column, oldColumn, oldEditRowIndex) { var that = this, rowsView = that._rowsView; if (!column || !column.showEditorAlways || oldColumn && !oldColumn.showEditorAlways) { that._editCellInProgress = true; that.getController("editorFactory").loseFocus(); that._dataController.updateItems({ changeType: "update", rowIndices: [oldEditRowIndex, that._getVisibleEditRowIndex()] }) } var $cell = rowsView && rowsView._getCellElement(that._getVisibleEditRowIndex(), that._editColumnIndex); if ($cell && !$cell.find(":focus").length) { that._focusEditingCell(function() { that._editCellInProgress = false }, $cell, true) } else { that._editCellInProgress = false } }, _delayedInputFocus: function($cell, beforeFocusCallback, callBeforeFocusCallbackAlways) { var that = this; function inputFocus() { if (beforeFocusCallback) { beforeFocusCallback() } $cell && _events_engine2.default.trigger($cell.find(FOCUSABLE_ELEMENT_SELECTOR).first(), "focus"); that._beforeFocusCallback = null } if (_devices2.default.real().ios || _devices2.default.real().android) { inputFocus() } else { if (that._beforeFocusCallback) { that._beforeFocusCallback() } clearTimeout(that._inputFocusTimeoutID); if (callBeforeFocusCallbackAlways) { that._beforeFocusCallback = beforeFocusCallback } that._inputFocusTimeoutID = setTimeout(inputFocus) } }, _focusEditingCell: function(beforeFocusCallback, $editCell, callBeforeFocusCallbackAlways) { var that = this, rowsView = that.getView("rowsView"); $editCell = $editCell || rowsView && rowsView._getCellElement(that._getVisibleEditRowIndex(), that._editColumnIndex); that._delayedInputFocus($editCell, beforeFocusCallback, callBeforeFocusCallbackAlways) }, removeRow: function(rowIndex) { _ui2.default.log("W0002", "dxDataGrid", "removeRow", "15.2", "Use the 'deleteRow' method instead"); return this.deleteRow(rowIndex) }, deleteRow: function(rowIndex) { var removeByKey, showDialogTitle, that = this, editingOptions = that.option("editing"), editingTexts = editingOptions && editingOptions.texts, confirmDeleteTitle = editingTexts && editingTexts.confirmDeleteTitle, isBatchMode = editingOptions && editingOptions.mode === EDIT_MODE_BATCH, confirmDeleteMessage = editingTexts && editingTexts.confirmDeleteMessage, dataController = that._dataController, oldEditRowIndex = that._getVisibleEditRowIndex(), item = dataController.items()[rowIndex], key = item && item.key, allowDeleting = isBatchMode || !this.isEditing(); if (item && allowDeleting) { removeByKey = function(key) { that.refresh(); var editIndex = (0, _uiGrid_core3.getIndexByKey)(key, that._editData); if (editIndex >= 0) { if (that._editData[editIndex].type === DATA_EDIT_DATA_INSERT_TYPE) { that._removeEditDataItem(editIndex) } else { that._addEditData({ key: key, type: DATA_EDIT_DATA_REMOVE_TYPE }) } } else { that._addEditData({ key: key, oldData: item.data, type: DATA_EDIT_DATA_REMOVE_TYPE }) } if (isBatchMode) { dataController.updateItems({ changeType: "update", rowIndices: [oldEditRowIndex, rowIndex] }) } else { that.saveEditData() } }; if (isBatchMode || !confirmDeleteMessage) { removeByKey(key) } else { showDialogTitle = _type2.default.isDefined(confirmDeleteTitle) && confirmDeleteTitle.length > 0; _dialog2.default.confirm(confirmDeleteMessage, confirmDeleteTitle, showDialogTitle).done(function(confirmResult) { if (confirmResult) { removeByKey(key) } }) } } }, undeleteRow: function(rowIndex) { var that = this, dataController = that._dataController, item = dataController.items()[rowIndex], oldEditRowIndex = that._getVisibleEditRowIndex(), key = item && item.key; if (item) { var editData, editIndex = (0, _uiGrid_core3.getIndexByKey)(key, that._editData); if (editIndex >= 0) { editData = that._editData[editIndex]; if (_type2.default.isEmptyObject(editData.data)) { that._removeEditDataItem(editIndex) } else { that._addEditData({ key: key, type: DATA_EDIT_DATA_UPDATE_TYPE }) } dataController.updateItems({ changeType: "update", rowIndices: [oldEditRowIndex, rowIndex] }) } } }, _saveEditDataCore: function(deferreds, results, changes) { var that = this, store = that._dataController.store(), isDataSaved = true; function executeEditingAction(actionName, params, func) { var deferred = new _deferred.Deferred; that.executeAction(actionName, params); function createFailureHandler(deferred) { return function(arg) { var error = arg instanceof Error ? arg : new Error(arg && String(arg) || "Unknown error"); deferred.reject(error) } }(0, _deferred.when)((0, _deferred.fromPromise)(params.cancel)).done(function(cancel) { if (cancel) { setTimeout(function() { deferred.resolve("cancel") }) } else { func(params).done(deferred.resolve).fail(createFailureHandler(deferred)) } }).fail(createFailureHandler(deferred)); return deferred }(0, _iterator.each)(that._editData, function(index, editData) { var deferred, doneDeferred, params, data = editData.data, oldData = editData.oldData, type = editData.type; if (that._beforeSaveEditData(editData, index)) { return } switch (type) { case DATA_EDIT_DATA_REMOVE_TYPE: params = { data: oldData, key: editData.key, cancel: false }; deferred = executeEditingAction("onRowRemoving", params, function() { return store.remove(editData.key).done(function(key) { changes.push({ type: "remove", key: key }) }) }); break; case DATA_EDIT_DATA_INSERT_TYPE: params = { data: data, cancel: false }; deferred = executeEditingAction("onRowInserting", params, function() { return store.insert(params.data).done(function(data, key) { if (_type2.default.isDefined(key)) { editData.key = key } if (data && _type2.default.isObject(data) && data !== params.data) { editData.data = data }