add more comments

This commit is contained in:
Chen Lily 2024-02-02 16:02:34 +08:00
parent 5d199a2bfb
commit bed5c1aca1
5 changed files with 237 additions and 125 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -338,6 +338,7 @@
.ui-check-wrapper { .ui-check-wrapper {
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
height: var(--row-height);
.ui-check-inner { .ui-check-inner {

View File

@ -9,7 +9,11 @@ import { createDateInput, formatDate, setDateValue, getDateValue } from "../date
/** /**
* 列定义基类 * 列定义基类
*
* _函数调用流程图示_<br/>
* <img src="./assets/column-refresh.jpg" alt="Column Refresh"/>
* @class * @class
* @static
*/ */
export class GridColumn { export class GridColumn {
/** /**
@ -26,6 +30,8 @@ export class GridColumn {
/** /**
* 创建显示单元格时调用的方法 * 创建显示单元格时调用的方法
* @param {GridColumnDefinition} col - 列定义对象 * @param {GridColumnDefinition} col - 列定义对象
* @param {number} index - 行元素索引需要配合 [startIndex]{@linkcode Grid#startIndex} 相加得到真实数据索引
* @param {Grid} grid - Grid 实例
* @returns {HTMLElement} 返回创建的单元格元素 * @returns {HTMLElement} 返回创建的单元格元素
* @virtual * @virtual
*/ */
@ -93,6 +99,16 @@ export class GridColumn {
element.style.cssText = convertCssStyle(style); element.style.cssText = convertCssStyle(style);
} }
/**
* 设置单元格类名时调用的方法
* @param {HTMLElement} element - 单元格元素
* @param {string} name - 要设置的类名
* @virtual
*/
static setClass(element, name) {
element.className = name ?? '';
}
/** /**
* 设置单元格可用性时调用的方法 * 设置单元格可用性时调用的方法
* @param {HTMLElement} element - 单元格元素 * @param {HTMLElement} element - 单元格元素
@ -297,6 +313,14 @@ export class GridDropdownColumn extends GridColumn {
return e[col.dropOptions?.valueKey ?? 'value']; return e[col.dropOptions?.valueKey ?? 'value'];
} }
static setClass(element, name) {
if (element.tagName === 'DIV') {
element.className = `ui-drop-wrapper ${name ?? ''}`;
} else {
super.setClass(element, name);
}
}
static setEnabled(element, enabled) { static setEnabled(element, enabled) {
super.setEnabled(element, enabled); super.setEnabled(element, enabled);
const drop = this._getDrop(element); const drop = this._getDrop(element);
@ -336,6 +360,14 @@ export class GridCheckboxColumn extends GridColumn {
static getValue(e) { return e.target.checked } static getValue(e) { return e.target.checked }
static setClass(element, name) {
if (element.tagName === 'LABEL') {
element.className = `ui-check-wrapper ${name ?? ''}`;
} else {
super.setClass(element, name);
}
}
static setEnabled(element, enabled) { static setEnabled(element, enabled) {
super.setEnabled(element, enabled); super.setEnabled(element, enabled);
element.querySelector('input').disabled = enabled === false; element.querySelector('input').disabled = enabled === false;
@ -346,15 +378,15 @@ export class GridIconColumn extends GridColumn {
static create() { return createElement('span', 'col-icon') } static create() { return createElement('span', 'col-icon') }
static setValue(element, val, item, col) { static setValue(element, val, item, col) {
let className = col.iconClassName; // let className = col.iconClassName;
if (typeof className === 'function') { // if (typeof className === 'function') {
className = className.call(col, item.values); // className = className.call(col, item.values);
} // }
if (className == null) { // if (className == null) {
element.className = 'col-icon'; // element.className = 'col-icon';
} else { // } else {
element.className = `col-icon ${className}`; // element.className = `col-icon ${className}`;
} // }
let type = col.iconType; let type = col.iconType;
if (typeof type === 'function') { if (typeof type === 'function') {
type = type.call(col, item.values); type = type.call(col, item.values);
@ -370,6 +402,10 @@ export class GridIconColumn extends GridColumn {
} }
} }
static setClass(element, name) {
element.className = `col-icon ${name ?? ''}`;
}
static setEnabled(element, enabled) { static setEnabled(element, enabled) {
super.setEnabled(element, enabled); super.setEnabled(element, enabled);
if (enabled === false) { if (enabled === false) {
@ -405,6 +441,14 @@ export class GridDateColumn extends GridColumn {
return getDateValue(e.target, col.dateValueFormatter); return getDateValue(e.target, col.dateValueFormatter);
} }
static setClass(element, name) {
if (element.tagName === 'INPUT') {
element.className = `ui-date-cell ${name ?? ''}`;
} else {
super.setClass(element, name);
}
}
static setEnabled(element, enabled) { static setEnabled(element, enabled) {
element.disabled = enabled === false; element.disabled = enabled === false;
} }

View File

@ -128,55 +128,6 @@ let r = lang;
* @returns {GridSourceItem[]} 行下拉列表数据源 * @returns {GridSourceItem[]} 行下拉列表数据源
*/ */
/**
* 列头复选框改变时的回调函数
* @callback GridColumnCheckedCallback
* @param {GridColumnDefinition} col - 列定义对象
* @param {boolean} flag - 是否选中
* @this Grid
*/
/**
* 单元格发生变化时的回调函数
* @callback GridCellChangedCallback
* @param {GridItem} item - 行数据对象
* @param {(boolean | string | number)} value - 修改后的值
* @param {(boolean | string | number)} oldValue - 修改前的值
* @param {any} [e] - 列修改事件传递过来的任意对象
* @this Grid
*/
/**
* 文本单元格输入完成时的回调函数
* @callback GridCellInputEndedCallback
* @param {GridColumnDefinition} col - 列定义对象
* @param {string} value - 修改后的文本框值
* @this Grid
*/
/**
* 列过滤点 `OK` 时的回调函数
* @callback GridColumnFilterOkCallback
* @param {GridColumnDefinition} col - 列定义对象
* @param {GridItem[]} selected - 选中的过滤项
* @this Grid
*/
/**
* 列过滤后的回调函数
* @callback GridColumnFilteredCallback
* @param {GridColumnDefinition} col - 列定义对象
* @this Grid
*/
/**
* 下拉框列表展开时的回调函数
* @callback GridColumnDropExpandedCallback
* @param {GridItem} item - 行数据对象
* @param {Dropdown} drop - 拉框对象
* @this GridColumnDefinition
*/
/** /**
* 下拉列表参数对象 * 下拉列表参数对象
* @typedef DropdownOptions * @typedef DropdownOptions
@ -207,7 +158,7 @@ let r = lang;
/** /**
* 列定义接口 * 列定义接口
* @typedef {object} GridColumnDefinition * @class
* @property {string} key - 列关键字默认以该关键字从行数据中提取单元格值行数据的关键字属性值里包含 DisplayValue 则优先显示此值 * @property {string} key - 列关键字默认以该关键字从行数据中提取单元格值行数据的关键字属性值里包含 DisplayValue 则优先显示此值
* @property {(GridColumnTypeEnum | GridColumn)} [type=Grid.ColumnTypes.Common] - 列的类型可以为 {@linkcode GridColumn} 的子类或者如下内置类型 {@linkcode Grid.ColumnTypes} * @property {(GridColumnTypeEnum | GridColumn)} [type=Grid.ColumnTypes.Common] - 列的类型可以为 {@linkcode GridColumn} 的子类或者如下内置类型 {@linkcode Grid.ColumnTypes}
* @property {number} type.Common=0 - 通用列只读 * @property {number} type.Common=0 - 通用列只读
@ -241,15 +192,19 @@ let r = lang;
* @property {boolean} [sortable=true] - 列是否允许排序 * @property {boolean} [sortable=true] - 列是否允许排序
* @property {boolean} [orderable=true] - 列是否允许重排顺序 * @property {boolean} [orderable=true] - 列是否允许重排顺序
* @property {boolean} [allcheck=false] - 列为复选框类型时是否在列头增加全选复选框 * @property {boolean} [allcheck=false] - 列为复选框类型时是否在列头增加全选复选框
* @property {boolean} [shrink=false] - 列为收缩列禁用自动调整大小
* @property {string} [class] - 单元格元素的额外样式类型字符串仅在重建行元素时读取
* @property {object} [css] - 单元格css样式对象仅在重建行元素时读取 * @property {object} [css] - 单元格css样式对象仅在重建行元素时读取
* @property {GridItemObjectCallback} [styleFilter] - 根据返回值填充单元格样式填充行列数据时读取 * @property {(object | GridItemObjectCallback)} [style] - 单元格样式填充行列数据时读取支持直接返回样式对象或调用函数返回若赋值则忽略 [styleFilter]{@linkcode GridColumnDefinition#styleFilter}
* @property {GridColumnDefinition} styleFilter.{this} - 上下文为列定义对象 * @property {GridColumnDefinition} style.{this} - 上下文为列定义对象
* @property {GridItem} styleFilter.item - 行数据对象 * @property {GridItem} style.item - 行数据对象
* @property {object} styleFilter.{returns} - 返回样式对象 * @property {object} style.{returns} - 返回样式对象
* @property {GridItemStringCallback} [bgFilter] - 根据返回值设置单元格背景色 * @property {(@deprecated)} [styleFilter] - **已过时**<br/>_根据返回值填充单元格样式填充行列数据时读取_
* @property {GridColumnDefinition} bgFilter.{this} - 上下文为列定义对象 * @property {(string | GridItemStringCallback)} [background] - 设置单元格背景色填充行列数据时读取支持直接设置颜色字符串或调用函数返回若赋值则忽略 [bgFilter]{@linkcode GridColumnDefinition#bgFilter}
* @property {GridItem} bgFilter.item - 行数据对象 * @property {GridColumnDefinition} background.{this} - 上下文为列定义对象
* @property {string} bgFilter.{returns} - 返回单元格背景色字符串 * @property {GridItem} background.item - 行数据对象
* @property {string} background.{returns} - 返回单元格背景色字符串
* @property {(@deprecated)} [bgFilter] - **已过时**<br/>_根据返回值设置单元格背景色_
* @property {object} [events] - 给单元格元素附加事件事件函数上下文为数据行对象 * @property {object} [events] - 给单元格元素附加事件事件函数上下文为数据行对象
* @property {Function} events.{event} - 事件回调函数 * @property {Function} events.{event} - 事件回调函数
* @property {(object | GridItemObjectCallback)} [attrs] - 根据返回值设置单元格元素的附加属性允许直接设置对象也支持调用如下函数返回对象 * @property {(object | GridItemObjectCallback)} [attrs] - 根据返回值设置单元格元素的附加属性允许直接设置对象也支持调用如下函数返回对象
@ -271,10 +226,6 @@ let r = lang;
* @property {GridSourceItem[]} source.{returns} - 返回行下拉列表数据源 * @property {GridSourceItem[]} source.{returns} - 返回行下拉列表数据源
* @property {boolean} [sourceCache=false] - 下拉列表数据源是否缓存结果即行数据未发生变化时仅从source属性获取一次值 * @property {boolean} [sourceCache=false] - 下拉列表数据源是否缓存结果即行数据未发生变化时仅从source属性获取一次值
* @property {("fa-light" | "fa-regular" | "fa-solid")} [iconType=fa-light] - 列为图标类型时以该值设置图标样式 * @property {("fa-light" | "fa-regular" | "fa-solid")} [iconType=fa-light] - 列为图标类型时以该值设置图标样式
* @property {(string | GridItemStringCallback)} [iconClassName] - 列为图标类型时以该值作为单元格元素的额外样式类型支持直接使用字符串或者调用如下函数
* @property {GridColumnDefinition} iconClassName.{this} - 上下文为列定义对象
* @property {GridItem} iconClassName.item - 行数据对象
* @property {string} iconClassName.{returns} - 返回额外样式类型字符串
* @property {string} [dateMin] - 列为日期类型时以该值作为最小可选日期值 * @property {string} [dateMin] - 列为日期类型时以该值作为最小可选日期值
* @property {string} [dateMax] - 列为日期类型时以该值作为最大可选日期值 * @property {string} [dateMax] - 列为日期类型时以该值作为最大可选日期值
* @property {DateFormatterCallback} [dateValueFormatter] - 列为日期类型时自定义日期格式化函数 * @property {DateFormatterCallback} [dateValueFormatter] - 列为日期类型时自定义日期格式化函数
@ -284,32 +235,59 @@ let r = lang;
* @property {GridColumnDefinition} tooltip.{this} - 上下文为列定义对象 * @property {GridColumnDefinition} tooltip.{this} - 上下文为列定义对象
* @property {GridItem} tooltip.item - 行数据对象 * @property {GridItem} tooltip.item - 行数据对象
* @property {string} tooltip.{returns} - 返回额外 tooltip 字符串 * @property {string} tooltip.{returns} - 返回额外 tooltip 字符串
* @property {GridColumnCheckedCallback} [onAllChecked] - 列头复选框改变时触发
* @property {Grid} onAllChecked.{this} - 上下文为 Grid
* @property {GridColumnDefinition} onAllChecked.col - 列定义对象
* @property {boolean} onAllChecked.flag - 是否选中
* @property {GridCellChangedCallback} [onChanged] - 单元格发生变化时触发
* @property {Grid} onChanged.{this} - 上下文为 Grid
* @property {GridItem} onChanged.item - 行数据对象
* @property {(boolean | string | number)} onChanged.value - 修改后的值
* @property {(boolean | string | number)} onChanged.oldValue - 修改前的值
* @property {any} [onChanged.e] - 列修改事件传递过来的任意对象
* @property {GridCellInputEndedCallback} [onInputEnded] - 文本单元格在输入完成时触发的事件
* @property {Grid} onInputEnded.{this} - 上下文为 Grid
* @property {GridColumnDefinition} onInputEnded.col - 列定义对象
* @property {string} onInputEnded.value - 修改后的文本框值
* @property {GridColumnFilterOkCallback} [onFilterOk] - 列过滤点击 `OK` 时触发的事件
* @property {Grid} onFilterOk.{this} - 上下文为 Grid
* @property {GridColumnDefinition} onFilterOk.col - 列定义对象
* @property {GridItem[]} onFilterOk.selected - 选中的过滤项
* @property {GridColumnFilteredCallback} [onFiltered] - 列过滤后触发的事件
* @property {Grid} onFiltered.{this} - 上下文为 Grid
* @property {GridColumnDefinition} onFiltered.col - 列定义对象
* @property {GridColumnDropExpandedCallback} [onDropExpanded] - 列为下拉框类型时在下拉列表展开时触发的事件
* @property {GridColumnDefinition} onDropExpanded.{this} - 上下文为列定义对象
* @property {GridItem} onDropExpanded.item - 行数据对象
* @property {Dropdown} onDropExpanded.drop - 拉框对象
*/ */
class GridColumnDefinition {
/**
* 列头复选框改变时触发
* @type {Function}
* @event
* @param {GridColumnDefinition} col - 列定义对象
* @param {boolean} flag - 是否选中
* @this Grid
*/
onAllChecked;
/**
* 单元格发生变化时触发
* @event
* @param {GridItem} item - 行数据对象
* @param {(boolean | string | number)} value - 修改后的值
* @param {(boolean | string | number)} oldValue - 修改前的值
* @param {any} [e] - 列修改事件传递过来的任意对象
* @this Grid
*/
onChanged;
/**
* 文本单元格在输入完成时触发的事件
* @event
* @param {GridColumnDefinition} col - 列定义对象
* @param {string} value - 修改后的文本框值
* @this Grid
*/
onInputEnded;
/**
* 列过滤点击 `OK` 时触发的事件
* @event
* @param {GridColumnDefinition} col - 列定义对象
* @param {GridItem[]} selected - 选中的过滤项
* @this Grid
*/
onFilterOk;
/**
* 列过滤后触发的事件
* @event
* @param {GridColumnDefinition} col - 列定义对象
* @this Grid
*/
onFiltered;
/**
* 列为下拉框类型时在下拉列表展开时触发的事件
* @event
* @param {GridItem} item - 行数据对象
* @param {Dropdown} drop - 拉框对象
* @this GridColumnDefinition
*/
onDropExpanded;
}
/** /**
* 判断复选框列的回调函数 * 判断复选框列的回调函数
@ -424,73 +402,92 @@ const GridColumnDirection = {
* ]; * ];
*/ */
export class Grid { export class Grid {
/**
* 内部引用变量
* @private
*/
_var = { _var = {
/** /**
* 父容器元素 * 父容器元素
* @type {HTMLElement} * @type {HTMLElement}
* @private
*/ */
parent: null, parent: null,
/** /**
* Grid 元素 - `div.ui-grid` * Grid 元素 - `div.ui-grid`
* @type {HTMLDivElement} * @type {HTMLDivElement}
* @private
*/ */
el: null, el: null,
/** /**
* 全部数据数组 * 全部数据数组
* @type {GridItemWrapper[]} * @type {GridItemWrapper[]}
* @private
*/ */
source: null, source: null,
/** /**
* 当前已过滤显示的数据数组 * 当前已过滤显示的数据数组
* @type {GridItemWrapper[]} * @type {GridItemWrapper[]}
* @private
*/ */
currentSource: null, currentSource: null,
/** /**
* 当前选中的列索引 * 当前选中的列索引
* @type {number} * @type {number}
* @private
*/ */
selectedColumnIndex: -1, selectedColumnIndex: -1,
/** /**
* 当前选中的行索引数组 * 当前选中的行索引数组
* @type {number[]} * @type {number[]}
* @private
*/ */
selectedIndexes: null, selectedIndexes: null,
/** /**
* 虚模式头部索引 * 虚模式头部索引
* @type {number} * @type {number}
* @private
*/ */
startIndex: 0, startIndex: 0,
/** /**
* 旧选择索引数组 * 旧选择索引数组
* @type {number[]} * @type {number[]}
* @private
*/ */
oldSelectedIndexes: null, oldSelectedIndexes: null,
/** /**
* 旧虚模式头部索引 * 旧虚模式头部索引
* @type {number}
* @private
*/ */
oldIndex: null, oldIndex: null,
/** /**
* 当前滚动上边距 * 当前滚动上边距
* @private
* @type {number} * @type {number}
*/ */
scrollTop: 0, scrollTop: 0,
/** /**
* 当前滚动左边距 * 当前滚动左边距
* @private
* @type {number} * @type {number}
*/ */
scrollLeft: 0, scrollLeft: 0,
/** /**
* 一页高度可显示的行数 * 一页高度可显示的行数
* @private
* @type {number} * @type {number}
*/ */
rowCount: -1, rowCount: -1,
/** /**
* 列类型缓存字典 * 列类型缓存字典
* @private
* @property {GridColumn} {key} - 关键字对应列的类型缓存对象 * @property {GridColumn} {key} - 关键字对应列的类型缓存对象
*/ */
colTypes: {}, colTypes: {},
/** /**
* 列属性字典 * 列属性字典
* @private
* @property {object} {key} - 关键字对应列的拖拽调整大小暂存对象 * @property {object} {key} - 关键字对应列的拖拽调整大小暂存对象
* @property {boolean} {key}.dragging - 列正在拖拽 * @property {boolean} {key}.dragging - 列正在拖拽
* @property {number} {key}.offset - 列拖拽偏移 * @property {number} {key}.offset - 列拖拽偏移
@ -508,81 +505,103 @@ export class Grid {
/** /**
* 有已过滤的列 * 有已过滤的列
* @type {boolean} * @type {boolean}
* @private
*/ */
__filtered: false, __filtered: false,
/** /**
* 过滤面板已打开 * 过滤面板已打开
* @type {boolean} * @type {boolean}
* @private
*/ */
__filtering: false, __filtering: false,
/** /**
* 上一个目标排序列索引 * 上一个目标排序列索引
* @type {number} * @type {number}
* @private
*/ */
__orderIndex: -1, __orderIndex: -1,
}, },
/** /**
* 是否处于渲染中 * 是否处于渲染中
* @type {boolean} * @type {boolean}
* @private
*/ */
rendering: false, rendering: false,
/**
* 头部高度
* @type {number}
* @private
*/
headerHeight: null,
/** /**
* 正文高度 * 正文高度
* @type {number} * @type {number}
* @private
*/ */
containerHeight: null, containerHeight: null,
/** /**
* 正文宽度 * 正文宽度
* @type {number} * @type {number}
* @private
*/ */
bodyClientWidth: null, bodyClientWidth: null,
/** /**
* 是否需要 resize * 是否需要 resize
* @type {boolean} * @type {boolean}
* @private
*/ */
needResize: null, needResize: null,
/** /**
* 页面元素引用 * 页面元素引用
* @private
*/ */
refs: { refs: {
/** /**
* 表格引用 - table.ui-grid-table * 表格引用 - table.ui-grid-table
* @type {HTMLTableElement} * @type {HTMLTableElement}
* @private
*/ */
table: null, table: null,
/** /**
* 表格正文引用 - tbody * 表格正文引用 - tbody
* @type {HTMLTableSectionElement} * @type {HTMLTableSectionElement}
* @private
*/ */
body: null, body: null,
/** /**
* 表格头部引用 - thead>tr * 表格头部引用 - thead>tr
* @type {HTMLTableSectionElement} * @type {HTMLTableSectionElement}
* @private
*/ */
header: null, header: null,
/** /**
* 加载状态元素引用 - div.ui-grid-loading * 加载状态元素引用 - div.ui-grid-loading
* @type {HTMLDivElement} * @type {HTMLDivElement}
* @private
*/ */
loading: null, loading: null,
/** /**
* 大小计算元素引用 - span.ui-grid-sizer * 大小计算元素引用 - span.ui-grid-sizer
* @type {HTMLSpanElement} * @type {HTMLSpanElement}
* @private
*/ */
sizer: null, sizer: null,
/** /**
* 包装元素引用 - div.ui-grid-wrapper * 包装元素引用 - div.ui-grid-wrapper
* @type {HTMLDivElement} * @type {HTMLDivElement}
* @private
*/ */
wrapper: null, wrapper: null,
/** /**
* 拖拽块引用 - div.dragger * 拖拽块引用 - div.dragger
* @type {HTMLDivElement} * @type {HTMLDivElement}
* @private
*/ */
dragger: null, dragger: null,
/** /**
* 拖拽光标引用 - layer.dragger-cursor * 拖拽光标引用 - layer.dragger-cursor
* @type {HTMLElement} * @type {HTMLElement}
* @private
*/ */
draggerCursor: null, draggerCursor: null,
} }
@ -955,9 +974,9 @@ export class Grid {
} }
} }
if (this.sortIndex >= 0) { if (this.sortIndex >= 0) {
this.sortColumn(); this.sortColumn(true);
} else if (this.sortArray?.length > 0) { } else if (this.sortArray?.length > 0) {
this.sort(); this.sort(true);
} else { } else {
this.reload(); this.reload();
} }
@ -998,9 +1017,9 @@ export class Grid {
} }
} }
if (this.sortIndex >= 0) { if (this.sortIndex >= 0) {
this.sortColumn(); this.sortColumn(true);
} else if (this.sortArray?.length > 0) { } else if (this.sortArray?.length > 0) {
this.sort(); this.sort(true);
} else { } else {
this.reload(); this.reload();
} }
@ -1109,12 +1128,15 @@ export class Grid {
this._var.scrollLeft = 0; this._var.scrollLeft = 0;
this._var.rowCount = -1; this._var.rowCount = -1;
if (this.sortIndex >= 0) { this.resize(true, null, () => {
this.sortColumn(); if (this.sortIndex >= 0) {
} else if (this.sortArray?.length > 0) { this.sortColumn(true);
this.sort(); } else if (this.sortArray?.length > 0) {
} this.sort(true);
this.resize(); } else {
this.reload();
}
});
} }
/** /**
@ -1145,6 +1167,13 @@ export class Grid {
return Array.prototype.slice.call(this._var.refs.header.querySelectorAll('&>th.column')); return Array.prototype.slice.call(this._var.refs.header.querySelectorAll('&>th.column'));
} }
/**
* 获取虚模式起始索引
* @readonly
* @type {number}
*/
get startIndex() { return this._var.startIndex }
/** /**
* 获取或设置当前选中的行索引的数组设置后会刷新列表 * 获取或设置当前选中的行索引的数组设置后会刷新列表
* @type {number[]} * @type {number[]}
@ -1331,9 +1360,9 @@ export class Grid {
this._var.rendering = false; this._var.rendering = false;
if (this._var.source != null) { if (this._var.source != null) {
if (this.sortIndex >= 0) { if (this.sortIndex >= 0) {
this.sortColumn(); this.sortColumn(true);
} else if (this.sortArray?.length > 0) { } else if (this.sortArray?.length > 0) {
this.sort(); this.sort(true);
} }
} }
} }
@ -1359,8 +1388,10 @@ export class Grid {
* 调整 Grid 元素的大小一般需要在宽度变化时如页面大小发生变化时调用 * 调整 Grid 元素的大小一般需要在宽度变化时如页面大小发生变化时调用
* @param {boolean} [force] - 是否强制 [reload]{@linkcode Grid#reload}默认只有待渲染的行数发生变化时才会调用 * @param {boolean} [force] - 是否强制 [reload]{@linkcode Grid#reload}默认只有待渲染的行数发生变化时才会调用
* @param {boolean} [keep] - 是否保持当前滚动位置 * @param {boolean} [keep] - 是否保持当前滚动位置
* @param {Function} [callback] - 计算大小后的回调函数
* @param {Grid} callback.{this} - 上下文为 Grid
*/ */
resize(force, keep) { resize(force, keep, callback) {
if (this._var.rendering || this._var.el == null) { if (this._var.rendering || this._var.el == null) {
return; return;
} }
@ -1376,7 +1407,11 @@ export class Grid {
const count = truncate((height - 1) / (this.rowHeight + 1)) + (RedumCount * 2) + 1; const count = truncate((height - 1) / (this.rowHeight + 1)) + (RedumCount * 2) + 1;
if (force || count !== this._var.rowCount) { if (force || count !== this._var.rowCount) {
this._var.rowCount = count; this._var.rowCount = count;
this.reload(keep); if (typeof callback === 'function') {
callback.call(this);
} else {
this.reload(keep);
}
} }
this._var.bodyClientWidth = body.clientWidth; this._var.bodyClientWidth = body.clientWidth;
} }
@ -1408,13 +1443,14 @@ export class Grid {
if (this.extraRows > 0) { if (this.extraRows > 0) {
length += this.extraRows; length += this.extraRows;
} }
this._var.containerHeight = (length + 1) * (this.rowHeight + 1); this._var.containerHeight = length * (this.rowHeight + 1);
if (!keep) { if (!keep) {
this._var.el.scrollTop = 0; this._var.el.scrollTop = 0;
// this._var.el.scrollLeft = 0; // this._var.el.scrollLeft = 0;
this._var.refs.table.style.top = '0px'; this._var.refs.table.style.top = '0px';
} }
this._var.refs.wrapper.style.height = `${this._var.containerHeight}px`; const headerHeight = this._var.headerHeight || this.rowHeight;
this._var.refs.wrapper.style.height = `${this._var.containerHeight + headerHeight}px`;
this._adjustRows(this._var.refs.body); this._adjustRows(this._var.refs.body);
this.refresh(); this.refresh();
} }
@ -1442,6 +1478,8 @@ export class Grid {
this._changeColumnWidth(i, width); this._changeColumnWidth(i, width);
} }
}); });
} else {
this._var.headerHeight = this._var.refs.table.children[0].offsetHeight;
} }
} }
@ -1825,7 +1863,7 @@ export class Grid {
type ??= GridColumn; type ??= GridColumn;
this._var.colTypes[col.key] = type; this._var.colTypes[col.key] = type;
} }
if (col.width > 0 || typeof type.createCaption === 'function') { if (col.width > 0 || col.shrink || typeof type.createCaption === 'function') {
// col.autoResize = false; // col.autoResize = false;
} else { } else {
this._set(col.key, 'autoResize', true); this._set(col.key, 'autoResize', true);
@ -1847,13 +1885,18 @@ export class Grid {
if (col.sortable !== false) { if (col.sortable !== false) {
col.sortable = true; col.sortable = true;
} }
const w = `${col.width}px`; let style;
const style = { if (col.shrink) {
'width': w, style = { 'text-align': col.align };
'max-width': w, } else {
'min-width': w, const w = `${col.width}px`;
'text-align': col.align style = {
}; 'width': w,
'max-width': w,
'min-width': w,
'text-align': col.align
};
}
this._set(col.key, 'style', style); this._set(col.key, 'style', style);
// element // element
const th = createElement('th', 'column'); const th = createElement('th', 'column');
@ -2015,7 +2058,11 @@ export class Grid {
type ??= GridColumn; type ??= GridColumn;
this._var.colTypes[col.key] = type; this._var.colTypes[col.key] = type;
} }
cell.appendChild(type.create(col)); const element = type.create(col, i, this);
if (typeof col.class === 'string') {
type.setClass(element, col.class);
}
cell.appendChild(element);
} }
} else { } else {
cell.style.display = 'none'; cell.style.display = 'none';
@ -2135,7 +2182,13 @@ export class Grid {
} }
val ??= ''; val ??= '';
// fill // fill
if (typeof col.bgFilter === 'function') { let bg = col.background;
if (bg != null) {
if (typeof bg === 'function') {
bg = col.background(item);
}
cell.style.backgroundColor = bg ?? '';
} else if (typeof col.bgFilter === 'function') {
const bgColor = col.bgFilter(item); const bgColor = col.bgFilter(item);
cell.style.backgroundColor = bgColor ?? ''; cell.style.backgroundColor = bgColor ?? '';
} }
@ -2155,7 +2208,10 @@ export class Grid {
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 => this._onRowChanged(e, i, col, type.getValue(e, col), cell), col, this._var.el, vals) :
type.create(col); type.create(col, i, this);
if (typeof col.class === 'string') {
type.setClass(element, col.class);
}
cell.replaceChildren(element); cell.replaceChildren(element);
} else { } else {
element = cell.children[0]; element = cell.children[0];
@ -2195,7 +2251,17 @@ export class Grid {
widths.flag = true; widths.flag = true;
} }
} }
if (typeof col.styleFilter === 'function') { let style = col.style;
if (style != null) {
if (typeof style === 'function') {
style = col.style(item);
}
if (style != null) {
type.setStyle(element, style);
} else {
element.style.cssText = '';
}
} else if (typeof col.styleFilter === 'function') {
const style = col.styleFilter(item); const style = col.styleFilter(item);
if (style != null) { if (style != null) {
type.setStyle(element, style); type.setStyle(element, style);
@ -2273,6 +2339,7 @@ export class Grid {
} }
} }
} }
this._var.headerHeight = this._var.refs.table.children[0].offsetHeight;
} }
_changingColumnOrder(index, offset, mouse, draggerCellLeft) { _changingColumnOrder(index, offset, mouse, draggerCellLeft) {

View File

@ -22,7 +22,7 @@
], ],
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "node ./vite.build.js && typedoc", "build": "node ./vite.build.js",
"doc": "typedoc", "doc": "typedoc",
"jsdoc": "jsdoc -c jsdoc.json", "jsdoc": "jsdoc -c jsdoc.json",
"jsdoc-date": "jsdoc -c jsdoc-date.json" "jsdoc-date": "jsdoc -c jsdoc-date.json"