@dewesoft-web/grid2
Version:
Dewesoft WebUI Grid
277 lines (224 loc) • 7.39 kB
text/typescript
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 {
data : any;
temp : any;
editing : boolean;
column : ColumnModel;
columnProperty : string;
row : RowModel;
dirty : boolean;
custom : any;
filter : string;
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);
}
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})`;
}
}
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);
}
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;
}
}
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;
}
}
}