UNPKG

@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
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