app change
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
import { createElement } from "../functions";
|
||||
import { createIcon } from "./icon";
|
||||
|
||||
function fillCheckbox(container, type, label) {
|
||||
function fillCheckbox(container, type, label, charactor = 'check') {
|
||||
container.appendChild(
|
||||
createElement('layer', 'check-box-inner', createIcon(type, 'check'))
|
||||
createElement('layer', 'check-box-inner', createIcon(type, charactor))
|
||||
);
|
||||
if (label instanceof HTMLElement) {
|
||||
container.appendChild(label);
|
||||
@ -14,6 +14,33 @@ function fillCheckbox(container, type, label) {
|
||||
}
|
||||
}
|
||||
|
||||
function createRadiobox(opts = {}) {
|
||||
const container = createElement('label', 'checkbox-wrapper radiobox-wrapper',
|
||||
createElement('input', input => {
|
||||
input.setAttribute('type', 'radio');
|
||||
input.name = opts.name;
|
||||
if (opts.checked === true) {
|
||||
input.checked = true;
|
||||
}
|
||||
if (opts.enabled === false) {
|
||||
input.disabled = true;
|
||||
}
|
||||
if (opts.customerAttributes != null) {
|
||||
for (let entry of Object.entries(opts.customerAttributes)) {
|
||||
input.setAttribute(entry[0], entry[1]);
|
||||
}
|
||||
}
|
||||
if (typeof opts.onchange === 'function') {
|
||||
input.addEventListener('change', opts.onchange);
|
||||
}
|
||||
}));
|
||||
if (opts.className) {
|
||||
container.classList.add(opts.className);
|
||||
}
|
||||
fillCheckbox(container, opts.type || 'fa-regular', opts.label, 'circle');
|
||||
return container;
|
||||
}
|
||||
|
||||
function createCheckbox(opts = {}) {
|
||||
const container = createElement('label', 'checkbox-wrapper',
|
||||
createElement('input', input => {
|
||||
@ -131,5 +158,6 @@ function resolveCheckbox(container = document.body, legacy) {
|
||||
|
||||
export {
|
||||
createCheckbox,
|
||||
resolveCheckbox
|
||||
resolveCheckbox,
|
||||
createRadiobox
|
||||
}
|
2
lib/ui/grid.d.ts
vendored
2
lib/ui/grid.d.ts
vendored
@ -25,6 +25,7 @@ interface GridColumnType {
|
||||
2: "Dropdown";
|
||||
3: "Checkbox";
|
||||
4: "Icon";
|
||||
5: "Text";
|
||||
}
|
||||
|
||||
interface GridColumnDefinition {
|
||||
@ -123,6 +124,7 @@ declare var Grid: {
|
||||
Dropdown: 2,
|
||||
Checkbox: 3,
|
||||
Icon: 4,
|
||||
Text: 5,
|
||||
isCheckbox(type: Number): boolean;
|
||||
};
|
||||
GridColumn: typeof GridColumn;
|
||||
|
@ -223,6 +223,7 @@
|
||||
type: statusCol,
|
||||
enabled: 'enabled'
|
||||
},
|
||||
{ key: 'c2c', caption: '多行编辑', type: Grid.ColumnTypes.Text, enabled: 'enabled' },
|
||||
{ key: 'c3', caption: 'column 3', width: 90 },
|
||||
{ key: 'c4', caption: 'Note', type: Grid.ColumnTypes.Input },
|
||||
{
|
||||
@ -252,11 +253,11 @@
|
||||
grid.cellDblClicked = (rId, cId) => console.log(`row (${rId}), column (${cId}) double clicked.`);
|
||||
grid.init();
|
||||
grid.source = [
|
||||
{ c1: 'abc', c2: true, c2a: 'off', c2b: '<font style="color: red; margin-left: 8px">red</font>', c3: 12345, c4: 'another note', enabled: false },
|
||||
{ c1: 'abc', c2: true, c2a: 'off', c2b: '<font style="color: red; margin-left: 8px">red</font>', c2c: 'multiple lines\nline2\nline3\n\nline5', c3: 12345, c4: 'another note' },
|
||||
{ c1: 'abc2bbbbaaaaa', c2: false, c2a: 'pending', c2b: '<b style="margin-left: 8px">bold</b>', c3: 1225, c4: 'Note note this is note' },
|
||||
{ c1: 'type', c2: false, c2a: 'broken', c3: 121111 },
|
||||
{ c1: 'type', c2: false, c2a: 'broken', c2c: 'multiple lines\nline2\nline3\n\nline5', c3: 121111 },
|
||||
{ c1: 'diff', c2: true, c2a: 'running', c3: 124445555555555555 },
|
||||
{ c1: 'diff', c2: true, c2a: 'running', c3: 12499 },
|
||||
{ c1: 'diff', c2: true, c2a: 'running', c3: 12499, enabled: false },
|
||||
{ c1: 'diff', c2: true, c2a: 'off', c3: 1244445 }
|
||||
];
|
||||
|
||||
@ -265,7 +266,7 @@
|
||||
</script>
|
||||
<style type="text/css">
|
||||
#grid-sample {
|
||||
/* height: 400px; */
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
#grid-sample>.grid {
|
||||
|
@ -54,12 +54,15 @@ class GridColumn {
|
||||
}
|
||||
|
||||
class GridInputColumn extends GridColumn {
|
||||
static createEdit(trigger) {
|
||||
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', () => vals.__editing = true);
|
||||
return input;
|
||||
}
|
||||
|
||||
@ -76,6 +79,29 @@ class GridInputColumn extends GridColumn {
|
||||
static setEnabled(element, enabled) { element.disabled = enabled === false }
|
||||
}
|
||||
|
||||
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', () => vals.__editing = 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`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SymbolDropdown = Symbol.for('ui-dropdown');
|
||||
|
||||
class GridDropdownColumn extends GridColumn {
|
||||
@ -217,7 +243,8 @@ const ColumnTypes = {
|
||||
1: GridInputColumn,
|
||||
2: GridDropdownColumn,
|
||||
3: GridCheckboxColumn,
|
||||
4: GridIconColumn
|
||||
4: GridIconColumn,
|
||||
5: GridTextColumn
|
||||
};
|
||||
|
||||
class Grid {
|
||||
@ -248,6 +275,7 @@ class Grid {
|
||||
};
|
||||
virtualCount = 100;
|
||||
rowHeight = 36;
|
||||
lineHeight = 24;
|
||||
extraRows = 0;
|
||||
filterRowHeight = 30;
|
||||
height;
|
||||
@ -274,6 +302,7 @@ class Grid {
|
||||
Dropdown: 2,
|
||||
Checkbox: 3,
|
||||
Icon: 4,
|
||||
Text: 5,
|
||||
isCheckbox(type) { return type === 3 }
|
||||
};
|
||||
|
||||
@ -715,10 +744,15 @@ class Grid {
|
||||
if (!this.holderDisabled) {
|
||||
const holder = createElement('div', 'grid-hover-holder');
|
||||
holder.addEventListener('mousedown', e => {
|
||||
const keyid = e.currentTarget.keyid;
|
||||
const holder = e.currentTarget;
|
||||
const keyid = holder.keyid;
|
||||
if (keyid == null) {
|
||||
return;
|
||||
}
|
||||
delete holder.keyid;
|
||||
if (holder.classList.contains('active')) {
|
||||
holder.classList.remove('active');
|
||||
}
|
||||
return this.#onRowClicked(e, (keyid >>> MaxColumnBit) - this.#startIndex, keyid & MaxColumnMask);
|
||||
});
|
||||
holder.addEventListener('dblclick', e => this.#onRowDblClicked(e));
|
||||
@ -846,8 +880,12 @@ class Grid {
|
||||
const type = isCheckbox ? GridCheckboxColumn : this.#colTypes[col.key] ?? GridColumn;
|
||||
let element;
|
||||
if (!isCheckbox && selectChanged && typeof type.createEdit === 'function') {
|
||||
if (vals.__editing && type.editing) {
|
||||
val = type.getValue({ target: cell.children[0] });
|
||||
this.#onRowChanged(null, startIndex + i, col, val, true);
|
||||
}
|
||||
element = selected ?
|
||||
type.createEdit(e => this.#onRowChanged(e, startIndex + i, col, type.getValue(e)), col, this.#refs.bodyContent) :
|
||||
type.createEdit(e => this.#onRowChanged(e, startIndex + i, col, type.getValue(e)), col, this.#refs.bodyContent, vals) :
|
||||
type.create(col);
|
||||
cell.replaceChildren(element);
|
||||
} else {
|
||||
@ -864,7 +902,7 @@ class Grid {
|
||||
enabled = item[enabled];
|
||||
}
|
||||
}
|
||||
type.setValue(element, val, item, col);
|
||||
type.setValue(element, val, item, col, this);
|
||||
if (typeof type.setEnabled === 'function') {
|
||||
type.setEnabled(element, enabled);
|
||||
}
|
||||
@ -898,6 +936,9 @@ class Grid {
|
||||
}
|
||||
}
|
||||
});
|
||||
if (vals.__editing) {
|
||||
delete vals.__editing;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1322,7 +1363,7 @@ class Grid {
|
||||
if (overflow) {
|
||||
holder.keyid = keyid;
|
||||
holder.innerText = element.innerText;
|
||||
const top = this.#refs.bodyContent.offsetTop + target.offsetTop + 1;
|
||||
const top = this.#refs.bodyContent.offsetTop + target.offsetTop;
|
||||
let left = target.offsetLeft;
|
||||
let width = holder.offsetWidth;
|
||||
if (width > this.#bodyClientWidth) {
|
||||
@ -1412,7 +1453,7 @@ class Grid {
|
||||
}
|
||||
|
||||
#onRowDblClicked(e) {
|
||||
if (e.target.tagName === 'INPUT') {
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'LAYER' && e.target.className === 'check-box-inner' || e.target.tagName === 'LABEL' && (e.target.className === 'drop-text' || e.target.className === 'drop-caret')) {
|
||||
return;
|
||||
}
|
||||
const index = this.selectedIndex;
|
||||
@ -1427,7 +1468,7 @@ class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
#onRowChanged(_e, index, col, value) {
|
||||
#onRowChanged(_e, index, col, value, blur) {
|
||||
if (this.#currentSource == null) {
|
||||
return;
|
||||
}
|
||||
@ -1445,8 +1486,14 @@ class Grid {
|
||||
if (enabled !== false) {
|
||||
item[col.key] = value;
|
||||
row.__changed = true;
|
||||
if (typeof col.onchanged === 'function') {
|
||||
col.onchanged.call(this, item, value);
|
||||
if (blur) {
|
||||
if (typeof col.oneditend === 'function') {
|
||||
col.oneditend.call(this, item, value);
|
||||
}
|
||||
} else {
|
||||
if (typeof col.onchanged === 'function') {
|
||||
col.onchanged.call(this, item, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,10 +60,16 @@ class Popup {
|
||||
const button = createElement('div', 'popup-button');
|
||||
button.innerText = b.text;
|
||||
button.addEventListener('click', () => {
|
||||
if (typeof b.trigger === 'function' && b.trigger(this) === false) {
|
||||
return;
|
||||
if (typeof b.trigger === 'function') {
|
||||
const result = b.trigger(this);
|
||||
if (typeof result?.then === 'function') {
|
||||
result.then(r => r !== false && close()).catch(() => { });
|
||||
} else if (result !== false) {
|
||||
close();
|
||||
}
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
close();
|
||||
});
|
||||
return button;
|
||||
}))
|
||||
@ -140,20 +146,25 @@ export function showAlert(title, message, iconType = 'info', parent = document.b
|
||||
});
|
||||
}
|
||||
|
||||
export function showConfirm(title, message, buttons, iconType = 'question', parent = document.body) {
|
||||
export function showConfirm(title, content, buttons, iconType = 'question', parent = document.body) {
|
||||
return new Promise(resolve => {
|
||||
const popup = new Popup({
|
||||
title,
|
||||
content: createElement('div', 'message-wrapper',
|
||||
createIcon('fa-solid', iconTypes[iconType] ?? 'question-circle'),
|
||||
createElement('span', span => span.innerText = message)
|
||||
createElement('span', null, content)
|
||||
),
|
||||
buttons: buttons?.map(b => {
|
||||
return { text: b.text, trigger: p => resolve(b.key, p) }
|
||||
return {
|
||||
text: b.text, trigger: p => resolve({
|
||||
key: b.key,
|
||||
popup: p
|
||||
})
|
||||
};
|
||||
}) ??
|
||||
[
|
||||
{ text: r('yes', 'Yes'), trigger: p => resolve('yes', p) },
|
||||
{ text: r('no', 'No'), trigger: p => resolve('no', p) }
|
||||
{ text: r('yes', 'Yes'), trigger: p => resolve({ key: 'yes', popup: p }) },
|
||||
{ text: r('no', 'No'), trigger: p => resolve({ key: 'no', popup: p }) }
|
||||
]
|
||||
});
|
||||
popup.show(parent);
|
||||
|
Reference in New Issue
Block a user