@syncfusion/ej2-grids
Version:
Feature-rich JavaScript datagrid (datatable) control with built-in support for editing, filtering, grouping, paging, sorting, and exporting to Excel.
361 lines (360 loc) • 16 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { extend, removeClass, setValue, select } from '@syncfusion/ej2-base';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { parentsUntil, getObject, addRemoveEventListener } from '../base/util';
import * as events from '../base/constant';
import * as literals from '../base/string-literals';
import { BatchEdit } from './batch-edit';
import { Data } from './data';
import { NormalEdit } from './normal-edit';
/**
* `CellEdit` module is used to handle single-cell editing with keyboard navigation.
*
* @hidden
*/
var CellEdit = /** @class */ (function (_super) {
__extends(CellEdit, _super);
function CellEdit(parent, serviceLocator, renderer) {
var _this = _super.call(this, parent, serviceLocator, renderer) || this;
_this.data = new Data(parent, serviceLocator);
_this.renderer = renderer;
_this.cellEditModule = new NormalEdit(parent, serviceLocator, renderer);
_this.addEventListener();
return _this;
}
/**
* Register event listeners for cell edit mode.
*
* @returns {void}
* @hidden
*/
CellEdit.prototype.addEventListener = function () {
if (this.parent.isDestroyed) {
return;
}
this.evtHandlers = [
{ event: events.click, handler: this.clickHandler },
{ event: events.dblclick, handler: this.dblClickHandler },
{ event: events.cellFocused, handler: _super.prototype.onCellFocused },
{ event: events.destroy, handler: this.destroy },
{ event: events.deleteComplete, handler: this.editComplete },
{ event: events.saveComplete, handler: this.editComplete }
];
addRemoveEventListener(this.parent, this.evtHandlers, true, this);
};
/**
* Remove event listeners (called during destroy).
*
* @returns {void}
* @hidden
*/
CellEdit.prototype.removeEventListener = function () {
if (this.parent.isDestroyed) {
return;
}
addRemoveEventListener(this.parent, this.evtHandlers, false);
};
CellEdit.prototype.clickHandler = function (e) {
var target = e.target;
if (!parentsUntil(target, this.parent.element.id + '_add', true)) {
if (parentsUntil(target, literals.gridContent) &&
parentsUntil(parentsUntil(target, literals.gridContent), 'e-grid').id === this.parent.element.id
&& !parentsUntil(target, 'e-unboundcelldiv')) {
if (this.parent.isEdit) {
this.endEdit();
}
}
}
};
CellEdit.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);
}
};
/**
* Enter edit mode for specified cell.
*
* @param {number} rowIndex - Row index to edit
* @param {string} field - Column field to edit
* @returns {void}
*/
CellEdit.prototype.editCell = function (rowIndex, field) {
_super.prototype.editCell.call(this, rowIndex, field);
};
CellEdit.prototype.editCellExtend = function (rowIndex, field) {
var _this = this;
var gObj = this.parent;
var column = gObj.getColumnByField(field);
var keys = gObj.getPrimaryKeyFieldNames();
if (gObj.isEdit) {
return;
}
var rowData = extend({}, {}, this.getDataByIndex(rowIndex), true);
var row = gObj.getRowByIndex(rowIndex);
if (keys[0] === column.field || column.columns ||
(column.isPrimaryKey && column.isIdentity) || column.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: column.field, isForeignKey: !isNullOrUndefined(column.foreignKeyValue),
primaryKey: keys, rowData: rowData,
validationRules: extend({}, column.validationRules ? column.validationRules : {}),
value: getObject(column.field, rowData), requestType: 'beginEdit',
type: 'edit', cancel: false,
foreignKeyData: rowObj && rowObj.foreignKeyData
};
args.cell = cells[this.getColIndex(cells, this.getCellIdx(column.uid))];
args.row = row;
args.columnObject = column;
gObj.trigger(events.actionBegin, args, function (cellEditArgs) {
if (cellEditArgs.cancel) {
return;
}
cellEditArgs.cell = cellEditArgs.cell ? cellEditArgs.cell : cells[_this.getColIndex(cells, _this.getCellIdx(column.uid))];
cellEditArgs.row = cellEditArgs.row ? cellEditArgs.row : row;
cellEditArgs.columnObject = cellEditArgs.columnObject ? cellEditArgs.columnObject : column;
_this.cellDetails = {
rowData: rowData, column: column, value: cellEditArgs.value, isForeignKey: cellEditArgs.isForeignKey, rowIndex: rowIndex,
cellIndex: parseInt(cellEditArgs.cell.getAttribute(literals.ariaColIndex), 10) - 1,
foreignKeyData: cellEditArgs.foreignKeyData
};
gObj.isEdit = true;
var checkSelect = !isNullOrUndefined(cellEditArgs.row.querySelector('.e-selectionbackground')) ? true : false;
gObj.clearSelection();
if ((!gObj.isCheckBoxSelection || !gObj.isPersistSelection) && (checkSelect || !gObj.selectionSettings.checkboxOnly)) {
gObj.selectRow(_this.cellDetails.rowIndex, true);
}
_this.renderer.update(cellEditArgs);
_this.parent.notify(events.batchEditFormRendered, cellEditArgs);
_this.form = select('#' + gObj.element.id + 'EditForm', gObj.element);
_this.args = cellEditArgs;
gObj.editModule.applyFormValidation([column]);
_this.parent.element.querySelector('.e-gridpopup').style.display = 'none';
_this.parent.notify(events.toolbarRefresh, {});
gObj.trigger(events.actionComplete, cellEditArgs);
});
};
CellEdit.prototype.updateCell = function (rowIndex, field, value) {
var _this = this;
var rowElement = this.parent.getRowByIndex(rowIndex);
var args = {
requestType: 'save', action: 'edit', type: events.actionBegin, cancel: false,
rowData: this.parent.getCurrentViewRecords()[parseInt(rowIndex.toString(), 10)], row: rowElement
};
this.parent.trigger(events.actionBegin, args, function (updateCellArgs) {
if (updateCellArgs.cancel) {
return;
}
_super.prototype.updateCell.call(_this, rowIndex, field, value);
var rowObj = _this.parent.getRowObjectFromUID(rowElement.getAttribute('data-uid'));
if (rowObj && 'changes' in rowObj) {
delete rowObj.changes;
}
setValue(field, value, args.rowData);
_this.parent.notify(events.updateData, args);
args.type = events.actionComplete;
_this.parent.trigger(events.actionComplete, args);
});
};
/**
* Save current cell edit.
*
* @returns {void}
*/
CellEdit.prototype.saveCell = function () {
var _this = this;
var gObj = this.parent;
if (this.parent.isEdit && this.validateFormObj()) {
return;
}
var cellSaveArgs = _super.prototype.generateCellArgs.call(this);
var rowIndex = this.cellDetails.rowIndex;
var columnName = cellSaveArgs.columnName;
var saveArgs = extend({}, {
requestType: 'save',
type: events.actionBegin,
data: cellSaveArgs.rowData,
cancel: false,
previousData: cellSaveArgs.rowData,
selectedRow: gObj.selectedRowIndex,
action: 'edit',
cell: cellSaveArgs.cell,
columnName: columnName,
foreignKeyData: {},
rowIndex: rowIndex,
index: rowIndex
});
gObj.trigger(events.actionBegin, saveArgs, function (updateArgs) {
if (updateArgs.cancel) {
return;
}
setValue(columnName, cellSaveArgs.value, cellSaveArgs.rowData);
gObj.isEdit = false;
gObj.element.classList.remove('e-editing');
var rowElement = cellSaveArgs.cell.parentElement;
var column = _this.cellDetails.column;
if (rowElement) {
var cellElement = cellSaveArgs.cell;
if (!isNullOrUndefined(cellElement)) {
cellElement.innerHTML = '';
var displayValue = String(cellSaveArgs.value || '');
cellElement.textContent = displayValue;
removeClass([rowElement], [literals.editedRow]);
removeClass([cellElement], ['e-editedcell', 'e-boolcell']);
}
}
gObj.notify(events.updateData, updateArgs);
gObj.editModule.destroyWidgets([column]);
gObj.editModule.destroyForm();
var rowObj = gObj.getRowObjectFromUID(rowElement.getAttribute('data-uid'));
_this.refreshTD(cellSaveArgs.cell, column, rowObj, cellSaveArgs.value);
var isReactChild = _this.parent.parentDetails && _this.parent.parentDetails.parentInstObj &&
_this.parent.parentDetails.parentInstObj.isReact;
if (((_this.parent.isReact && _this.parent.requireTemplateRef) || (isReactChild &&
_this.parent.parentDetails.parentInstObj.requireTemplateRef)) && column.template) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
var thisRef_1 = _this;
var newReactTd_1 = _this.newReactTd;
thisRef_1.parent.renderTemplates(function () {
thisRef_1.parent.trigger(events.queryCellInfo, {
cell: newReactTd_1 || cellSaveArgs.cell, column: column, data: cellSaveArgs.rowData
});
});
}
else if ((_this.parent.isReact || isReactChild) && column.template) {
_this.parent.renderTemplates();
_this.parent.trigger(events.queryCellInfo, {
cell: _this.newReactTd || cellSaveArgs.cell, column: column, data: cellSaveArgs.rowData
});
}
if (!_this.parent.groupSettings.enableLazyLoading && _this.parent.aggregates.length &&
(_this.parent.enableInfiniteScrolling || _this.parent.enableVirtualization ||
(_this.parent.allowPaging && _this.parent.groupSettings.disablePageWiseAggregates))) {
_this.parent.notify(events.modelChanged, { requestType: 'refresh-aggregate-on-save', action: 'update' });
}
else if (_this.parent.aggregates.length) {
_this.parent.aggregateModule.refresh(cellSaveArgs.rowData, _this.parent.groupSettings.enableLazyLoading ? rowElement : undefined);
}
saveArgs.type = events.actionComplete;
gObj.trigger(events.actionComplete, saveArgs);
});
this.preventSaveCell = false;
if (this.editNext) {
this.editNext = false;
if (this.cellDetails.rowIndex === this.index && this.cellDetails.column.field === this.field && this.prevEditedBatchCell) {
return;
}
var column = gObj.getColumnByField(this.field);
if (column && column.allowEditing) {
this.editCellExtend(this.index, this.field);
}
}
};
CellEdit.prototype.endEdit = function () {
if (this.parent.isEdit && this.validateFormObj()) {
return;
}
if ([].slice.call(this.parent.element.getElementsByClassName(literals.addedRow)).length) {
this.cellEditModule.endEdit();
}
else {
this.saveCell();
}
};
CellEdit.prototype.closeEdit = function () {
if ([].slice.call(this.parent.element.getElementsByClassName(literals.addedRow)).length) {
this.cellEditModule.closeEdit();
}
else {
this.closeCellEdit();
}
};
/**
* Close edit mode and cleanup.
*
* @returns {void}
* @hidden
*/
CellEdit.prototype.closeCellEdit = function () {
var _this = this;
var gObj = this.parent;
var args = extend(this.args, {
requestType: 'cancel', type: events.actionBegin, cancel: false, data: this.cellDetails.rowData, selectedRow: gObj.selectedRowIndex
});
gObj.notify(events.virtualScrollEditCancel, args);
gObj.trigger(events.actionBegin, args, function (closeEditArgs) {
if (closeEditArgs.cancel) {
return;
}
closeEditArgs.type = events.actionComplete;
var rowObj = _this.parent.getRowObjectFromUID(_this.args.row.getAttribute('data-uid'));
_this.removeBatchElementChanges(rowObj, true);
_this.refreshRowIdx();
gObj.isEdit = false;
gObj.trigger(events.actionComplete, closeEditArgs);
});
};
/**
* In Cell edit mode, add creates a new row and immediately enters edit mode on first cell.
*
* @param {Object} [data] - optional default data for new record
* @param {number} [index] - optional index for new record
* @returns {void}
*/
CellEdit.prototype.addRecord = function (data, index) {
this.cellEditModule.addRecord(data, index);
};
/**
* In Cell edit mode, delete removes the row immediately from grid.
*
* @param {string} [fieldname] - optional field name for specific record
* @param {Object} [data] - optional data object to delete
* @returns {void}
*/
CellEdit.prototype.deleteRecord = function (fieldname, data) {
this.cellEditModule.deleteRecord(fieldname, data);
};
/**
* Handle delete complete event - cleanup after row deletion.
*
* @param {NotifyArgs} e - NotifyArgs event
* @returns {void}
*/
CellEdit.prototype.editComplete = function (e) {
this.cellEditModule.editComplete(e);
};
/**
* Destroy cell edit module.
*
* @returns {void}
* @hidden
*/
CellEdit.prototype.destroy = function () {
this.removeEventListener();
};
return CellEdit;
}(BatchEdit));
export { CellEdit };