fix: header z-index issue.

fix: incorrect `onChanged` event trigger on `GridInputColumn`, `GridTextColumn` and `GridDateColumn`.
This commit is contained in:
Chen Lily 2024-02-26 16:11:42 +08:00
parent 7940edbea2
commit 38bad864e0
5 changed files with 63 additions and 45 deletions

View File

@ -94,6 +94,7 @@
// position: relative; // position: relative;
top: 0; top: 0;
position: sticky; position: sticky;
z-index: 1;
&.sticky { &.sticky {
position: sticky; position: sticky;

View File

@ -55,7 +55,8 @@ export class GridColumn {
* 更多例子参考代码中 {@linkcode GridDropdownColumn} 的实现 * 更多例子参考代码中 {@linkcode GridDropdownColumn} 的实现
* @method * @method
* @name GridColumn.createEdit * @name GridColumn.createEdit
* @param {Function} trigger - 编辑事件回调函数`e` 参数会传递给 [getValue]{@linkcode GridColumn.getValue} 方法 * @param {Function} trigger - 编辑事件回调函数
* @param {any} trigger.e - 该参数会传递给 [getValue]{@linkcode GridColumn.getValue} 方法
* @param {GridColumnDefinition} col - 列定义对象 * @param {GridColumnDefinition} col - 列定义对象
* @param {HTMLElement} container - 父容器元素 * @param {HTMLElement} container - 父容器元素
* @param {GridItemWrapper} wrapper - 行包装对象 `values` 属性为行数据对象 * @param {GridItemWrapper} wrapper - 行包装对象 `values` 属性为行数据对象
@ -144,6 +145,29 @@ export class GridColumn {
* @ignore * @ignore
*/ */
static toString() { return '[object Column]' } static toString() { return '[object Column]' }
/**
* @ignore
* @param {string} key
* @param {GridItemWrapper} wrapper
* @param {any} value
*/
static _changeValue(key, wrapper, value) {
const val = wrapper.values[key] ?? null;
const hasValue = val != null && Object.prototype.hasOwnProperty.call(val, 'Value');
if (wrapper.__editing == null) {
wrapper.__editing = {
[key]: hasValue ? val.Value : val
}
} else if (!Object.prototype.hasOwnProperty.call(wrapper.__editing, key)) {
wrapper.__editing[key] = hasValue ? val.Value : val;
}
if (hasValue) {
val.Value = value;
} else {
wrapper.values[key] = value;
}
}
} }
/** /**
@ -158,24 +182,17 @@ export class GridInputColumn extends GridColumn {
/** /**
* @ignore * @ignore
* @param {Function} _trigger * @param {Function} trigger
* @param {GridColumnDefinition} col * @param {GridColumnDefinition} col
* @param {HTMLElement} _container * @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper * @param {GridItemWrapper} wrapper
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
static createEdit(_trigger, col, _container, wrapper) { static createEdit(trigger, col, _container, wrapper) {
const input = createElement('input'); const input = createElement('input');
input.setAttribute('type', 'text'); input.setAttribute('type', 'text');
input.addEventListener('input', () => { input.addEventListener('input', () => super._changeValue(col.key, wrapper, input.value));
if (wrapper.__editing == null) { input.addEventListener('change', trigger);
wrapper.__editing = {
[col.key]: true
}
} else {
wrapper.__editing[col.key] = true;
}
});
return input; return input;
} }
@ -221,23 +238,16 @@ export class GridInputColumn extends GridColumn {
export class GridTextColumn extends GridInputColumn { export class GridTextColumn extends GridInputColumn {
/** /**
* @ignore * @ignore
* @param {Function} _trigger * @param {Function} trigger
* @param {GridColumnDefinition} col * @param {GridColumnDefinition} col
* @param {HTMLElement} _container * @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper * @param {GridItemWrapper} wrapper
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
static createEdit(_trigger, col, _container, wrapper) { static createEdit(trigger, col, _container, wrapper) {
const input = createElement('textarea'); const input = createElement('textarea');
input.addEventListener('input', () => { input.addEventListener('input', () => super._changeValue(col.key, wrapper, input.value));
if (wrapper.__editing == null) { input.addEventListener('change', trigger);
wrapper.__editing = {
[col.key]: true
}
} else {
wrapper.__editing[col.key] = true;
}
});
return input; return input;
} }
@ -476,7 +486,7 @@ export class GridCheckboxColumn extends GridColumn {
*/ */
static createEdit(trigger) { static createEdit(trigger) {
const check = createCheckbox({ const check = createCheckbox({
onchange: typeof trigger === 'function' ? trigger : null onchange: trigger
}); });
return check; return check;
} }
@ -604,13 +614,13 @@ export class GridDateColumn extends GridColumn {
/** /**
* @ignore * @ignore
* @param {Function} _trigger * @param {Function} trigger
* @param {GridColumnDefinition} col * @param {GridColumnDefinition} col
* @param {HTMLElement} _container * @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper * @param {GridItemWrapper} wrapper
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
static createEdit(_trigger, col, _container, wrapper) { static createEdit(trigger, col, _container, wrapper) {
let enabled = col.enabled; let enabled = col.enabled;
if (typeof enabled === 'string') { if (typeof enabled === 'string') {
enabled = wrapper.values[enabled]; enabled = wrapper.values[enabled];
@ -621,15 +631,8 @@ export class GridDateColumn extends GridColumn {
return super.create(); return super.create();
} }
const date = createDateInput(col.dateMin, col.dateMax); const date = createDateInput(col.dateMin, col.dateMax);
date.addEventListener('change', () => { date.addEventListener('change', () => super._changeValue(col.key, wrapper, date.value));
if (wrapper.__editing == null) { date.addEventListener('blur', trigger);
wrapper.__editing = {
[col.key]: true
}
} else {
wrapper.__editing[col.key] = true;
}
});
return date; return date;
} }

View File

@ -95,7 +95,7 @@ let r = lang;
* @property {KeyMap<GridSourceItem[]>} source - 下拉数据源缓存对象 * @property {KeyMap<GridSourceItem[]>} source - 下拉数据源缓存对象
* @property {number} __index - 行索引 * @property {number} __index - 行索引
* @property {number} __offset - 批量删除时暂存的索引偏移量 * @property {number} __offset - 批量删除时暂存的索引偏移量
* @property {KeyMap<boolean>} __editing - 正在编辑 * @property {KeyMap<any>} __editing - 正在编辑的列的原始值字典
* @property {boolean} __changed - 行数据是否发生改变 * @property {boolean} __changed - 行数据是否发生改变
* @property {boolean} __expanded - 行是否已展开 * @property {boolean} __expanded - 行是否已展开
* @property {GridExpandableObject} __expandable_object - 行扩展对象 * @property {GridExpandableObject} __expandable_object - 行扩展对象
@ -2593,19 +2593,30 @@ export class Grid {
const type = isCheckbox ? GridCheckboxColumn : this._var.colTypes[col.key] ?? GridColumn; const type = isCheckbox ? GridCheckboxColumn : this._var.colTypes[col.key] ?? GridColumn;
let element; let element;
if (!readonly && !isCheckbox && typeof type.createEdit === 'function') { if (!readonly && !isCheckbox && typeof type.createEdit === 'function') {
if (vals.__editing?.[col.key]) { const oldValue = vals.__editing?.[col.key];
if (oldValue !== undefined) {
delete vals.__editing[col.key]; delete vals.__editing[col.key];
if (typeof type.leaveEdit === 'function') { if (typeof type.leaveEdit === 'function') {
type.leaveEdit(cell.children[0], this._var.el); type.leaveEdit(cell.children[0], this._var.el);
} }
if (type.editing) { if (type.editing) {
val = type.getValue({ target: cell.children[0] }, col); val = type.getValue({ target: cell.children[0] }, col);
this._onRowChanged(null, i, col, val, cell); this._onRowChanged(null, i, col, val, cell, oldValue);
} }
} }
if (stateChanged) { if (stateChanged) {
element = selected ? element = selected ?
type.createEdit(e => this._onRowChanged(e, i, col, type.getValue(e, col), cell), col, this._var.el, vals) : type.createEdit(e => {
let old;
if (type.editing) {
old = vals.__editing?.[col.key];
if (old === undefined) {
return;
}
delete vals.__editing[col.key];
}
this._onRowChanged(e, i, col, type.getValue(e, col), cell, old);
}, col, this._var.el, vals) :
type.create(col, i, this); type.create(col, i, this);
if (typeof col.class === 'string') { if (typeof col.class === 'string') {
type.setClass(element, col.class); type.setClass(element, col.class);
@ -3783,8 +3794,9 @@ export class Grid {
* @param {GridColumnDefinition} col * @param {GridColumnDefinition} col
* @param {any} value * @param {any} value
* @param {HTMLTableCellElement} cell * @param {HTMLTableCellElement} cell
* @param {any} [oldValue]
*/ */
_onRowChanged(e, index, col, value, cell) { _onRowChanged(e, index, col, value, cell, oldValue) {
if (this._var.currentSource == null) { if (this._var.currentSource == null) {
return; return;
} }
@ -3802,12 +3814,11 @@ export class Grid {
} }
if (enabled !== false) { if (enabled !== false) {
const val = item[col.key]; const val = item[col.key];
let oldValue;
if (val != null && Object.prototype.hasOwnProperty.call(val, 'Value')) { if (val != null && Object.prototype.hasOwnProperty.call(val, 'Value')) {
oldValue = val.Value; oldValue ??= val.Value;
val.Value = value; val.Value = value;
} else { } else {
oldValue = val; oldValue ??= val;
item[col.key] = value; item[col.key] = value;
} }
let tip = col.tooltip; let tip = col.tooltip;

View File

@ -1650,8 +1650,9 @@ const dict = {
function createUse(type, id) { function createUse(type, id) {
const c = typeof consts !== 'undefined' ? consts : {}; const c = typeof consts !== 'undefined' ? consts : {};
const netroot = typeof _network !== 'undefined' ? _network.root : ''; const path = c.path ||
const path = c.path || netroot; (typeof _network !== 'undefined' ? _network.root :
(typeof _net !== 'undefined' ? _net.root : ''));
const ver = c.resver == null ? '' : `?${c.resver}`; const ver = c.resver == null ? '' : `?${c.resver}`;
const use = document.createElementNS(svgns, 'use'); const use = document.createElementNS(svgns, 'use');
if (id?.length === 1 && id.charCodeAt(0) > 0xf000) { if (id?.length === 1 && id.charCodeAt(0) > 0xf000) {

View File

@ -50,6 +50,8 @@ export function formatUrl(msg) {
path = consts.path; path = consts.path;
} else if (typeof _network !== 'undefined') { } else if (typeof _network !== 'undefined') {
path = _network.root; path = _network.root;
} else if (typeof _net !== 'undefined') {
path = _net.root;
} }
for (let r of rs) { for (let r of rs) {
msg = msg.replaceAll(r, `<a target="_blank" href="${r}"><svg><use xlink:href="${path || ''}fonts/fa-regular.svg#link"></use></svg></a>`); msg = msg.replaceAll(r, `<a target="_blank" href="${r}"><svg><use xlink:href="${path || ''}fonts/fa-regular.svg#link"></use></svg></a>`);