devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
1,087 lines (1,082 loc) • 102 kB
JavaScript
/**
* 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
}