UNPKG

@dewesoft-web/grid2

Version:

Dewesoft WebUI Grid

277 lines (224 loc) 7.39 kB
import { action, computed, observable } from "mobx"; import { ColumnModel } from "./ColumnModel"; import { RowModel } from "./RowModel"; import { GridType, Option, SelectOption } from "../types"; export enum CellEvent { ValueChanged, TypeChanged, EditStart, EditEnd, ReadOnlyChanged, } export class CellModel { @observable data : any; @observable temp : any; @observable editing : boolean; column : ColumnModel; columnProperty : string; row : RowModel; dirty : boolean; custom : any; @observable filter : string; @observable typeOverride : GridType; constructor(cell : any, column : ColumnModel | string, row? : RowModel) { this.column = column instanceof ColumnModel ? column : null; this.row = row ? row : null; this.dirty = false; this.editing = false; this.filter = ""; if (typeof cell === "object") { if (cell) { this.data = cell.value; this.temp = cell.value; this.typeOverride = cell.type; } else { this.data = null; this.temp = null; this.typeOverride = null; } } else { this.data = cell; this.temp = cell; } this.columnProperty = column ? (column as ColumnModel).property : (column as string); } @computed get color() { const type = typeof this.data; if (type === "string") { return this.data; } else if (type === "object") { return `rgba(${this.data.r}, ${this.data.g}, ${this.data.b}, ${this.data.a})`; } } @computed get isReadOnly() : boolean { if (this.typeOverride && this.typeOverride.readOnly !== undefined) { return this.typeOverride.readOnly; } return (this.column ? this.column.readOnly : false) || (this.row ? this.row.readOnly : false); } @computed get type() { if (!this.column) { return this.typeOverride; } return { ...this.column.type, ...this.typeOverride }; } parseValue(temp) { const cellType : any = this.type; if (cellType.kind.toLowerCase() === "number") { let data = parseFloat(temp); if (data !== 0 && !data) { data = this.data; } else { let max = (cellType.max === undefined || cellType.max === null) ? Infinity : cellType.max; let min = (cellType.min === undefined || cellType.min === null) ? -Infinity : cellType.min; if (data < min) { data = min; } else if (data > max) { data = max; } } temp = data; } return temp; } setValue(data : any) { data = this.parseValue(data); this.data = data; this.temp = data; this.row.onCellChanged(this, CellEvent.ValueChanged, { value: data }); } getValue() : any { const type : GridType = this.type; switch(type.kind.toLowerCase()) { case "toggle": return this.data ? type.options.on : type.options.off; case "button": return type.label; case "enum": if (this.data || this.data == 0) { for (const opt of type.options as Option[]) { const valueType = typeof opt; if (valueType === "string" && this.data == opt) { return opt; } else if (valueType === "object" && (opt as SelectOption).value === this.data) { return (opt as SelectOption).description; } } } return this.data; default: return this.data; } } @action setTypeOverride(type : any, noEvent? : boolean) { if (typeof type === "string") { this.typeOverride = { kind: type }; } else { this.typeOverride = type; } if (!noEvent) { } } stopEditing(force : boolean = false) { this.dirty = false; if (force || this.type.kind.toLowerCase() !== "color") { this.editing = false; } } startEditing() { this.temp = this.data; this.editing = true; } contains(filter : string) : boolean { const value = this.getValue(); const compare = ((value === undefined) || value == null) ? "" : value.toString() .toLowerCase(); //console.log(`${this.column.property} filter: ${filter} ? data: ${compare}, [${compare.includes(filter)}] type: ${this.type.kind}`); const matches = compare.includes(filter); if (matches) { this.filter = filter; } return matches; } serialize() { return { data: this.data || null, property: this.columnProperty, typeOverride: this.typeOverride }; } checkAndSet(data) { let kind; if (!this.column && this.typeOverride) { kind = this.typeOverride.kind; } else if (this.typeOverride){ kind = this.typeOverride.kind; } else if (this.column){ kind = this.column.type.kind; } if (kind === "enum") { const options : any = this.type.options; let valid = false; for (const opt of options) { if (typeof opt === "string" && opt === data) { valid = true; } else if (opt.value && opt.value === data) { valid = true; } } if (!valid) { console.warn(`Invalid value of '${data}' received for column ${this.columnProperty}[${this.row.index}]`); return; } } this.data = data; } handleEvent(event : CellEvent, args : any) { switch (event) { case CellEvent.ValueChanged: this.checkAndSet(args[0]); break; case CellEvent.TypeChanged: this.setTypeOverride(args[0]); break; case CellEvent.ReadOnlyChanged: if (this.typeOverride) { this.typeOverride.readOnly = args[0]; } else { this.typeOverride = { readOnly: args[0] } as GridType; } break; default: break; } } }