@dewesoft-web/grid2
Version:
Dewesoft WebUI Grid
289 lines (225 loc) • 7.28 kB
text/typescript
import { observable, action, computed } from "mobx";
import { CellModel } from "./CellModel";
import { ColumnModel } from "./ColumnModel";
import { EventEmitter } from "./EventEmitter";
import { CellEvent } from "./CellModel";
import { EventArguments } from "@dewesoft-web/ui/events";
import { Row, SortDirecton } from "../types";
export enum RowEvent {
IndexChanged,
VisibleChanged,
ReadOnlyChanged,
SelectedChanged,
CellValueChanged,
RowCellChanged,
CellChanged,
}
export interface RowCells {
[col : string] : CellModel;
}
export class RowModel extends EventEmitter<RowEvent> {
cells : RowCells;
selected : boolean;
first : boolean;
last : boolean;
readOnly : boolean;
scrollVisible : boolean;
searchVisible : boolean;
visible : boolean;
index : number;
displayIndex : number;
columns : ColumnModel[];
virtualize : boolean;
constructor(index : number, displayIndex : number, rowInfo : Row, columns : ColumnModel[], virtualize : boolean) {
super();
this.virtualize = virtualize;
this.index = index;
this.displayIndex = displayIndex;
this.cells = {};
for (const col of columns) {
this.cells[col.property] = new CellModel(rowInfo.data[col.property], col, this);
}
for (const prop of Object.keys(rowInfo.data)) {
if (!this.cells[prop]) {
this.cells[prop] = new CellModel(rowInfo.data[prop], prop, this);
}
}
this.columns = columns;
this.readOnly = rowInfo.readOnly === true;
this.selected = false;
this.first = false;
this.last = false;
this.scrollVisible = !virtualize;
this.searchVisible = true;
this.visible = rowInfo.visible !== false;
this.select = this.select.bind(this);
}
onInitialized() {
}
get isVisible() {
return this.scrollVisible && this.searchVisible && this.visible;
}
selectCustom(first : boolean, last : boolean) {
// this.selected = true;
this.setSelected(true);
this.first = first;
this.last = last;
}
select(noEvent? : boolean) {
// this.selected = true;
this.setSelected(true, noEvent);
this.first = true;
this.last = true;
}
deselect(noEvent? : boolean) {
// this.selected = false;
this.setSelected(false, noEvent);
this.first = false;
this.last = false;
}
setSelected(select : boolean, noEvent? : boolean) {
if (noEvent !== true && this.selected !== select) {
this.triggerEvent(RowEvent.SelectedChanged, {
selected: select
});
}
this.selected = select;
}
triggerSelected() {
this.triggerEvent(RowEvent.SelectedChanged, {
selected: this.selected
});
}
edit(col : ColumnModel) : CellModel {
// const cell = this.cells.find((cell) => cell.column === col);
const cell = this.cells[col.property];
if (cell) {
cell.startEditing();
}
return cell;
}
setValue(value : any, col : ColumnModel) {
// const cell = this.cells.find((cell) => cell.column === col);
const cell = this.cells[col.property];
if (cell) {
cell.setValue(value);
}
}
resetFilter() {
this.searchVisible = true;
for (const col of this.columns) {
this.cells[col.property].filter = "";
}
}
contains(filter : string) : boolean {
if (filter === "") {
this.resetFilter();
return true;
}
this.searchVisible = false;
// console.group(`Row ${this.index}`);
for (const col of this.columns) {
if (this.cells[col.property].contains(filter)) {
this.searchVisible = true;
}
}
// console.groupEnd();
return this.searchVisible;
}
compare(ascending : boolean, column : string, other : RowModel) {
if (this.cells[column].data < other.cells[column].data) {
return ascending ? -1 : 1;
}
else if (this.cells[column].data > other.cells[column].data) {
return ascending ? 1 : -1;
}
return 0;
}
serialize() {
const keys = Object.keys(this.cells);
const numKeys = keys.length;
const cells = new Array(numKeys);
for (let i = 0; i < numKeys; i++) {
cells[i] = this.cells[keys[i]].serialize();
}
return {
cells: cells,
selected: this.selected,
readOnly: this.readOnly,
visible: this.isVisible,
index: this.index
};
}
onCellChanged(cell : CellModel, event : CellEvent, args : EventArguments) {
// console.log(`RowData[${this.index}]{${cell.column.property}} ${CellEvent[event]} => ${JSON.stringify(args)}`);
this.triggerEvent(RowEvent.CellChanged, {
column: cell.column.property,
cellEvent: event,
args: args
});
}
addColumnData() {
for (const col of this.columns) {
if (!this.cells[col.property]) {
this.cells[col.property] = new CellModel(null, col, this);
}
}
}
removeColumnData(columnProp : string) {
this.cells[columnProp] = undefined;
}
private cppCellChanged(col : string, cellEvent : CellEvent, args) {
if (this.cells[col]) {
this.cells[col].handleEvent(cellEvent, args);
}
else {
console.warn("No such row cell: " + col);
}
}
handleEvent(event : RowEvent, args : any[]) {
switch (event) {
case RowEvent.IndexChanged:
break;
case RowEvent.VisibleChanged:
this.visible = args[0];
break;
case RowEvent.SelectedChanged:
if (args[0]) {
this.select(true);
}
else {
this.deselect(false);
}
break;
case RowEvent.CellValueChanged:
break;
case RowEvent.RowCellChanged:
break;
case RowEvent.CellChanged: {
const [col, cellEvent, cellArgs] = args;
this.cppCellChanged(col, cellEvent, cellArgs);
}
break;
case RowEvent.ReadOnlyChanged:
this.readOnly = args[0];
break;
default:
break;
}
}
}