362 lines
11 KiB
JavaScript
362 lines
11 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";
|
|
import { convertCssStyle } from "../extension";
|
|
|
|
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]);
|
|
// }
|
|
element.style.cssText = convertCssStyle(style);
|
|
}
|
|
|
|
static setEnabled(element, enabled) {
|
|
const tooltip = element.querySelector('.ui-tooltip-wrapper');
|
|
if (tooltip != null) {
|
|
tooltip.style.display = enabled === false ? 'none' : '';
|
|
}
|
|
}
|
|
|
|
static toString() { return '[object Column]' }
|
|
}
|
|
|
|
export class GridInputColumn extends GridColumn {
|
|
static get editing() { return true };
|
|
|
|
static createEdit(trigger, col, _wrapper, 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, _wrapper, 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, container, it) {
|
|
const drop = new Dropdown({
|
|
...col.dropOptions,
|
|
wrapper: container.parentElement
|
|
});
|
|
drop.onSelected = trigger;
|
|
drop.onExpanded = function () {
|
|
if (it.__editing == null) {
|
|
it.__editing = {
|
|
[col.key]: true
|
|
}
|
|
} else {
|
|
it.__editing[col.key] = true;
|
|
}
|
|
if (typeof col.onDropExpanded === 'function') {
|
|
col.onDropExpanded.call(col, it.values, drop);
|
|
}
|
|
};
|
|
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;
|
|
if (col.sourceCache !== false) {
|
|
source = item.source?.[col.key];
|
|
if (source != null) {
|
|
return source;
|
|
}
|
|
}
|
|
source = col.source;
|
|
if (typeof source === 'function') {
|
|
source = source(item.values);
|
|
}
|
|
if (col.sourceCache !== false) {
|
|
if (item.source == null) {
|
|
item.source = { [col.key]: source };
|
|
} else {
|
|
item.source[col.key] = source;
|
|
}
|
|
}
|
|
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, col) {
|
|
return e[col.dropOptions?.valueKey ?? 'value'];
|
|
}
|
|
|
|
static setEnabled(element, enabled) {
|
|
super.setEnabled(element, enabled);
|
|
const drop = this._getDrop(element);
|
|
if (drop == null) {
|
|
return;
|
|
}
|
|
drop.disabled = enabled === false;
|
|
}
|
|
|
|
static leaveEdit(element, container) {
|
|
container.parentElement.querySelectorAll('.ui-drop-box.active').forEach(e => {
|
|
if (e != null) {
|
|
e.classList.remove('active');
|
|
}
|
|
});
|
|
const drop = this._getDrop(element);
|
|
if (drop == null) {
|
|
return;
|
|
}
|
|
if (drop?.multiSelect && typeof drop.onCollapsed === 'function') {
|
|
drop.onCollapsed();
|
|
}
|
|
}
|
|
}
|
|
|
|
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.iconClassName;
|
|
if (typeof className === 'function') {
|
|
className = className.call(col, item.values);
|
|
}
|
|
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.values);
|
|
}
|
|
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');
|
|
}
|
|
}
|
|
}
|
|
|
|
export class GridDateColumn extends GridColumn {
|
|
static createEdit(trigger, col, _container, vals) {
|
|
let enabled = col.enabled;
|
|
if (typeof enabled === 'string') {
|
|
enabled = vals.values[enabled];
|
|
} else if (typeof enabled === 'function') {
|
|
enabled = col.enabled(vals.values);
|
|
}
|
|
if (enabled === false) {
|
|
return super.create();
|
|
}
|
|
const date = createElement('input', 'ui-grid-date-cell');
|
|
date.required = true;
|
|
date.type = 'date';
|
|
if (col.dateMin != null) {
|
|
date.min = col.dateMin;
|
|
}
|
|
if (col.dateMax != null) {
|
|
date.max = col.dateMax;
|
|
}
|
|
// date.addEventListener('change', trigger);
|
|
date.addEventListener('blur', trigger);
|
|
return date;
|
|
}
|
|
|
|
static setValue(element, val) {
|
|
if (element.tagName === 'INPUT') {
|
|
if (isNaN(val) || /^\d{4}-\d{2}-\d{2}$/.test(val)) {
|
|
element.value = val;
|
|
} else {
|
|
val = new Date((val - 621355968e9) / 1e4);
|
|
const month = String(val.getMonth() + 1).padStart(2, '0');
|
|
const date = String(val.getDate()).padStart(2, '0');
|
|
element.value = `${val.getFullYear()}-${month}-${date}`;
|
|
}
|
|
} else {
|
|
element.innerText = this.formatDate(val);
|
|
}
|
|
}
|
|
|
|
static getValue(e) {
|
|
const date = e.target?.valueAsDate;
|
|
if (date instanceof Date && !isNaN(date)) {
|
|
const year = date.getFullYear();
|
|
if (year < 1900 || year > 9999) {
|
|
return '';
|
|
}
|
|
return String(date.getTime() * 1e4 + 621355968e9);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
static setEnabled(element, enabled) {
|
|
element.disabled = enabled === false;
|
|
}
|
|
|
|
static _resolveDate(s) {
|
|
if (s instanceof Date) {
|
|
return s;
|
|
}
|
|
const ticks = Number(s);
|
|
if (!isNaN(ticks) && ticks > 0) {
|
|
return new Date((ticks - 621355968e9) / 1e4);
|
|
}
|
|
return new Date(s);
|
|
}
|
|
|
|
static formatDate(date) {
|
|
date = this._resolveDate(date);
|
|
if (date instanceof Date && !isNaN(date)) {
|
|
return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;
|
|
}
|
|
return '';
|
|
}
|
|
} |