ui-lib/lib/ui/grid/column.js

238 lines
6.8 KiB
JavaScript

import { global } from "../../utility";
// import { nullOrEmpty } from "../../utility/strings";
import { createElement } from "../../functions";
import { createIcon } from "../icon";
import { createCheckbox } from "../checkbox";
// import { setTooltip } from "../tooltip";
import { Dropdown } from "../dropdown";
export class GridColumn {
static create() {
return createElement('span');
}
static setValue(element, val) {
element.innerText = val;
}
static setStyle(element, style) {
for (let css of Object.entries(style)) {
element.style.setProperty(css[0], css[1]);
}
}
static setEnabled(element, enabled) {
const tooltip = element.querySelector('.ui-tooltip-wrapper');
if (tooltip != null) {
tooltip.style.display = enabled === false ? 'none' : '';
}
}
}
export class GridInputColumn extends GridColumn {
static get editing() { return true };
static createEdit(trigger, col, _parent, vals) {
const input = createElement('input');
input.setAttribute('type', 'text');
if (typeof trigger === 'function') {
input.addEventListener('change', trigger);
}
input.addEventListener('input', () => {
if (vals.__editing == null) {
vals.__editing = {
[col.key]: true
}
} else {
vals.__editing[col.key] = true;
}
});
return input;
}
static setValue(element, val) {
if (element.tagName !== 'INPUT') {
super.setValue(element, val);
} else {
element.value = val;
}
}
static getValue(e) { return e.target.value }
static setEnabled(element, enabled) {
super.setEnabled(element , enabled);
element.disabled = enabled === false;
}
}
export class GridTextColumn extends GridInputColumn {
static createEdit(trigger, col, _parent, vals) {
const input = createElement('textarea');
if (typeof trigger === 'function') {
input.addEventListener('change', trigger);
}
input.addEventListener('input', () => {
if (vals.__editing == null) {
vals.__editing = {
[col.key]: true
}
} else {
vals.__editing[col.key] = true;
}
});
return input;
}
static setValue(element, val, _item, _col, grid) {
if (element.tagName !== 'TEXTAREA') {
super.setValue(element, val);
} else {
element.value = val;
if (val != null) {
const lines = String(val).split('\n').length;
element.style.height = `${lines * grid.lineHeight + 12}px`;
}
// TODO: bad performance
}
}
}
const SymbolDropdown = Symbol.for('ui-dropdown');
export class GridDropdownColumn extends GridColumn {
static createEdit(trigger, col, parent) {
const drop = new Dropdown({ ...col.dropOptions, parent });
drop.onselected = trigger;
return drop.create();
}
static #getDrop(element) {
const dropGlobal = global[SymbolDropdown];
if (dropGlobal == null) {
return null;
}
const dropId = element.dataset.dropId;
const drop = dropGlobal[dropId];
if (drop == null) {
return null;
}
return drop;
}
static #getSource(item, col) {
let source = col.source;
if (typeof source === 'function') {
source = source(item);
}
return source;
}
static #setValue(source, element, val) {
const data = source?.find(v => v.value === val);
if (data != null) {
val = data.text;
}
super.setValue(element, val);
}
static setValue(element, val, item, col) {
if (element.tagName !== 'DIV') {
let source = this.#getSource(item, col);
if (source instanceof Promise) {
source.then(s => this.#setValue(s, element, val));
} else {
this.#setValue(source, element, val);
}
return;
}
const drop = this.#getDrop(element);
if (drop == null) {
return;
}
if (drop.source == null || drop.source.length === 0) {
let source = this.#getSource(item, col);
if (source instanceof Promise) {
source.then(s => {
drop.source = s;
drop.select(val, true);
})
return;
} else if (source != null) {
drop.source = source;
}
}
drop.select(val, true);
}
static getValue(e) {
return e.value;
}
static setEnabled(element, enabled) {
super.setEnabled(element , enabled);
const drop = this.#getDrop(element);
if (drop == null) {
return;
}
drop.disabled = enabled === false;
}
}
export class GridCheckboxColumn extends GridColumn {
static createEdit(trigger) {
const check = createCheckbox({
onchange: typeof trigger === 'function' ? trigger : null
});
return check;
}
static setValue(element, val) {
element.querySelector('input').checked = val;
}
static getValue(e) { return e.target.checked }
static setEnabled(element, enabled) {
super.setEnabled(element , enabled);
element.querySelector('input').disabled = enabled === false;
}
}
export class GridIconColumn extends GridColumn {
static create() { return createElement('span', 'col-icon') }
static setValue(element, val, item, col, grid) {
let className = col.className;
if (typeof className === 'function') {
className = className.call(col, item);
}
if (className == null) {
element.className = 'col-icon';
} else {
element.className = `col-icon ${className}`;
}
let type = col.iconType;
if (typeof type === 'function') {
type = type.call(col, item);
}
type ??= 'fa-regular';
if (element.dataset.type !== type || element.dataset.icon !== val) {
const icon = createIcon(type, val);
// const layer = element.children[0];
element.replaceChildren(icon);
// !nullOrEmpty(col.tooltip) && setTooltip(element, col.tooltip, false, grid.element);
element.dataset.type = type;
element.dataset.icon = val;
}
}
static setEnabled(element, enabled) {
super.setEnabled(element , enabled);
if (enabled === false) {
element.classList.add('disabled');
} else {
element.classList.remove('disabled');
}
}
}