@dewesoft-web/grid
Version:
Dewesoft WebUI Grid
254 lines (199 loc) • 6.25 kB
text/typescript
import { observable, action, computed } from "mobx";
import * as uuid from "uuid";
import { CellEvent, GridCellModel } from "./GridCellModel";
import { EventArguments } from "@dewesoft-web/ui/events";
import { EventEmitter, EventHandler } from "./EventEmitter";
export interface GridRowData {
[key : string] : GridCellModel;
}
export enum RowEvent {
IndexChanged,
VisibleChanged,
ReadOnlyChanged,
SelectedChanged,
CellValueChanged,
RowCellChanged,
CellChanged,
}
export class GridRowModel extends EventEmitter<RowEvent> {
visible : boolean;
selected : boolean;
first : boolean;
last : boolean;
readOnly : boolean;
private searchVisible : boolean;
data : GridRowData;
readonly uniqueId : string;
private index : number;
private columns : string[];
constructor(row : any, cols : string[], uniqueId? : string | EventHandler<RowEvent>, eventHandler? : EventHandler<RowEvent>) {
super();
this.selected = false;
this.visible = true;
this.searchVisible = true;
this.readOnly = false;
this.first = false;
this.last = false;
this.columns = cols;
this.data = {};
this.onEvent = this.onEvent.bind(this);
this.onCellChanged = this.onCellChanged.bind(this);
const type = typeof uniqueId;
if (type !== "function") {
if (uniqueId) {
this.uniqueId = uniqueId as string;
if (eventHandler) {
this.addEventHandler(eventHandler);
}
}
else {
this.uniqueId = uuid.v4();
}
}
else {
this.uniqueId = uuid.v4();
this.addEventHandler(uniqueId as EventHandler<RowEvent>);
}
this.data = {...row};
for (const col of cols) {
this.data[col] = new GridCellModel(row[col], col, this.onCellChanged);
}
}
get isVisible() {
return this.visible && this.searchVisible;
}
hideNotMatching(query : string) : boolean {
const normalizedQuery = query.toUpperCase();
for (const col of this.columns) {
const data = (this.data[col].value + "").toUpperCase();
if (data.includes(normalizedQuery)) {
this.searchVisible = true;
return;
}
}
this.searchVisible = false;
}
setVisible(visible : boolean) {
this.visible = visible;
}
forceVisible() {
this.visible = true;
this.searchVisible = true;
}
setIndex(index : number) {
this.index = index;
this.triggerEvent(RowEvent.IndexChanged, {
index: index
});
}
setReadOnly(readOnly : boolean) {
this.readOnly = readOnly;
this.triggerEvent(RowEvent.ReadOnlyChanged, {
readOnly: readOnly
});
}
setSelected(selected : boolean) {
if (this.selected === selected) {
return;
}
this.selected = selected;
this.triggerEvent(RowEvent.SelectedChanged, {
selected: selected
});
}
getValue(col : string) {
return this.data[col] ? this.data[col].value : undefined;
}
getIndex() {
return this.index;
}
setValue(col : string, value : any, noEvent? : boolean) {
if (this.readOnly) {
return;
}
if (!this.data[col]) {
throw new Error(`Column with name '${col}' does not exist.`);
}
if (this.data[col].type && this.data[col].type.readOnly) {
// console.log(`row: ${this.uniqueId} col: ${col} ReadOnly`);
return;
}
// console.log(`row: ${this.uniqueId} col: ${col} SetValue: ${value}`);
this.data[col].setValue(value, noEvent);
}
setEditing(editing : boolean, column? : string) {
if (editing) {
this.data[column].setEditing(true);
}
else if (column) {
this.data[column].setEditing(false);
}
else {
for (const key in this.data) {
if (this.data.hasOwnProperty(key) && this.data[key] && this.data[key].setEditing) {
this.data[key].setEditing(false);
}
}
}
}
select() {
this.setSelected(true);
//
this.first = true;
this.last = true;
}
deselect() {
this.setSelected(false);
this.first = false;
this.last = false;
for (const key in this.data) {
if (this.data.hasOwnProperty(key) &&
this.data[key] &&
this.data[key].setEditing
) {
this.data[key].setEditing(false);
}
}
}
onCellChanged(cell : GridCellModel, event : CellEvent, args : EventArguments) {
this.triggerEvent(RowEvent.CellChanged, {
event: event,
column: cell.getColumn(),
args: args
});
}
/*
* C++ event handlers
*/
onEvent(event : RowEvent, ...args : any[]) {
switch (event) {
case RowEvent.VisibleChanged:
this.visible = args[1];
break;
case RowEvent.ReadOnlyChanged:
this.readOnly = args[1];
break;
case RowEvent.CellValueChanged:
this.setValue(args[1], args[2], true);
break;
case RowEvent.CellChanged:
const [eventCell, column, cellEvent, cellArgs] = args;
this.data[column].onEvent(cellEvent, ...cellArgs);
break;
}
}
}