@dewesoft-web/grid2
Version:
Dewesoft WebUI Grid
1,301 lines (1,017 loc) • 36.5 kB
text/typescript
import { action, computed, observable } from "mobx";
import * as CssSelectorGenerator from "css-selector-generator";
import * as groupBy from "lodash.groupby";
import { GroupModel } from "./GroupModel";
import { ColumnEvent, ColumnModel } from "./ColumnModel";
import { RowEvent, RowModel } from "./RowModel";
import { GroupEvent } from "./GroupModel";
import { CellModel } from "./CellModel";
import { ControlModel } from "@dewesoft-web/ui/controls";
import { DSMessage, WebControl, EventArguments, ds } from "@dewesoft-web/ui/events";
import { Column, RowData, Row, SortDirecton } from "../types";
import { CommonEvent } from "../../ui/events/webEvent";
import { BufferedEvent } from "../../ui/events/ds";
import { GridProps } from "../FlexGrid";
export enum GridEvent {
Initializing,
ColumnChanged,
GroupsChanged,
GroupChanged,
RowChanged,
SelectedColumnChanged,
ShowGroupsChanged,
RowOrderChanged,
GroupByChanged,
UnselectRows,
SelectRows,
SelectRow,
RemoveRow,
AddColumn,
AddRow,
Clear,
AddGroup,
RemoveGroup,
AddRows,
SelectedRowsChanged,
InsertRow,
SortRows,
UnsortRows,
SortedColumnChanged,
RemoveColumn,
FilterChanged
}
const ENTER = 13;
const ESC = 27;
export class GridModel extends ControlModel<GridEvent> {
element : HTMLDivElement;
private rows : RowModel[];
groups : GroupModel[];
columns : ColumnModel[];
scrollTop : number;
clientHeight: number;
scrollHeight : number;
scrollWidth : number;
rowHeight: number;
groupByColumn : string;
filter : string;
sortDirection : SortDirecton;
sortedColumn : string;
groupRows : boolean;
unvirtualizedHeight : number;
private isBatch : boolean;
readonly virtualize : boolean;
private selectedColumn : ColumnModel;
private selectedColumnIndex : number;
private selectedRows : RowModel[];
private editingCell : CellModel;
private selectionStart : number;
private selectionEnd : number;
private isSelecting : boolean;
private prevScrollTop : number;
private prevClientHeight : number;
readonly selector : string;
private readonly groupTitleHeight : number = 25;
private readonly headersHeight : number = 42;
constructor(name : string, options : GridProps, rows? : RowData[], cols? : Column[]) {
super(WebControl.Grid, name, options);
this.isBatch = false;
this.rowHeight = parseInt(options.RowHeight) || 25;
this.virtualize = true;
if (options.Virtualize !== undefined && (options.Virtualize as any) !== true) {
const type = typeof options.Virtualize;
if (type === "boolean") {
this.virtualize = options.Virtualize as any as boolean;
}
else if (typeof options.Virtualize === "string") {
this.virtualize = options.Virtualize !== "False";
}
}
if (!cols) {
this.columns = [];
}
else {
const len = cols.length;
this.columns = new Array(len);
let hasGroupName = false;
for (let i = 0; i < len; i++) {
this.columns[i] = new ColumnModel(cols[i], this);
this.columns[i].order = i;
if (!hasGroupName && this.columns[i].property === "GroupName") {
hasGroupName = true;
}
}
if (!hasGroupName) {
let groupColumn = new ColumnModel({
Title: "Group name",
Property: "GroupName",
Visible: false,
ReadOnly: true,
Type: "String",
Description: "Group name"
}, this);
groupColumn.order = this.columns.length;
this.columns.push(groupColumn);
}
}
if (!rows) {
this.rows = [];
}
else {
const len = rows.length;
this.rows = new Array(len);
for (let i = 0; i < len; i++) {
this.rows[i] = new RowModel(
i,
i,
{
readOnly: false,
data: rows[i],
visible: true
},
this.columns,
this.virtualize
);
}
}
this.groupRows = true;
this.sortDirection = SortDirecton.None;
this.groupByColumn = "GroupName";
// console.log("done generating");
this.selectedRows = [];
this.selectionStart = -1;
this.selectionEnd = -1;
this.isSelecting = false;
this.prevScrollTop = 0;
this.prevClientHeight = 0;
this.onGroupEvent = this.onGroupEvent.bind(this);
this.onRowEvent = this.onRowEvent.bind(this);
this.onEvent = this.onEvent.bind(this);
this.rows.forEach(row => row.addEventHandler(this.onRowEvent));
const groups = groupBy(this.rows, (r) => {
return r.cells["GroupName"].data;
});
let index = 0;
this.groups = [];
// noinspection TsLint
for (const group in groups) {
// noinspection JSUnfilteredForInLoop
this.groups.push(new GroupModel(
group, index++, groups[group], this.onGroupEvent
));
}
this.updateDisplayIndex();
if (!this.virtualize) {
this.unvirtualizedHeight = this.getUnvirtualizedHeight();
}
// this.setScrollPosition(0, 500);
}
onInitialized() {
// console.log(JSON.stringify(initArgs));
this.triggerEvent(GridEvent.Initializing, {
rows: this.rows.map(r => r.serialize()),
columns: this.columns.map(c => c.serialize()),
groups: this.groups.map(g => g.serialize()),
groupByColumn: "GroupName"
});
}
setElement(el) {
(this as any).selector = new CssSelectorGenerator().getSelector(el);
this.element = el;
const height = this.getElementHeight(el, true);
this.clientHeight = height;
// this.element.style.height = height + "px";
this.setScrollPosition(0, height);
// this.setScrollPosition(0, el.clientHeight || 500);
}
getElementHeight(el : HTMLElement, parentHeightOnly : boolean = false) : number {
let size = 500;
if (!parentHeightOnly && el.clientHeight) {
size = el.clientHeight;
}
else {
size = this.getParentHeight(el.parentElement);
if (size <= 0) {
size = 500;
}
size -= this.element.offsetTop;
}
return size;
}
getParentHeight(el : HTMLElement) : number {
let size = -1;
if (el.parentElement) {
size = el.parentElement.clientHeight;
if (size === 0) {
size = this.getParentHeight(el.parentElement);
}
}
return size;
}
getIsBatch() : boolean {
return this.isBatch;
}
getRowCount() : number {
return this.rows.length;
}
setFilter(filter : string, event : boolean = true) {
this.filter = filter.toLowerCase();
if (event) {
this.triggerEvent(GridEvent.FilterChanged, {
filter: filter
});
}
// console.group("filter");
for (const row of this.rows) {
row.contains(this.filter);
}
// console.groupEnd();
}
addColumn(column : Column, emitEvent : boolean) {
const gridColumn = new ColumnModel(column, this);
if (!gridColumn.order && gridColumn.order !== 0) {
gridColumn.order = this.columns.length - 1;
}
this.columns.push(gridColumn);
for (const row of this.rows) {
row.addColumnData();
}
if (emitEvent) {
this.triggerEvent(GridEvent.AddColumn, column);
}
}
removeColumn(columnProperty : string, emitEvent : boolean) {
const columnIndex = this.columns.findIndex(c => c.property === columnProperty);
if (columnIndex !== -1) {
this.columns.splice(columnIndex, 1);
for (const row of this.rows) {
row.removeColumnData(columnProperty);
}
}
}
private onGroupEvent(control : GroupModel, event : GroupEvent, args : EventArguments, onSuccess? : Function, onFailure? : Function) {
switch (event) {
case GroupEvent.ExpandedChanged:
this.setScrollPosition(this.prevScrollTop, this.prevClientHeight);
break;
default:
break;
}
this.triggerEvent(GridEvent.GroupsChanged, {
groupEvent: event,
group: control.name,
arguments: args
});
}
private onRowEvent(control : RowModel, event : RowEvent, args : EventArguments, onSuccess? : Function, onFailure? : Function) {
// console.log(`RowData[${control.index}] ${RowEvent[event]} => ${JSON.stringify(args)}`);
this.triggerEvent(GridEvent.RowChanged, {
rowEvent: event,
index: control.index,
arguments: args
});
}
get orderedColumns() {
return this.columns.sort(function(lhs, rhs) {
return lhs.order - rhs.order;
});
}
toggleGroups() {
this.showGroups(!this.groupRows);
}
showGroups(visible : boolean, noEvent : boolean = false) {
for (const group of this.groups) {
group.setTitleVisibility(visible);
}
this.groupRows = visible;
if (!noEvent) {
this.triggerEvent(GridEvent.ShowGroupsChanged, {
visible: visible
});
}
}
sort(column : string, event : boolean = true) {
if (column !== this.sortedColumn) {
this.sortedColumn = column;
this.sortDirection = SortDirecton.Ascending;
}
else {
if (this.sortDirection === SortDirecton.None) {
this.sortDirection = SortDirecton.Ascending;
}
else if (this.sortDirection === SortDirecton.Ascending) {
this.sortDirection = SortDirecton.Descending;
}
else {
this.sortDirection = SortDirecton.Ascending;
}
}
for (const group of this.groups) {
group.sort(this.sortDirection === SortDirecton.Ascending, this.sortedColumn);
}
this.updateDisplayIndex();
if (event) {
this.triggerEvent(GridEvent.SortRows, {
direction: this.sortDirection
});
}
}
unsort(event : boolean = true) {
if (this.sortDirection === SortDirecton.None) {
return;
}
this.sortDirection = SortDirecton.None;
for (const group of this.groups) {
group.unsort();
}
this.updateDisplayIndex();
if (event) {
this.triggerEvent(GridEvent.UnsortRows);
}
}
selectColumn(col : ColumnModel) {
if (this.selectedColumn) {
this.selectedColumn.selected = false;
}
this.selectedColumn = col;
this.selectedColumn.selected = true;
this.selectedColumnIndex = this.columns.indexOf(this.selectedColumn);
}
startSelectRow(row : RowModel, col : ColumnModel) {
if (!this.editingCell) {
this.editingCell = row.edit(col);
}
if (this.editingCell.dirty) {
this.setValueForSelected(this.editingCell.temp);
}
this.isSelecting = true;
this.selectColumn(col);
this.unselectRows(row.displayIndex);
this.selectedRows = [row];
this.selectionStart = row.displayIndex; // this.rows.indexOf(row);
this.selectionEnd = row.displayIndex; // this.rows.indexOf(row);
row.select();
}
stopSelecting() {
this.isSelecting = false;
}
onTrySelect(row : RowModel) {
if (!this.isSelecting || this.selectedColumn.readOnly || !this.selectedColumn.groupSelect) {
return;
}
ds.ignoreOutboundEvents(true);
const numRows = this.rows.length;
const selected = new Array(numRows);
for (let i = 0; i < numRows; i++) {
selected[i] = this.rows[i].selected;
}
// console.log("onTrySelect");
this.selectionEnd = row.displayIndex; // this.rows.indexOf(row);
if (this.selectedRows.length) {
this.unselectRows(this.selectionEnd);
}
this.selectRows(this.selectionStart, this.selectionEnd);
if (this.selectedRows.length) {
this.selectedRows[0].first = true;
this.selectedRows[this.selectedRows.length - 1].last = true;
}
ds.ignoreOutboundEvents(false);
for (let i = 0; i < numRows; i++) {
if (this.rows[i].selected !== selected[i]) {
this.rows[i].triggerSelected();
}
}
ds.ignoreOutboundEvents(false);
for (let i = 0; i < numRows; i++) {
if (this.rows[i].selected !== selected[i]) {
this.rows[i].triggerSelected();
}
}
}
selectRows(startIndex : number, endIndex : number) {
this.selectedRows = [];
if (endIndex < startIndex) {
let temp = endIndex;
endIndex = startIndex;
startIndex = temp;
}
const numGroups = this.groups.length;
for (let index = 0; index < numGroups; index++) {
const group = this.groups[index];
const groupRows = group.rows.length;
for (let rowIndex = 0; rowIndex < groupRows; rowIndex++) {
const row = group.rows[rowIndex];
const select = (row.displayIndex >= startIndex) && (row.displayIndex <= endIndex);
if (select) {
row.setSelected(select);
row.first = false;
row.last = false;
this.selectedRows.push(row);
}
else {
row.deselect();
}
}
}
}
onRowSelect(row : RowModel, col : ColumnModel, selectToRow? : boolean) {
if (col !== this.selectedColumn || col.readOnly) {
return;
}
if (row.selected) {
if (this.selectedRows.length === 1) {
return;
}
const index = this.selectedRows.indexOf(row);
if (index !== -1) {
this.selectedRows.splice(index, 1);
row.deselect();
}
}
else if (selectToRow) {
const index = row.displayIndex; // this.rows.indexOf(row);
this.selectRows(this.selectionStart, index);
if (this.selectedRows.length) {
this.selectedRows[0].first = true;
this.selectedRows[this.selectedRows.length - 1].last = true;
}
}
else {
this.selectedRows.push(row);
row.select();
}
}
unselectRows(index : number) {
this.cancelEdit();
for (const row of this.selectedRows) {
if (row.displayIndex !== index) {
row.deselect();
}
}
}
selectAllRows(column : ColumnModel) {
this.cancelEdit();
this.selectColumn(column);
if (!this.rows || this.rows.length === 0 || !column.groupSelect) {
return;
}
const length = this.rows.length;
for (let i = 0; i < length; i++) {
this.rows[i].selectCustom(i === 0, i === length - 1);
}
this.selectedRows = this.rows;
}
setScrollPosition(scrollTop : number, clientHeight : number) {
// console.group(`scroll / resize (${this.name}), clientHeight: ${clientHeight}`);
// console.log(`PREV: top: ${this.scrollTop}, height: ${this.scrollHeight}`);
if (!this.virtualize) {
return;
}
this.clientHeight = clientHeight;
this.scrollTop = scrollTop + 24;
let rowPos = 30;
let rowIdx = 0;
for (const group of this.groups) {
if (!group.expanded && group.showTitle) {
continue;
}
else if (group.showTitle) {
rowPos += this.groupTitleHeight;
}
for (const row of group.rows) {
row.scrollVisible = (rowPos > scrollTop) && (rowPos < scrollTop + clientHeight);
rowIdx++;
rowPos += this.rowHeight;
}
}
this.scrollHeight = rowPos + (30 + this.groups.length * 30);
this.prevScrollTop = scrollTop;
this.prevClientHeight = clientHeight;
// console.log(`POST: top: ${this.scrollTop}, height: ${this.scrollHeight}`);
// console.groupEnd();
}
selectPreviousRow() {
if (this.selectedRows.length === 0) {
return;
}
if (this.selectionStart > 0) {
this.cancelEdit();
this.selectionStart--;
this.selectionEnd = this.selectionStart;
this.unselectRows(this.selectionStart);
// const row = this.rows[this.selectionStart];
const row = this.rows.find(r => r.displayIndex === this.selectionStart);
if (row) {
this.selectedRows = [row];
row.select();
// if (this.element) {
// this.element.scrollTop = (row.index * 25) - 30;
// }
}
}
}
selectNextRow() {
if (this.selectedRows.length === 0) {
return;
}
if (this.selectionStart < this.rows.length - 1) {
this.cancelEdit();
this.selectionStart++;
this.selectionEnd = this.selectionStart;
this.unselectRows(this.selectionStart);
let row : RowModel;
const numRows = this.rows.length;
for (let i = 0; i < numRows; i++) {
if (this.rows[i].displayIndex === this.selectionStart) {
row = this.rows[i];
break;
}
}
if (row) {
this.selectedRows = [row];
row.select();
}
}
}
selectFirstRow() {
this.cancelEdit();
this.selectionStart = 0;
this.selectionEnd = 0;
if (this.selectedRows.length) {
this.unselectRows(0);
}
this.selectRows(this.selectionStart, this.selectionEnd);
if (this.selector && window.document) {
const el : Element = document.querySelector(this.selector);
el.scrollTop = 0;
}
this.selectedRows[0].last = true;
}
selectLastRow() {
this.cancelEdit();
this.selectionStart = this.rows.length - 1;
this.selectionEnd = this.rows.length - 1;
if (this.selectedRows.length) {
this.unselectRows(this.selectionStart);
}
this.selectRows(this.selectionStart, this.selectionEnd);
if (this.selector && window.document) {
const el : Element = document.querySelector(this.selector);
el.scrollTop = el.scrollHeight + (3 * 25);
}
this.selectedRows[0].first = true;
}
selectNextColumn() {
if (!this.selectedColumn || this.selectedColumnIndex >= this.columns.length) {
return;
}
this.cancelEdit();
let selectedIndex = this.selectedColumnIndex + 1;
while (selectedIndex < this.columns.length && !this.columns[selectedIndex].visible) {
selectedIndex++;
}
const col = this.columns[selectedIndex];
if (col) {
this.selectedColumn.selected = false;
this.selectedColumn = col;
this.selectedColumn.selected = true;
this.selectedColumnIndex = selectedIndex;
}
}
selectPreviousColumn() {
if (!this.selectedColumn || this.selectedColumnIndex <= 0) {
return;
}
this.cancelEdit();
let selectedIndex = this.selectedColumnIndex - 1;
while (selectedIndex >= 0 && !this.columns[selectedIndex].visible) {
selectedIndex--;
}
const col = this.columns[selectedIndex];
if (col) {
this.selectedColumn.selected = false;
this.selectedColumn = col;
this.selectedColumn.selected = true;
this.selectedColumnIndex = selectedIndex;
}
}
cancelEdit() {
if (this.editingCell) {
this.editingCell.stopEditing();
}
}
onEditCell(row : RowModel, col : ColumnModel) {
this.cancelEdit();
this.editingCell = row.edit(col);
}
onStartEdit(cell : CellModel) {
this.cancelEdit();
this.editingCell = cell;
this.editingCell.startEditing();
}
setValueForSelected(value : any) : void {
if (!this.editingCell) {
return;
}
else if (this.editingCell.isReadOnly) {
return;
}
for (const row of this.selectedRows) {
row.setValue(value, this.selectedColumn);
}
this.editingCell.stopEditing();
}
setGroupBy(order : any) {
const col = this.columns.find(function(column) {
return column.order === order;
});
if (col) {
}
}
addGroup(group : GroupModel, noEvent : boolean = false) {
group.setTitleVisibility(this.groupRows);
this.groups.push(group);
if (!noEvent) {
this.triggerEvent(GridEvent.AddGroup, {
group: group.serialize()
});
}
}
removeGroup(group : GroupModel) {
const index = this.groups.indexOf(group);
if (index !== -1) {
this.groups.splice(index, 1);
this.triggerEvent(GridEvent.RemoveGroup, {
groupName: group.name
});
}
}
private updateRowOrder() {
if (this.sortDirection !== SortDirecton.None) {
if (this.sortDirection === SortDirecton.Ascending) {
this.sortDirection = SortDirecton.Descending;
}
else if (this.sortDirection === SortDirecton.Descending) {
this.sortDirection = SortDirecton.Ascending;
}
this.sort(this.sortedColumn, true);
}
else {
this.updateDisplayIndex();
}
}
private updateDisplayIndex() {
let index = 0;
for (const group of this.groups) {
for (let row of group.rows) {
row.displayIndex = index++;
}
}
}
insertRow(row : Row, index : number, noEvent? : boolean, noRefresh? : boolean) : RowModel {
let groupToAdd : GroupModel = null;
for (const group of this.groups) {
if (group.name === row.data.GroupName) {
groupToAdd = group;
}
}
if (!groupToAdd) {
groupToAdd = new GroupModel(row.data.GroupName as string, this.groups.length, [], this.onGroupEvent);
this.addGroup(groupToAdd, noEvent);
}
const rowModel = new RowModel(this.rows.length, 0, row, this.columns, this.virtualize);
rowModel.addEventHandler(this.onRowEvent);
this.rows.splice(index, 0, rowModel);
groupToAdd.rows.push(rowModel);
// this.updateIndices();
if (!this.isBatch) {
this.updateRowOrder();
}
if (!noRefresh && !this.isBatch) {
this.refresh();
}
if (!noEvent) {
this.triggerEvent(GridEvent.AddRow, {
row: rowModel.serialize()
});
}
if (!this.virtualize) {
this.unvirtualizedHeight = this.getUnvirtualizedHeight();
}
return rowModel;
}
insertRowToGroup(row : Row, groupIndex : number, noEvent? : boolean, noRefresh? : boolean) : RowModel {
let groupToAdd : GroupModel = null;
for (const group of this.groups) {
if (group.name === row.data.GroupName) {
groupToAdd = group;
}
}
if (!groupToAdd) {
groupToAdd = new GroupModel(row.data.GroupName as string, this.groups.length, [], this.onGroupEvent);
this.addGroup(groupToAdd, noEvent);
}
const rowModel = new RowModel(this.rows.length, 0, row, this.columns, this.virtualize);
rowModel.addEventHandler(this.onRowEvent);
this.rows.push(rowModel);
groupToAdd.insertRow(groupIndex, rowModel);
// this.updateIndices();
if (!this.isBatch) {
this.updateRowOrder();
}
if (!noRefresh && !this.isBatch) {
this.setScrollPosition(this.prevScrollTop, this.prevClientHeight);
}
if (!noEvent) {
this.triggerEvent(GridEvent.AddRow, {
row: rowModel.serialize()
});
}
if (!this.virtualize) {
this.unvirtualizedHeight = this.getUnvirtualizedHeight();
}
return rowModel;
}
getUnvirtualizedHeight() : number {
let height = (this.rowHeight * this.rows.length) + this.headersHeight;
let numShownGroups = 0;
for (const group of this.groups) {
if (group.showTitle) {
height += this.groupTitleHeight;
numShownGroups++;
}
}
return height;
}
addRow(row : Row, noEvent : boolean = false, noRefresh : boolean = false, lastRowToAdd : boolean = true) : RowModel {
let groupToAdd : GroupModel = null;
for (const group of this.groups) {
if (group.name === row.data.GroupName) {
groupToAdd = group;
}
}
if (!groupToAdd) {
groupToAdd = new GroupModel(row.data.GroupName as string, this.groups.length, [], this.onGroupEvent);
this.addGroup(groupToAdd, noEvent);
}
const rowModel = new RowModel(this.rows.length, 0, row, this.columns, this.virtualize);
rowModel.addEventHandler(this.onRowEvent);
this.rows.push(rowModel);
groupToAdd.rows.push(rowModel);
if (lastRowToAdd && !this.isBatch) {
this.updateRowOrder();
}
if (!noRefresh && !this.isBatch) {
this.setScrollPosition(this.prevScrollTop, this.prevClientHeight);
}
if (!noEvent) {
this.triggerEvent(GridEvent.AddRow, {
row: rowModel.serialize()
});
}
if (!this.virtualize) {
this.unvirtualizedHeight = this.getUnvirtualizedHeight();
}
return rowModel;
}
addRows(rows : Row[]) : void {
const newRows = [];
let isLastRow = false;
for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
isLastRow = rowIndex === rows.length - 1;
newRows.push(this.addRow(rows[rowIndex], true, true, isLastRow));
}
this.refresh();
// this.triggerEvent(GridEvent.AddRows, {
// rows: newRows.map(r => r.serialize())
// });
}
removeRow(index : number, noEvent? : boolean) : void {
const row = this.rows[index];
if (!row) {
return;
}
let targetGroup = this.groups.find(g => g.name === row.cells["GroupName"].data);
if (!targetGroup) {
return;
}
targetGroup.removeRow(row);
this.rows.splice(index, 1);
if (targetGroup.rows.length === 0) {
this.removeGroup(targetGroup);
}
if (!this.isBatch) {
this.updateIndices();
this.updateRowOrder();
}
if (!noEvent) {
this.triggerEvent(GridEvent.RemoveRow, {
removedIds: [{
index: index
}]
});
}
this.refresh();
}
private updateIndices() : void {
const rowsLength = this.rows.length;
for (let i = 0; i < rowsLength; i++) {
this.rows[i].index = i;
}
}
refresh() : void {
this.setScrollPosition(this.prevScrollTop, this.prevClientHeight);
}
onKeyPressed(e) {
switch (e.keyCode) {
case ESC:
case ENTER:
if (this.editingCell && this.editingCell.type.kind.toLowerCase() === "color") {
this.editingCell.stopEditing(true);
}
break;
default:
break;
}
}
clear() : void {
this.selectedRows = [];
this.rows = [];
this.groups = [];
this.editingCell = null;
this.setScrollPosition(0, this.prevClientHeight);
}
private onGroupsChanged(name : string, event : GroupEvent, args : any[]) : void {
const group = this.groups.find(g => g.name === name);
if (group) {
group.handleEvent(event, args);
}
else {
// console.warn(`No group with name ${name} found`);
}
}
private onRowChanged(rowIndex : number, rowEvent : RowEvent, rowArgs : any[]) : void {
if (rowIndex < 0 || rowIndex > this.rows.length) {
console.warn(`No row with index ${rowIndex} found`);
return;
}
else {
const row = this.rows[rowIndex];
if (row !== undefined && row.handleEvent) {
row.handleEvent(rowEvent, rowArgs);
}
}
}
private onColumnChanged(property : string, colEvent : ColumnEvent, colArgs : any[]) : void {
// console.log(`ColChanged[${ColumnEvent[colEvent]} colArgs: ${JSON.stringify(colArgs)}`);
const col = this.columns.find(c => c.property === property);
if (col) {
col.handleEvent(colEvent, colArgs);
}
else {
console.warn(`No column with property ${col.property} found!`);
}
}
protected setOptions(options : any) {
}
private beginUpdate() {
this.isBatch = true;
}
private endUpdate() {
this.isBatch = false;
}
private batchUpdate(args : any[]) {
this.beginUpdate();
// console.log("Batch received: " + new Date());
for (const event of args as BufferedEvent[]) {
this.onEvent(event.eventId, this.name, ...event.arguments);
}
this.updateIndices();
this.updateRowOrder();
this.refresh();
// console.log("Batch processed: " + new Date());
this.endUpdate();
}
protected onEvent(event : GridEvent, name : string, ...args : any[]) : void {
if (this.name !== name) {
return;
}
// const eventName = event < 0 ? CommonEvent[event] : GridEvent[event];
// console.log(`GridEvent<${name}, ${eventName}|${event}>: ${JSON.stringify(args)}`);
switch (event) {
case CommonEvent.Batch as number:
this.batchUpdate(args);
break;
case GridEvent.ColumnChanged:
const [colProperty, colEvent, colArgs] = args;
this.onColumnChanged(colProperty, colEvent, colArgs);
break;
case GridEvent.GroupsChanged:
const [groupName, groupEvent, groupArgs] = args;
this.onGroupsChanged(groupName, groupEvent, groupArgs);
break;
case GridEvent.RowChanged:
const [rowIndex, rowEvent, rowArgs] = args;
this.onRowChanged(rowIndex, rowEvent, rowArgs);
break;
case GridEvent.AddColumn:
this.addColumn(args[0], false);
break;
case GridEvent.RemoveColumn:
this.removeColumn(args[0], false);
break;
case GridEvent.SelectedColumnChanged:
break;
case GridEvent.ShowGroupsChanged:
this.showGroups(args[0], true);
break;
case GridEvent.RowOrderChanged:
break;
case GridEvent.GroupByChanged:
break;
case GridEvent.SortRows:
this.sort(args[0], false);
break;
case GridEvent.UnsortRows:
this.unsort(false);
break;
case GridEvent.UnselectRows:
this.unselectRows(-1);
this.selectedRows = [];
break;
case GridEvent.SelectRows:
break;
case GridEvent.SelectRow:
break;
case GridEvent.RemoveRow: {
const [index] = args;
this.removeRow(index, true);
}
break;
case GridEvent.SortedColumnChanged:
this.sortedColumn = args[0];
break;
case GridEvent.AddRow: {
let [index, row] = args;
if (row.GroupName || row.GroupName === "") {
row = {
data: row
};
}
if (index !== -1) {
this.insertRow(row, index, true, false);
}
else {
this.addRow(row, true, false, true);
}
}
break;
case GridEvent.AddGroup:
this.addGroup(new GroupModel(args[0], this.groups.length, [], this.onGroupEvent), true);
break;
case GridEvent.Clear:
this.clear();
break;
case GridEvent.FilterChanged:
this.setFilter(args[0], false);
break;
default:
super.onEvent(event, name, ...args);
break;
}
}
}