@syncfusion/ej2-grids
Version:
Feature-rich JavaScript datagrid (datatable) control with built-in support for editing, filtering, grouping, paging, sorting, and exporting to Excel.
1,157 lines • 72.9 kB
JavaScript
import { extend, addClass, removeClass, setValue, closest, select, EventHandler } from '@syncfusion/ej2-base';
import { remove, classList } from '@syncfusion/ej2-base';
import { isNullOrUndefined, isUndefined } from '@syncfusion/ej2-base';
import { CellType } from '../base/enum';
import { parentsUntil, refreshForeignData, getObject, addRemoveEventListener, getCellFromRow } from '../base/util';
import { getCellByColAndRowIndex, addFixedColumnBorder } from '../base/util';
import * as events from '../base/constant';
import { RowRenderer } from '../renderer/row-renderer';
import { CellRenderer } from '../renderer/cell-renderer';
import { Row } from '../models/row';
import { Cell } from '../models/cell';
import { RowModelGenerator } from '../services/row-model-generator';
import { DataUtil } from '@syncfusion/ej2-data';
import * as literals from '../base/string-literals';
/**
* `BatchEdit` module is used to handle batch editing actions.
*
* @hidden
*/
var BatchEdit = /** @class */ (function () {
function BatchEdit(parent, serviceLocator, renderer) {
this.cellDetails = {};
this.args = {};
this.originalCell = {};
this.cloneCell = {};
this.editNext = false;
this.preventSaveCell = false;
this.initialRender = true;
this.validationColObj = [];
/** @hidden */
this.addBatchRow = false;
this.prevEditedBatchCell = false;
this.undoStack = [];
this.redoStack = [];
this.storedRowUids = new Set();
this.isUndoAction = false;
this.isRedoAction = false;
this.parent = parent;
this.serviceLocator = serviceLocator;
this.renderer = renderer;
this.focus = serviceLocator.getService('focus');
this.addEventListener();
}
/**
* @returns {void}
* @hidden
*/
BatchEdit.prototype.addEventListener = function () {
if (this.parent.isDestroyed) {
return;
}
this.evtHandlers = [{ event: events.click, handler: this.clickHandler },
{ event: events.dblclick, handler: this.dblClickHandler },
{ event: events.beforeCellFocused, handler: this.onBeforeCellFocused },
{ event: events.cellFocused, handler: this.onCellFocused },
{ event: events.doubleTap, handler: this.dblClickHandler },
{ event: events.keyPressed, handler: this.keyDownHandler },
{ event: events.editNextValCell, handler: this.editNextValCell },
{ event: events.destroy, handler: this.destroy }];
addRemoveEventListener(this.parent, this.evtHandlers, true, this);
EventHandler.add(this.parent.element, 'mousedown', this.mouseDownHandler, this);
this.dataBoundFunction = this.dataBound.bind(this);
this.batchCancelFunction = this.batchCancel.bind(this);
this.parent.addEventListener(events.dataBound, this.dataBoundFunction);
this.parent.addEventListener(events.batchCancel, this.batchCancelFunction);
};
/**
* @returns {void}
* @hidden
*/
BatchEdit.prototype.removeEventListener = function () {
if (this.parent.isDestroyed) {
return;
}
addRemoveEventListener(this.parent, this.evtHandlers, false);
EventHandler.remove(this.parent.element, 'mousedown', this.mouseDownHandler);
this.parent.removeEventListener(events.dataBound, this.dataBoundFunction);
this.parent.removeEventListener(events.batchCancel, this.batchCancelFunction);
};
BatchEdit.prototype.batchCancel = function () {
this.clearStacks();
this.parent.focusModule.restoreFocus({ requestType: 'batchCancel' });
};
BatchEdit.prototype.dataBound = function () {
this.parent.notify(events.toolbarRefresh, {});
};
/**
* @returns {void}
* @hidden
*/
BatchEdit.prototype.destroy = function () {
this.removeEventListener();
};
/**
* Pushes an action to the specified stack with size management.
*
* @param {IUndoRedoAction[]} stack - The stack to push to (undo or redo)
* @param {IUndoRedoAction} action - The action to push
* @returns {void}
*/
BatchEdit.prototype.pushToStack = function (stack, action) {
stack.push(action);
if (stack.length > this.parent.editSettings.undoRedoLimit) {
stack.shift();
}
};
/**
* Clears both undo and redo stacks.
*
* @returns {void}
* @hidden
*/
BatchEdit.prototype.clearStacks = function () {
this.undoStack = [];
this.redoStack = [];
this.storedRowUids.clear();
};
BatchEdit.prototype.restoreCellSelection = function (args) {
var gObj = this.parent;
gObj.clearSelection();
var colIndex = gObj.getColumnIndexByField(args.field);
gObj.selectionModule.selectCell({ rowIndex: args.rowIndex, cellIndex: colIndex });
};
BatchEdit.prototype.storeDeleteAction = function (deleteArgs) {
if (!this.parent.editSettings.enableUndoRedo || !deleteArgs) {
return;
}
var gObj = this.parent;
var deletedRowsData = [];
var deletedRowLength = deleteArgs.row.length;
if (Array.isArray(deleteArgs.row) && deletedRowLength) {
for (var i = 0; i < deletedRowLength; i++) {
var rowElement = deleteArgs.row[parseInt(i.toString(), 10)];
var uid = rowElement.getAttribute('data-uid');
if (!rowElement.classList.contains('e-insertedrow')) {
var rowIndex = rowElement.rowIndex;
var rowObj = gObj.getRowObjectFromUID(uid);
if (rowObj) {
deletedRowsData.push({
rowUid: uid,
rowIndex: rowIndex,
rowData: rowObj.data
});
}
}
}
}
else if (deleteArgs.row) {
var rowUid = deleteArgs.row.getAttribute('data-uid');
var row = gObj.getRowObjectFromUID(rowUid);
if (row) {
var rowIndex = deleteArgs.row.rowIndex;
deletedRowsData.push({
rowUid: row.uid,
rowIndex: rowIndex,
rowData: row.data
});
}
}
if (deletedRowsData.length > 0) {
var action = {
type: 'row-delete',
deletedRows: deletedRowsData
};
this.pushToStack(this.undoStack, action);
this.redoStack = [];
}
};
/**
* Stores the action in the undo stack after the cell is saved.
*
* @param {CellSaveArgs} args - The cell save arguments
* @returns {void}
*/
BatchEdit.prototype.storeCellsInUndoStack = function (args) {
if (!this.parent.editSettings.enableUndoRedo || args.action) {
return;
}
var gObj = this.parent;
var action;
var tr = args.cell.parentElement;
var rowUid = tr.getAttribute('data-uid');
var row = gObj.getRowObjectFromUID(rowUid);
var rowIndex = row.index;
if (!row) {
return;
}
if (row.edit === 'add') {
var rowData = row.changes;
if (this.storedRowUids.has(row.uid)) {
var lastAction = this.undoStack[this.undoStack.length - 1];
if (lastAction && lastAction.type === 'row-add' && lastAction.rowUid === row.uid) {
lastAction.rowData = rowData;
}
return;
}
this.storedRowUids.add(row.uid);
action = {
type: 'row-add',
rowUid: row.uid,
rowIndex: rowIndex,
rowData: rowData
};
}
else if ((!isNullOrUndefined(args.previousValue) && !isNullOrUndefined(args.value)) ?
(args.previousValue.toString() !== args.value.toString()) : (args.previousValue !== args.value)) {
action = {
type: 'cell-edit',
rowUid: row.uid,
rowIndex: rowIndex,
field: args.columnName,
previousValue: args.previousValue,
newValue: args.value
};
}
if (action) {
this.pushToStack(this.undoStack, action);
this.redoStack = [];
}
};
/**
* Undo the last batch edit action and restore the grid to its previous state.
*
* @returns {void}
* @hidden
*/
BatchEdit.prototype.undoBatchEdit = function () {
if (!this.parent.editSettings.enableUndoRedo || this.undoStack.length === 0) {
return;
}
var action = this.undoStack.pop();
if (!action) {
return;
}
this.isUndoAction = true;
this.parent.clearSelection();
this.parent.focusModule.clearIndicator();
this.undoAction(action);
this.isUndoAction = false;
if (this.parent.aggregates.length > 0) {
if (!(this.parent.isReact || this.parent.isVue)) {
this.parent.notify(events.refreshFooterRenderer, {});
}
if (this.parent.groupSettings.columns.length > 0) {
this.parent.notify(events.groupAggregates, {});
}
if (this.parent.isReact || this.parent.isVue) {
this.parent.notify(events.refreshFooterRenderer, {});
}
}
var cellSaveArgs = {
cancel: false,
action: 'undo'
};
this.parent.trigger(events.cellSaved, cellSaveArgs);
this.pushToStack(this.redoStack, action);
this.parent.notify(events.toolbarRefresh, {});
};
/**
* Redo the last undone batch edit action and reapply the changes to the grid.
*
* @returns {void}
* @hidden
*/
BatchEdit.prototype.redoBatchEdit = function () {
if (!this.parent.editSettings.enableUndoRedo || this.redoStack.length === 0) {
return;
}
var action = this.redoStack.pop();
if (!action) {
return;
}
this.isRedoAction = true;
this.redoAction(action);
this.isRedoAction = false;
if (this.parent.aggregates.length > 0) {
if (!(this.parent.isReact || this.parent.isVue)) {
this.parent.notify(events.refreshFooterRenderer, {});
}
if (this.parent.groupSettings.columns.length > 0) {
this.parent.notify(events.groupAggregates, {});
}
if (this.parent.isReact || this.parent.isVue) {
this.parent.notify(events.refreshFooterRenderer, {});
}
}
var cellSaveArgs = {
cancel: false,
action: 'redo'
};
this.parent.trigger(events.cellSaved, cellSaveArgs);
this.pushToStack(this.undoStack, action);
this.parent.notify(events.toolbarRefresh, {});
};
/**
* Cleans up a restored cell if value matches original.
*
* @param {string} rowUid - specfies the rowUid
* @param {string} field - specfies the column field
* @param {string | number | boolean | Date } previousValue - specfies the pervious value
* @returns {void}
*/
BatchEdit.prototype.restoreCellState = function (rowUid, field, previousValue) {
var gObj = this.parent;
var rowObject = gObj.getRowObjectFromUID(rowUid);
var currentValue = getObject(field, rowObject.changes);
var isValueRestored = (previousValue instanceof Date && currentValue instanceof Date) ?
new Date(previousValue).toString() === new Date(currentValue).toString() :
previousValue === currentValue;
if (!rowObject || !rowObject.changes || !currentValue || !isValueRestored) {
return;
}
var col = gObj.getColumnByField(field);
var colIndex = gObj.getColumnIndexByField(field);
if (col && colIndex >= 0) {
var td = gObj.isSpan ? getCellFromRow(gObj, rowObject.index, colIndex) :
getCellByColAndRowIndex(this.parent, col, rowObject.index, colIndex);
if (td) {
if (isValueRestored) {
td.classList.remove('e-updatedtd');
}
}
}
};
/**
* Handles undo and redo for the autofill operation.
*
* @param {IAutoFill} autoFillAction - autofill action from undo/redo stack
* @returns {void}
*/
BatchEdit.prototype.autoFill = function (autoFillAction) {
if (!autoFillAction || !autoFillAction.cells) {
return;
}
for (var _i = 0, _a = autoFillAction.cells; _i < _a.length; _i++) {
var cell = _a[_i];
var value = this.isUndoAction ? cell.previousValue : cell.newValue;
this.updateCell(cell.rowIndex, cell.field, value);
this.restoreCellState(cell.rowUid, cell.field, cell.previousValue);
this.restoreCellSelection(cell);
}
};
/**
* Restores an action to its previous state.
*
* @param {IUndoRedoAction} action - The action to revert
* @returns {void}
*/
BatchEdit.prototype.undoAction = function (action) {
var gObj = this.parent;
switch (action.type) {
case 'auto-fill':
if (action.cells) {
this.autoFill(action);
}
break;
case 'cell-edit':
case 'paste':
if (action.field) {
this.updateCell(action.rowIndex, action.field, action.previousValue);
this.restoreCellState(action.rowUid, action.field, action.previousValue);
this.restoreCellSelection(action);
}
break;
case 'row-add':
if (action.rowUid) {
this.storedRowUids.delete(action.rowUid);
var rowElement = gObj.getRowByIndex(action.rowIndex);
if (rowElement) {
gObj.deleteRow(rowElement);
}
}
break;
case 'row-delete':
if (action.deletedRows) {
this.restoreDeletedRows(action.deletedRows);
}
break;
}
};
/**
* Reapplies a previously undone action.
*
* @param {IUndoRedoAction} action - The action to reapply
* @returns {void}
* @private
*/
BatchEdit.prototype.redoAction = function (action) {
var gObj = this.parent;
switch (action.type) {
case 'auto-fill':
if (action.cells) {
this.autoFill(action);
}
break;
case 'cell-edit':
case 'paste':
if (action.field) {
this.updateCell(action.rowIndex, action.field, action.newValue);
this.restoreCellSelection(action);
}
break;
case 'row-add':
if (action.rowData) {
gObj.addRecord(action.rowData);
}
break;
case 'row-delete':
if (action.deletedRows) {
var deletedRowsData = action.deletedRows;
for (var i = deletedRowsData.length - 1; i >= 0; i--) {
gObj.deleteRecord(undefined, deletedRowsData[parseInt(i.toString(), 10)].rowData);
}
}
break;
}
};
/**
* Defines whether an undo action is available.
*
* @returns {boolean} - True if undo stack has actions
* @hidden
*/
BatchEdit.prototype.isUndoStackAvailable = function () {
return this.parent.editSettings.enableUndoRedo && this.undoStack.length > 0;
};
/**
* Defines whether an redo action is available.
*
* @returns {boolean} - True if redo stack has actions
* @hidden
*/
BatchEdit.prototype.isRedoStackAvailable = function () {
return this.parent.editSettings.enableUndoRedo && this.redoStack.length > 0;
};
BatchEdit.prototype.mouseDownHandler = function (e) {
if (!isNullOrUndefined(this.parent.element.querySelector('.e-gridform'))) {
this.mouseDownElement = e.target;
}
else {
this.mouseDownElement = undefined;
}
};
BatchEdit.prototype.clickHandler = function (e) {
if (!parentsUntil(e.target, this.parent.element.id + '_add', true)) {
if ((this.parent.isEdit && closest(this.form, 'td') !== closest(e.target, 'td'))
&& isNullOrUndefined(this.mouseDownElement) || this.mouseDownElement === e.target) {
this.saveCell();
this.editNextValCell();
}
if (parentsUntil(e.target, literals.rowCell) && !this.parent.isEdit) {
this.setCellIdx(e.target);
}
}
};
BatchEdit.prototype.dblClickHandler = function (e) {
var target = parentsUntil(e.target, literals.rowCell);
var tr = parentsUntil(e.target, literals.row);
var rowIndex = tr && parseInt(tr.getAttribute(literals.ariaRowIndex), 10) - 1;
var colIndex = target && parseInt(target.getAttribute(literals.ariaColIndex), 10) - 1;
if (!isNullOrUndefined(target) && !isNullOrUndefined(rowIndex) && !isNaN(colIndex)
&& !target.parentElement.classList.contains(literals.editedRow) &&
this.parent.getColumns()[parseInt(colIndex.toString(), 10)].allowEditing) {
this.editCell(rowIndex, this.parent.getColumns()[parseInt(colIndex.toString(), 10)].field, this.isAddRow(rowIndex));
}
};
BatchEdit.prototype.onBeforeCellFocused = function (e) {
if (this.parent.isEdit && this.validateFormObj() &&
(e.byClick || (['tab', 'shiftTab', 'enter', 'shiftEnter'].indexOf(e.keyArgs.action) > -1))) {
e.cancel = true;
if (e.byClick) {
e.clickArgs.preventDefault();
}
else {
e.keyArgs.preventDefault();
}
}
};
BatchEdit.prototype.onCellFocused = function (e) {
var clear = (!e.container.isContent || !e.container.isDataCell)
&& !((this.parent.frozenRows || this.parent.pinnedTopRowModels.length) && e.container.isHeader);
if (this.parent.focusModule.active) {
this.prevEditedBatchCell = this.parent.focusModule.active.matrix.current.toString() === this.prevEditedBatchCellMatrix()
.toString();
this.crtRowIndex = [].slice.call(this.parent.focusModule.active.getTable().rows).indexOf(closest(e.element, 'tr'));
}
if (!e.byKey || clear) {
if ((this.parent.isEdit && clear)) {
this.saveCell();
}
return;
}
var _a = e.container.indexes, rowIndex = _a[0], cellIndex = _a[1];
var actualIndex = e.element.getAttribute('aria-colindex') ? parseInt(e.element.getAttribute('aria-colindex'), 10) - 1 : cellIndex;
if (actualIndex !== cellIndex) {
cellIndex = actualIndex;
}
if (this.parent.frozenRows && e.container.isContent) {
rowIndex += ((this.parent.getContent().querySelector('.e-hiddenrow') ? 0 : this.parent.frozenRows) +
this.parent.getHeaderContent().querySelectorAll('.e-insertedrow').length);
}
var isEdit = this.parent.isEdit;
if (!this.parent.element.getElementsByClassName('e-popup-open').length) {
isEdit = isEdit && !this.validateFormObj();
switch (e.keyArgs.action) {
case 'tab':
case 'shiftTab':
// eslint-disable-next-line no-case-declarations
var indent = this.parent.isRowDragable() && this.parent.isDetail() ? 2 :
this.parent.isRowDragable() || this.parent.isDetail() ? 1 : 0;
// eslint-disable-next-line no-case-declarations
var col = this.parent.getColumns()[cellIndex - indent];
if (this.parent.editSettings.mode === 'Cell' && this.parent.enableVirtualization) {
var rowElement = e.element.parentElement;
rowIndex = rowElement && parseInt(rowElement.getAttribute(literals.ariaRowIndex), 10) - 1;
}
if (col && !this.parent.isEdit) {
this.editCell(rowIndex, col.field);
}
if (isEdit || this.parent.isLastCellPrimaryKey) {
this.editCellFromIndex(rowIndex, cellIndex);
}
break;
case 'enter':
case 'shiftEnter':
if (this.parent.editSettings.mode === 'Cell') {
if (isEdit) {
this.saveCell();
this.focus.focus(e);
}
else {
this.editCellFromIndex(rowIndex, cellIndex);
}
}
else {
e.keyArgs.preventDefault();
// eslint-disable-next-line no-case-declarations
var args = { cancel: false, keyArgs: e.keyArgs };
this.parent.notify('beforeFocusCellEdit', args);
if (!args.cancel && isEdit) {
this.editCell(rowIndex, this.cellDetails.column.field);
}
}
break;
case 'f2':
this.editCellFromIndex(rowIndex, cellIndex);
this.focus.focus();
break;
}
}
};
BatchEdit.prototype.isAddRow = function (index) {
return this.parent.getDataRows()[parseInt(index.toString(), 10)].classList.contains('e-insertedrow');
};
BatchEdit.prototype.editCellFromIndex = function (rowIdx, cellIdx) {
this.cellDetails.rowIndex = rowIdx;
this.cellDetails.cellIndex = cellIdx;
if (this.parent.editSettings.mode === 'Cell') {
this.editCell(rowIdx, this.parent.getColumns()[parseInt(cellIdx.toString(), 10)].field);
}
else {
this.editCell(rowIdx, this.parent.getColumns()[parseInt(cellIdx.toString(), 10)].field, this.isAddRow(rowIdx));
}
};
BatchEdit.prototype.closeEdit = function () {
var gObj = this.parent;
var rows = this.parent.getRowsObject();
if (this.parent.pinnedTopRowModels.length) {
rows = rows.concat(this.parent.pinnedTopRowModels);
}
var argument = { cancel: false, batchChanges: this.getBatchChanges() };
gObj.notify(events.beforeBatchCancel, argument);
if (argument.cancel) {
return;
}
if (gObj.isEdit) {
this.saveCell(true);
}
this.isAdded = false;
var selectedIndexes = [];
if (gObj.selectionModule) {
selectedIndexes = gObj.selectionModule.selectedRowIndexes;
}
gObj.clearSelection();
var hasDeletedRows = false;
for (var i = 0; i < rows.length; i++) {
var isInsert = false;
var isDirty = rows[parseInt(i.toString(), 10)].isDirty;
var edit = rows[parseInt(i.toString(), 10)].edit;
if (isDirty && edit === 'delete') {
hasDeletedRows = true;
}
isInsert = this.removeBatchElementChanges(rows[parseInt(i.toString(), 10)], isDirty);
if (isInsert) {
rows.splice(i, 1);
}
if (isInsert) {
i--;
}
}
if (gObj.frozenRows && hasDeletedRows) {
this.restoreFrozenRow();
}
if (!gObj.getContentTable().querySelector('tr.e-row')) {
gObj.renderModule.renderEmptyRow();
}
var args = {
requestType: 'batchCancel', rows: this.parent.getRowsObject()
};
gObj.notify(events.batchCancel, {
rows: this.parent.getRowsObject().length ? this.parent.getRowsObject() :
[new Row({ isDataRow: true, cells: [new Cell({ isDataCell: true, visible: true })] })]
});
if (gObj.isCheckBoxSelection && (gObj.selectionSettings.checkboxOnly || gObj.selectionSettings.persistSelection)) {
gObj.selectRows(selectedIndexes);
}
else {
gObj.selectRow(this.cellDetails.rowIndex);
}
if (this.parent.editSettings.enableUndoRedo && (gObj.isRedoStackAvailable() || gObj.isUndoStackAvailable())) {
this.clearStacks();
}
this.refreshRowIdx();
gObj.notify(events.toolbarRefresh, {});
this.parent.notify(events.tooltipDestroy, {});
args = { requestType: 'batchCancel', rows: this.parent.getRowsObject() };
gObj.trigger(events.batchCancel, args);
};
BatchEdit.prototype.removeBatchElementChanges = function (row, isDirty) {
var gObj = this.parent;
var rowRenderer = new RowRenderer(this.serviceLocator, null, this.parent);
var isInstertedRemoved = false;
if (isDirty) {
row.isDirty = isDirty;
var tr = gObj.getRowElementByUID(row.uid);
if (tr) {
if (tr.classList.contains('e-insertedrow')) {
remove(tr);
isInstertedRemoved = true;
}
else {
refreshForeignData(row, this.parent.getForeignKeyColumns(), row.data);
delete row.changes;
delete row.edit;
row.isDirty = false;
classList(tr, [], ['e-hiddenrow', 'e-updatedtd']);
this.refreshRowIdx();
rowRenderer.refresh(row, gObj.getColumns(), false);
}
if (this.parent.aggregates.length > 0) {
var type = 'type';
var editType = [];
editType["" + type] = 'cancel';
this.parent.notify(events.refreshFooterRenderer, editType);
if (this.parent.groupSettings.columns.length > 0) {
this.parent.notify(events.groupAggregates, editType);
}
}
}
}
return isInstertedRemoved;
};
/**
* Restores rows after batch cancel with frozen rows.
* @returns {void}
* @hidden
*/
BatchEdit.prototype.restoreFrozenRow = function () {
var gObj = this.parent;
if (!gObj.frozenRows) {
return;
}
var headerTbody = gObj.getHeaderTable().querySelector(literals.tbody);
var contentTbody = gObj.getContentTable().querySelector(literals.tbody);
var headerRows = [].slice.call(headerTbody.querySelectorAll('tr.e-row:not(.e-hiddenrow)'));
if (headerRows.length > gObj.frozenRows) {
var rowElements = headerRows.slice(gObj.frozenRows);
for (var _i = 0, rowElements_1 = rowElements; _i < rowElements_1.length; _i++) {
var rowElement = rowElements_1[_i];
contentTbody.insertBefore(rowElement, contentTbody.firstChild);
}
}
};
BatchEdit.prototype.deleteRecord = function (fieldname, data) {
this.saveCell();
if (this.validateFormObj()) {
this.saveCell(true);
}
this.isAdded = false;
this.bulkDelete(fieldname, data);
if (this.parent.aggregates.length > 0) {
if (!(this.parent.isReact || this.parent.isVue)) {
this.parent.notify(events.refreshFooterRenderer, {});
}
if (this.parent.groupSettings.columns.length > 0) {
this.parent.notify(events.groupAggregates, {});
}
if (this.parent.isReact || this.parent.isVue) {
this.parent.notify(events.refreshFooterRenderer, {});
}
}
};
BatchEdit.prototype.addRecord = function (data) {
this.bulkAddRow(data);
};
BatchEdit.prototype.restoreDeletedRows = function (deletedRows) {
if (!deletedRows) {
return;
}
var gObj = this.parent;
var deletedRecord = deletedRows;
for (var i = deletedRecord.length - 1; i >= 0; i--) {
var hiddenRows = gObj.getRowElementByUID(deletedRecord[parseInt(i.toString(), 10)].rowUid);
var rowUid = hiddenRows.getAttribute('data-uid');
var rowObj = gObj.getRowObjectFromUID(rowUid);
if (rowObj && rowObj.edit === 'delete') {
classList(hiddenRows, [], ['e-hiddenrow', 'e-updatedtd']);
delete rowObj.edit;
rowObj.isDirty = false;
}
}
this.refreshRowIdx();
gObj.focusModule.restoreFocus({ requestType: 'batchDelete' });
gObj.notify(events.batchDelete, { rows: this.parent.getRowsObject() });
gObj.notify(events.toolbarRefresh, {});
this.parent.notify(events.tooltipDestroy, {});
};
BatchEdit.prototype.endEdit = function () {
if (this.parent.isEdit && this.validateFormObj()) {
return;
}
this.batchSave();
};
BatchEdit.prototype.validateFormObj = function () {
return this.parent.editModule.formObj && !this.parent.editModule.formObj.validate();
};
BatchEdit.prototype.batchSave = function () {
var _this = this;
var gObj = this.parent;
var deletedRecords = 'deletedRecords';
if (gObj.isCheckBoxSelection) {
var checkAllBox = gObj.element.querySelector('.e-checkselectall').parentElement;
if (checkAllBox.classList.contains('e-checkbox-disabled') &&
gObj.pageSettings.totalRecordsCount > gObj.currentViewData.length) {
removeClass([checkAllBox], ['e-checkbox-disabled']);
}
}
this.saveCell();
if (gObj.isEdit || this.editNextValCell() || gObj.isEdit) {
return;
}
var changes = this.getBatchChanges();
if (this.parent.selectionSettings.type === 'Multiple' && changes["" + deletedRecords].length &&
this.parent.selectionSettings.persistSelection) {
changes["" + deletedRecords] = this.removeSelectedData;
this.removeSelectedData = [];
}
var original = {
changedRecords: this.parent.getRowsObject()
.filter(function (row) { return row.isDirty && ['add', 'delete'].indexOf(row.edit) === -1; })
.map(function (row) { return row.data; })
};
var args = { batchChanges: changes, cancel: false };
gObj.trigger(events.beforeBatchSave, args, function (beforeBatchSaveArgs) {
if (beforeBatchSaveArgs.cancel) {
return;
}
_this.clearStacks();
gObj.showSpinner();
gObj.notify(events.bulkSave, { changes: changes, original: original });
});
};
BatchEdit.prototype.getBatchChanges = function () {
var changes = {
addedRecords: [],
deletedRecords: [],
changedRecords: []
};
var rows = this.parent.getRowsObject();
if (this.parent.pinnedTopRowModels.length) {
rows = rows.concat(this.parent.pinnedTopRowModels);
}
for (var _i = 0, rows_1 = rows; _i < rows_1.length; _i++) {
var row = rows_1[_i];
if (row.isDirty) {
switch (row.edit) {
case 'add':
changes.addedRecords.push(row.changes);
break;
case 'delete':
changes.deletedRecords.push(row.data);
break;
default:
changes.changedRecords.push(row.changes);
}
}
}
return changes;
};
/**
* @param {string} uid - specifes the uid
* @returns {void}
* @hidden
*/
BatchEdit.prototype.removeRowObjectFromUID = function (uid) {
var rows = this.parent.getRowsObject();
var i = 0;
for (var len = rows.length; i < len; i++) {
if (rows[parseInt(i.toString(), 10)].uid === uid) {
break;
}
}
rows.splice(i, 1);
};
/**
* @param {Row<Column>} row - specifies the row object
* @returns {void}
* @hidden
*/
BatchEdit.prototype.addRowObject = function (row) {
var gObj = this.parent;
var isTop = gObj.editSettings.newRowPosition === 'Top';
var rowClone = row.clone();
if (isTop) {
gObj.getRowsObject().unshift(rowClone);
}
else {
gObj.getRowsObject().push(rowClone);
}
};
// tslint:disable-next-line:max-func-body-length
BatchEdit.prototype.bulkDelete = function (fieldname, data) {
var _this = this;
this.removeSelectedData = [];
var gObj = this.parent;
var index = gObj.selectedRowIndex;
var selectedRows = gObj.getSelectedRows();
var seletedCellDetails = gObj.selectionModule.getSeletedCellDetails();
var selectedCellRecords = gObj.getSelectedCellRecords();
var args = {
primaryKey: this.parent.getPrimaryKeyFieldNames(),
rowIndex: index,
rowData: data ? data : gObj.getSelectedRecords(),
cancel: false
};
if (data) {
args.row = gObj.editModule.deleteRowUid ? gObj.getRowElementByUID(gObj.editModule.deleteRowUid)
: gObj.getRows()[gObj.getCurrentViewRecords().indexOf(data)];
}
else if ((gObj.selectionSettings.mode === 'Cell' || gObj.selectionSettings.mode === 'Both')) {
selectedRows = args.row = seletedCellDetails.rowElements;
args.rowData = selectedCellRecords;
args.rowIndex = index = seletedCellDetails.rowIndexes[seletedCellDetails.rowIndexes.length - 1];
}
else {
args.row = selectedRows;
}
if (!args.row) {
return;
}
// tslint:disable-next-line:max-func-body-length
gObj.trigger(events.beforeBatchDelete, args, function (beforeBatchDeleteArgs) {
if (beforeBatchDeleteArgs.cancel) {
return;
}
_this.removeSelectedData = (gObj.selectionSettings.mode === 'Cell' || gObj.selectionSettings.mode === 'Both') &&
selectedCellRecords.length > 0 ? selectedCellRecords : gObj.getSelectedRecords();
gObj.clearSelection();
beforeBatchDeleteArgs.row = beforeBatchDeleteArgs.row ?
beforeBatchDeleteArgs.row : data ? gObj.getRows()[parseInt(index.toString(), 10)] :
selectedRows;
if (selectedRows.length === 1 || data) {
if (Array.isArray(beforeBatchDeleteArgs.row)) {
beforeBatchDeleteArgs.row = beforeBatchDeleteArgs.row[0];
}
var uid = beforeBatchDeleteArgs.row.getAttribute('data-uid');
uid = data && _this.parent.editModule.deleteRowUid ? uid = _this.parent.editModule.deleteRowUid : uid;
if (beforeBatchDeleteArgs.row.classList.contains('e-insertedrow')) {
_this.removeRowObjectFromUID(uid);
remove(beforeBatchDeleteArgs.row);
}
else {
var rowObj = gObj.getRowObjectFromUID(uid);
rowObj.isDirty = true;
rowObj.edit = 'delete';
classList(beforeBatchDeleteArgs.row, ['e-hiddenrow', 'e-updatedtd'], []);
if (gObj.frozenRows && index < gObj.frozenRows && gObj.getDataRows().length >= gObj.frozenRows) {
gObj.getHeaderTable().querySelector(literals.tbody).appendChild(gObj.getRowByIndex(gObj.frozenRows - 1));
}
}
if (gObj.editSettings.enableUndoRedo && !_this.isRedoAction && !_this.isUndoAction) {
_this.storeDeleteAction(beforeBatchDeleteArgs);
}
delete beforeBatchDeleteArgs.row;
}
else {
if (data) {
index = parseInt(beforeBatchDeleteArgs.row.getAttribute(literals.ariaRowIndex), 10) - 1;
}
for (var i = 0; i < selectedRows.length; i++) {
var uniqueid = selectedRows[parseInt(i.toString(), 10)].getAttribute('data-uid');
if (selectedRows[parseInt(i.toString(), 10)].classList.contains('e-insertedrow')) {
_this.removeRowObjectFromUID(uniqueid);
remove(selectedRows[parseInt(i.toString(), 10)]);
}
else {
classList(selectedRows[parseInt(i.toString(), 10)], ['e-hiddenrow', 'e-updatedtd'], []);
var selectedRow = gObj.getRowObjectFromUID(uniqueid);
selectedRow.isDirty = true;
selectedRow.edit = 'delete';
}
}
if (gObj.editSettings.enableUndoRedo && !_this.isRedoAction && !_this.isUndoAction) {
_this.storeDeleteAction(beforeBatchDeleteArgs);
}
if (gObj.frozenRows) {
var frozenTbody = gObj.getHeaderTable().querySelector(literals.tbody);
var frozenRowElements = frozenTbody ?
[].slice.call(frozenTbody.querySelectorAll('tr.e-row:not(.e-hiddenrow)')) : [];
var dataRows = gObj.getDataRows();
while (frozenRowElements.length < gObj.frozenRows && dataRows.length > frozenRowElements.length) {
var rowElement = frozenRowElements.length > 0 ?
gObj.getRowByIndex(gObj.frozenRows - 1) : gObj.getRowByIndex(0);
if (rowElement) {
frozenTbody.appendChild(rowElement);
frozenRowElements.push(rowElement);
}
else {
break;
}
}
}
delete beforeBatchDeleteArgs.row;
}
_this.refreshRowIdx();
if (data) {
gObj.editModule.deleteRowUid = undefined;
}
if (!gObj.isCheckBoxSelection) {
gObj.selectRow(index);
}
gObj.trigger(events.batchDelete, beforeBatchDeleteArgs);
gObj.notify(events.batchDelete, { rows: _this.parent.getRowsObject() });
gObj.focusModule.restoreFocus({ requestType: 'batchDelete' });
gObj.notify(events.toolbarRefresh, {});
if (!gObj.getContentTable().querySelector('tr.e-row')) {
gObj.renderModule.renderEmptyRow();
}
});
};
BatchEdit.prototype.refreshRowIdx = function () {
var gObj = this.parent;
var rows = gObj.getAllDataRows(true);
var dataObjects = gObj.getRowsObject().filter(function (row) { return !row.isDetailRow; });
for (var i = 0, j = 0, len = rows.length; i < len; i++) {
if (rows[parseInt(i.toString(), 10)].classList.contains(literals.row) && !rows[parseInt(i.toString(), 10)].classList.contains('e-hiddenrow')) {
rows[parseInt(i.toString(), 10)].setAttribute(literals.ariaRowIndex, (j + 1).toString());
dataObjects[parseInt(i.toString(), 10)].index = j;
j++;
}
else {
rows[parseInt(i.toString(), 10)].removeAttribute(literals.ariaRowIndex);
dataObjects[parseInt(i.toString(), 10)].index = -1;
}
}
};
BatchEdit.prototype.bulkAddRow = function (data) {
var _this = this;
var gObj = this.parent;
if (!gObj.editSettings.allowAdding) {
if (gObj.isEdit) {
this.saveCell();
}
return;
}
if (gObj.isEdit) {
this.saveCell();
this.parent.notify(events.editNextValCell, {});
}
if (this.validateFormObj()) {
return;
}
if (this.initialRender) {
var visibleColumns = gObj.getVisibleColumns();
for (var i = 0; i < visibleColumns.length; i++) {
if (visibleColumns[parseInt(i.toString(), 10)].validationRules &&
visibleColumns[parseInt(i.toString(), 10)].validationRules['required']) {
var obj = { field: (visibleColumns[parseInt(i.toString(), 10)]['field']).slice(), cellIdx: i };
this.validationColObj.push(obj);
}
}
this.initialRender = false;
}
this.parent.element.classList.add('e-editing');
var defaultData = data ? data : this.getDefaultData();
var args = {
defaultData: defaultData,
primaryKey: gObj.getPrimaryKeyFieldNames(),
cancel: false
};
gObj.trigger(events.beforeBatchAdd, args, function (beforeBatchAddArgs) {
if (beforeBatchAddArgs.cancel) {
return;
}
_this.isAdded = true;
gObj.clearSelection();
var row = new RowRenderer(_this.serviceLocator, null, _this.parent);
var model = new RowModelGenerator(_this.parent);
var modelData = model.generateRows([beforeBatchAddArgs.defaultData]);
var tr = row.render(modelData[0], gObj.getColumns());
addFixedColumnBorder(tr);
var col;
var index;
for (var i = 0; i < _this.parent.groupSettings.columns.length; i++) {
tr.insertBefore(_this.parent.createElement('td', { className: 'e-indentcell' }), tr.firstChild);
modelData[0].cells.unshift(new Cell({ cellType: CellType.Indent }));
}
var tbody = gObj.getContentTable().querySelector(literals.tbody);
tr.classList.add('e-insertedrow');
if (tbody.querySelector('.e-emptyrow')) {
var emptyRow = tbody.querySelector('.e-emptyrow');
emptyRow.parentNode.removeChild(emptyRow);
if (gObj.frozenRows && gObj.element.querySelector('.e-frozenrow-empty')) {
gObj.element.querySelector('.e-frozenrow-empty').classList.remove('e-frozenrow-empty');
}
}
if (gObj.frozenRows && gObj.editSettings.newRowPosition === 'Top') {
tbody = gObj.getHeaderTable().querySelector(literals.tbody);
}
else {
tbody = gObj.getContentTable().querySelector(literals.tbody);
}
if (_this.parent.editSettings.newRowPosition === 'Top') {
tbody.insertBefore(tr, tbody.firstChild);
}
else {
tbody.appendChild(tr);
}
addClass([].slice.call(tr.getElementsByClassName(literals.rowCell)), ['e-updatedtd']);
modelData[0].isDirty = true;
modelData[0].changes = extend({}, {}, modelData[0].data, true);
modelData[0].edit = 'add';
_this.addRowObject(modelData[0]);
_this.refreshRowIdx();
_this.focus.forgetPrevious();
gObj.notify(events.batchAdd, { rows: _this.parent.getRowsObject() });
var changes = _this.getBatchChanges();
var btmIdx = _this.getBottomIndex();
if (_this.parent.editSettings.newRowPosition === 'Top') {
gObj.selectRow(0);
}
else {
gObj.selectRow(btmIdx);
}
if (!data) {
index = _this.findNextEditableCell(0, true);
col = gObj.getColumns()[parseInt(index.toString(), 10)];
if (_this.parent.editSettings.newRowPosition === 'Top') {
_this.editCell(0, col.field, true);
}
else {
_this.editCell(btmIdx, col.field, true);
}
}
if (_this.parent.aggregates.length > 0 && (data || changes[literals.addedRecords].length)) {
_this.parent.notify(events.refreshFooterRenderer, {});
}
var args1 = {
defaultData: beforeBatchAddArgs.defaultData, row: tr,
columnObject: col, columnIndex: index, primaryKey: beforeBatchAddArgs.primaryKey,
cell: !isNullOrUndefined(index) ? tr.cells[parseInt(index.toString(), 10)] : undefined
};
gObj.trigger(events.batchAdd, args1);
});
};
BatchEdit.prototype.findNextEditableCell = function (columnIndex, isAdd, isValOnly) {
var cols = this.parent.getColumns();
var endIndex = cols.length;
var validation;
for (var i = columnIndex; i < endIndex; i++) {
validation = isValOnly ? isNullOrUndefined(cols[parseInt(i.toString(), 10)].validationRules) : false;
// if (!isAdd && this.checkNPCell(cols[parseInt(i.toString(), 10)])) {
// return i;
// } else
if (isAdd && (!cols[parseInt(i.toString(), 10)].template || cols[parseInt(i.toString(), 10)].field)
&& cols[parseInt(i.toString(), 10)].allowEditing && cols[parseInt(i.toString(), 10)].visible &&
!(cols[parseInt(i.toString(), 10)].isIdentity && cols[parseInt(i.toString(), 10)].isPrimaryKey) && !validation) {
return i;
}
}
return -1;
};
BatchEdit.prototype.getDefaultData = function () {
var gObj = this.parent;
var data = {};
var dValues = { 'number': 0, 'string': null, 'boolean': false, 'date': null, 'datetime': null, 'dateonly': null };
for (var _i = 0, _a = (gObj.columnModel); _i < _a.length; _i++) {
var col = _a[_i];
if (col.field) {
setValue(col.field, Object.keys(col).indexOf('defaultValue') >= 0 ? col.defaultValue : dValues[col.type], data);
}
}
return data;
};
BatchEdit.prototype.setCellIdx = function (target) {
var gLen = 0;
if (this.parent.allowGrouping) {
gLen = this.parent.groupSettings.columns.length;
}
this.cellDetails.cellIndex = target.cellIndex - gLen;
this.cellDetails.rowIndex = parseInt(target.getAttribute('data-index'), 10);
};
BatchEdit.prototype.editCell = function (index, field, isAdd) {
var gObj = this.parent;
var col = gObj.getColumnByField(field);
this.index = index;
this.field = field;
this.isAdd = isAdd;
var visibleRows = gObj.getDataRows();
visibleRows = visibleRows.filter(function (row) { return row.style.display !== 'none' && !row.classList.contains('e-childrow-hidden'); });
var lastRowIndex = parseInt(visibleRows[visibleRows.length - 1].getAttribute('aria-rowindex'), 10) - 1;
var checkEdit = gObj.isEdit && !(this.cellDetails && this.cellDetails.column && this.cellDetails.column.field === field
&& (this.cellDetails.rowIndex === index && lastRowIndex !== index && this.prevEditedBatchCell));
if (gObj.editSettings.allowEditing) {
if (!checkEdit && (col.allowEditing || (!col.allowEditing && gObj.focusModule.active
&& gObj.focusModule.active.getTable().rows[this.crtRowIndex]
&& gObj.focusModule.active.getTable().rows[this.crtRowIndex].classList.contains('e-insertedrow')))) {
this.editCellExtend(index, field, isAdd);
}
else if (checkEdit) {
this.editNext = true;
this.saveCell();
}
}
};
BatchEdit.prototype.editCellExtend = function (index, field, isAdd) {
var _this = this;
var gObj = this.parent;
var col = gObj.getColumnByField(field);
var keys = gObj.getPrimaryKeyFieldNames();
if (gObj.isEdit) {
return;
}
var rowData = extend({}, {}, this.getDataByIndex(index), true);
var row = gObj.getDataRows()[parseInt(index.toString(), 10)];
rowData = extend({}, {}, this.getDataByIndex(index), true);
if ((keys[0] === col.field && !row.classList.contains('e-insertedrow')) || col.columns ||
(col.isPrimaryKey && col.isIdentity) || col.commands) {
this.parent.isLastCellPrimaryKey = true;
return;
}
this.parent.isLastCellPrimaryKey = false;
this.parent.element.classList.add('e-editing');
var rowObj = gObj.getRowObjectFromUID(row.getAttribute('data-uid'));
var cells = [].slice.apply(row.cells);
var args = {
columnName: col.field, isForeign