change to jsdoc
This commit is contained in:
@ -35,7 +35,7 @@ function indexOfParent(target) {
|
||||
return Array.prototype.indexOf.call(target.parentElement.children, target);
|
||||
}
|
||||
|
||||
const ColumnTypes = {
|
||||
const ColumnTypeDefs = {
|
||||
0: GridColumn,
|
||||
1: GridInputColumn,
|
||||
2: GridDropdownColumn,
|
||||
@ -47,6 +47,246 @@ const ColumnTypes = {
|
||||
|
||||
let r = lang;
|
||||
|
||||
/**
|
||||
* 行数据接口
|
||||
* @typedef {object} GridItem
|
||||
* @property {any} Value - 值
|
||||
* @property {string} DisplayValue - 显示值
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据包装接口
|
||||
* @typedef GridItemWrapper
|
||||
* @property {object} values - 真实数据对象
|
||||
* @property {(GridItem | any)} values.[key]] 数据属性
|
||||
* @property {object} source - 下拉数据源缓存对象
|
||||
* @property {GridSourceItem[]} source.[key]] 数据源
|
||||
*/
|
||||
|
||||
/**
|
||||
* 下拉框数据源接口
|
||||
* @typedef {object} GridSourceItem
|
||||
* @property {string} value - 值
|
||||
* @property {string} text - 显示文本
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据可用性回调函数
|
||||
* @callback GridItemBooleanCallback
|
||||
* @param {GridItem} item - 行数据对象
|
||||
* @returns {boolean} 返回是否可用
|
||||
* @this GridColumnDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据过滤回调函数
|
||||
* @callback GridItemFilterCallback
|
||||
* @param {GridItem} item - 行数据对象
|
||||
* @param {boolean} editing - 是否处于编辑状态
|
||||
* @param {HTMLElement} [body] - Grid 控件的 `<tbody>` 部分
|
||||
* @this GridColumnDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据处理回调函数
|
||||
* @callback GridItemObjectCallback
|
||||
* @param {GridItem} item - 行数据对象
|
||||
* @returns {object} 返回任意对象
|
||||
* @this GridColumnDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据字符串回调函数
|
||||
* @callback GridItemStringCallback
|
||||
* @param {GridItem} item - 行数据对象
|
||||
* @returns {string} 返回字符串
|
||||
* @this GridColumnDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* 列过滤器数据源回调函数
|
||||
* @callback GridColumnFilterSourceCallback
|
||||
* @param {GridColumnDefinition} col - 列定义对象
|
||||
* @returns {GridItem[]} 返回过滤器的数据数组
|
||||
* @this Grid
|
||||
*/
|
||||
|
||||
/**
|
||||
* 行数据排序回调函数
|
||||
* @callback GridItemSortCallback
|
||||
* @param {GridItem} a - 对比行数据1
|
||||
* @param {GridItem} b - 对比行数据2
|
||||
* @returns {number} 返回大小对比结果
|
||||
*/
|
||||
|
||||
/**
|
||||
* 下拉列表数据源回调函数
|
||||
* @callback GridDropdownSourceCallback
|
||||
* @param {GridItem} item - 行数据对象
|
||||
* @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 {object} GridColumnDefinition
|
||||
* @property {string} key - 列关键字,默认以该关键字从行数据中提取单元格值,行数据的关键字属性值里包含 DisplayValue 则优先显示此值
|
||||
* @property {(GridColumnTypeEnum | GridColumn)} [type=Grid.ColumnTypes.Common] - 列的类型,可以为 {@linkcode GridColumn} 的子类,或者内置类型 {@linkcode GridColumnTypeEnum}
|
||||
* @property {string} [caption] - 列标题文本
|
||||
* @property {object} [captionStyle] - 列标题的元素样式
|
||||
* @property {number} [width] - 大于 0 则设置为该宽度,否则根据列内容自动调整列宽
|
||||
* @property {("left" |"center" | "right")} [align=left] 列对齐方式
|
||||
* @property {(boolean | string | GridItemBooleanCallback)} [enabled] - 列是否可用(可编辑),允许以下类型
|
||||
*
|
||||
* * `boolean` 则直接使用该值
|
||||
* * `string` 则以该值为关键字从行数据中取值作为判断条件
|
||||
* * `(item: GridItem) => boolean` 则调用该函数(上下文为列定义对象),以返回值作为判断条件
|
||||
* @property {GridItemFilterCallback} [filter] - 单元格取值采用该函数返回的值
|
||||
* @property {string} [text] - 单元格以该值填充内容,忽略filter与关键字属性
|
||||
* @property {boolean} [visible=true] - 列是否可见
|
||||
* @property {boolean} [resizable=true] - 列是否允许调整宽度
|
||||
* @property {boolean} [sortable=true] - 列是否允许排序
|
||||
* @property {boolean} [orderable=true] - 列是否允许重排顺序
|
||||
* @property {boolean} [allcheck=false] - 列为复选框类型时是否在列头增加全选复选框
|
||||
* @property {object} [css] - 单元格css样式对象(仅在重建行元素时读取)
|
||||
* @property {GridItemObjectCallback} [styleFilter] - 根据返回值填充单元格样式(填充行列数据时读取)
|
||||
* @property {GridItemStringCallback} [bgFilter] - 根据返回值设置单元格背景色
|
||||
* @property {object} [events] - 给单元格元素附加事件(事件函数上下文为数据行对象)
|
||||
* @property {Function} events.[event]] - 事件回调函数
|
||||
* @property {(object | GridItemObjectCallback)} [attrs] - 根据返回值设置单元格元素的附加属性,允许直接设置对象也支持函数返回对象
|
||||
* @property {boolean} [allowFilter=false] - 是否允许进行列头过滤
|
||||
* @property {(GridItem[] | GridColumnFilterSourceCallback)} [filterSource] - 自定义列过滤器的数据源(函数上下文为Grid)
|
||||
* @property {GridItemSortCallback} [sortFilter] - 自定义列排序函数
|
||||
* @property {DropdownOptions} [dropOptions] - 列为下拉列表类型时以该值设置下拉框的参数
|
||||
* @property {(GridSourceItem[] | GridDropdownSourceCallback | Promise<GridSourceItem[]>)} [source] - 列为下拉列表类型时以该值设置下拉列表数据源,支持函数返回,也支持返回异步对象
|
||||
* @property {boolean} [sourceCache=false] - 下拉列表数据源是否缓存结果(即行数据未发生变化时仅从source属性获取一次值)
|
||||
* @property {("fa-light" | "fa-regular" | "fa-solid")} [iconType=fa-light] - 列为图标类型时以该值设置图标样式(函数上下文为列定义对象)
|
||||
* @property {(string | GridItemStringCallback)} [iconClassName] - 列为图标类型时以该值作为单元格元素的额外样式类型(函数上下文为列定义对象)
|
||||
* @property {string} [dateMin] - 列为日期类型时以该值作为最小可选日期值
|
||||
* @property {string} [dateMax] - 列为日期类型时以该值作为最大可选日期值
|
||||
* @property {DateFormatterCallback} [dateValueFormatter] - 列为日期类型时自定义日期格式化函数
|
||||
* @property {(string | GridItemStringCallback)} [tooltip] - 以返回值额外设置单元格的tooltip(函数上下文为列定义对象)
|
||||
* @property {GridColumnCheckedCallback} [onAllChecked] - 列头复选框改变时触发
|
||||
* @property {GridColumnDefinition} onAllChecked.col - 列定义对象
|
||||
* @property {boolean} onAllChecked.flag - 是否选中
|
||||
* @property {GridCellChangedCallback} [onChanged] - 单元格发生变化时触发
|
||||
* @property {GridCellInputEndedCallback} [onInputEnded] - 文本单元格在输入完成时触发的事件
|
||||
* @property {GridColumnFilterOkCallback} [onFilterOk] - 列过滤点击 `OK` 时触发的事件
|
||||
* @property {GridColumnFilteredCallback} [onFiltered] - 列过滤后触发的事件
|
||||
* @property {GridColumnDropExpandedCallback} [onDropExpanded] - 列为下拉框类型时在下拉列表展开时触发的事件
|
||||
*/
|
||||
|
||||
/**
|
||||
* 判断复选框列的回调函数
|
||||
* @callback ColumnTypesEnumIsCheckbox
|
||||
* @param {number} type - 列类型
|
||||
* @returns {boolean} 返回是否为复选框列
|
||||
*/
|
||||
|
||||
/**
|
||||
* 列类型枚举
|
||||
* @enum {number}
|
||||
*/
|
||||
const GridColumnTypeEnum = {
|
||||
/** 0 - 通用列(只读) */
|
||||
Common: 0,
|
||||
/** 1 - 单行文本列 */
|
||||
Input: 1,
|
||||
/** 2 - 下拉选择列 */
|
||||
Dropdown: 2,
|
||||
/** 3 - 复选框列 */
|
||||
Checkbox: 3,
|
||||
/** 4 - 图标列 */
|
||||
Icon: 4,
|
||||
/** 5 - 多行文本列 */
|
||||
Text: 5,
|
||||
/** 6 - 日期选择列 */
|
||||
Date: 6,
|
||||
/**
|
||||
* 判断列是否为复选框列
|
||||
* @type {ColumnTypesEnumIsCheckbox}
|
||||
*/
|
||||
isCheckbox(type) { return type === 3 }
|
||||
};
|
||||
|
||||
/**
|
||||
* 列排序枚举
|
||||
* @enum {number}
|
||||
*/
|
||||
const GridColumnDirection = {
|
||||
/** -1 - 倒序 */
|
||||
Descending: -1,
|
||||
/** 1 - 升序 */
|
||||
Ascending: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* 列排序定义接口
|
||||
* @typedef GridColumnSortDefinition
|
||||
* @property {string} column - 排序列的关键字
|
||||
* @property {("asc" | "desc")} order - 升序或降序
|
||||
*/
|
||||
|
||||
/**
|
||||
* 多语言文本资源回调函数
|
||||
* @callback GridLanguageCallback
|
||||
* @param {string} id - 资源 ID
|
||||
* @param {string} [def] - 默认资源
|
||||
* @returns 返回获取的多语言资源
|
||||
*/
|
||||
|
||||
/**
|
||||
* Grid 控件基础类
|
||||
* @class
|
||||
*/
|
||||
export class Grid {
|
||||
_var = {
|
||||
selectedColumnIndex: -1,
|
||||
@ -74,44 +314,189 @@ export class Grid {
|
||||
// _var.colAttrs = {};
|
||||
// _var.vtable = [];
|
||||
|
||||
/**
|
||||
* 列定义的数组
|
||||
* @type {GridColumnDefinition[]}
|
||||
*/
|
||||
columns = [];
|
||||
/**
|
||||
* 多语言资源对象
|
||||
* @type {object}
|
||||
* @property {string} [all=( All )]
|
||||
* @property {string} [ok=OK]
|
||||
* @property {string} [reset=Reset]
|
||||
* @property {string} [cancel=Cancel]
|
||||
* @property {string} [null=( Null )]
|
||||
* @property {string} [addLevel=Add Level]
|
||||
* @property {string} [deleteLevel=Delete Level]
|
||||
* @property {string} [copyLevel=Copy Level]
|
||||
* @property {string} [asc=Ascending]
|
||||
* @property {string} [desc=Descending]
|
||||
* @property {string} [column=Column]
|
||||
* @property {string} [order=Order]
|
||||
* @property {string} [sort=Sort]
|
||||
* @property {string} [requirePrompt=All sort criteria must have a column specified. Check the selected sort criteria and try again.]
|
||||
* @property {string} [duplicatePrompt={column} is being sorted more than once. Delete the duplicate sort criteria and try again.]
|
||||
*/
|
||||
langs = {};
|
||||
/**
|
||||
* 行数大于等于该值则启用虚模式
|
||||
* @type {number}
|
||||
* @default 100
|
||||
*/
|
||||
virtualCount = 100;
|
||||
/**
|
||||
* 表格行高
|
||||
* @type {number}
|
||||
* @default 36
|
||||
*/
|
||||
rowHeight = 36;
|
||||
/**
|
||||
* 文本行高
|
||||
* @type {number}
|
||||
* @default 24
|
||||
*/
|
||||
lineHeight = 24;
|
||||
/**
|
||||
* 列表底部留出额外的空白行
|
||||
* @type {number}
|
||||
* @default 0
|
||||
*/
|
||||
extraRows = 0;
|
||||
/**
|
||||
* 过滤条件列表的行高
|
||||
* @type {number}
|
||||
* @default 30
|
||||
*/
|
||||
filterRowHeight = 30;
|
||||
/**
|
||||
* 列表高度值,为 0 时列表始终显示全部内容(自增高),为非数字或者小于 0 则根据容器高度来确定虚模式的渲染行数
|
||||
* @type {number | null}
|
||||
*/
|
||||
height;
|
||||
/**
|
||||
* 列表是否为只读
|
||||
* @type {boolean}
|
||||
*/
|
||||
readonly;
|
||||
/**
|
||||
* 是否允许多选
|
||||
* @type {boolean}
|
||||
* @default false
|
||||
*/
|
||||
multiSelect = false;
|
||||
/**
|
||||
* 为 `false` 时只有点击在单元格内才会选中行
|
||||
* @type {boolean}
|
||||
* @default true
|
||||
*/
|
||||
fullrowClick = true;
|
||||
/**
|
||||
* 单元格 tooltip 是否禁用
|
||||
* @type {boolean}
|
||||
* @default false
|
||||
*/
|
||||
tooltipDisabled = false;
|
||||
/**
|
||||
* 列头是否显示
|
||||
* @type {boolean}
|
||||
* @default true
|
||||
*/
|
||||
headerVisible = true;
|
||||
/**
|
||||
* 监听事件的窗口载体
|
||||
* @type {(Window | HTMLElement)}
|
||||
* @default window
|
||||
*/
|
||||
window = global;
|
||||
/**
|
||||
* 排序列的索引
|
||||
* @type {number}
|
||||
* @default -1
|
||||
*/
|
||||
sortIndex = -1;
|
||||
sortDirection = 1;
|
||||
/**
|
||||
* 排序方式,正数升序,负数倒序
|
||||
* @type {GridColumnDirection}
|
||||
* @default GridColumnDirection.Ascending
|
||||
*/
|
||||
sortDirection = GridColumnDirection.Ascending;
|
||||
/**
|
||||
* 排序列数组
|
||||
* @type {GridColumnSortDefinition[]}
|
||||
* @default null
|
||||
*/
|
||||
sortArray = null;
|
||||
|
||||
/**
|
||||
* 即将选中行时触发
|
||||
* @event
|
||||
* @param {number} index - 即将选中的行索引
|
||||
* @param {number} colIndex - 即将选中的列索引
|
||||
* @returns {boolean} 返回 `false`、`null`、`undefined`、`0` 等则取消选中动作
|
||||
*/
|
||||
willSelect;
|
||||
/**
|
||||
* 单元格单击时触发,colIndex 为 -1 则表示点击的是行的空白处
|
||||
* @event
|
||||
* @param {number} index - 点击的行索引
|
||||
* @param {number} colIndex - 点击的列索引
|
||||
* @returns {boolean} 返回 false 则取消事件冒泡
|
||||
*/
|
||||
cellClicked;
|
||||
|
||||
/**
|
||||
* 选中行发生变化时触发的事件
|
||||
* @event
|
||||
* @param {number} index - 选中的行索引
|
||||
*/
|
||||
onSelectedRowChanged;
|
||||
/**
|
||||
* 单元格双击时触发的事件,colIndex 为 -1 则表示点击的是行的空白处
|
||||
* @event
|
||||
* @param {number} index - 双击的行索引
|
||||
* @param {number} colIndex - 双击的列索引
|
||||
*/
|
||||
onCellDblClicked;
|
||||
/**
|
||||
* 行双击时触发的事件
|
||||
* @event
|
||||
* @param {number} index - 双击的行索引
|
||||
*/
|
||||
onRowDblClicked;
|
||||
/**
|
||||
* 列发生变化时触发的事件
|
||||
* @event
|
||||
* @param {("reorder" | "resize" | "sort")} type - 事件类型
|
||||
*
|
||||
* * "reorder" 为发生列重排事件,此时 value 为目标列索引
|
||||
* * "resize" 为发生列宽调整事件,此时 value 为列宽度值
|
||||
* * "sort" 为发生列排序事件,此时 value 为 1(升序)或 -1(倒序)
|
||||
* @param {number} colIndex - 发生变化事件的列索引
|
||||
* @param {number | GridColumnDirection} value - 变化的值
|
||||
*/
|
||||
onColumnChanged;
|
||||
/**
|
||||
* 列滚动时触发的事件
|
||||
* @event
|
||||
* @param {Event} e - 滚动事件对象
|
||||
*/
|
||||
onBodyScrolled;
|
||||
|
||||
static ColumnTypes = {
|
||||
Common: 0,
|
||||
Input: 1,
|
||||
Dropdown: 2,
|
||||
Checkbox: 3,
|
||||
Icon: 4,
|
||||
Text: 5,
|
||||
Date: 6,
|
||||
isCheckbox(type) { return type === 3 }
|
||||
};
|
||||
/**
|
||||
* 列类型枚举
|
||||
* @readonly
|
||||
* @type {GridColumnTypeEnum}
|
||||
*/
|
||||
static get ColumnTypes() { return GridColumnTypeEnum }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {(string | HTMLElement)} container Grid 控件所在的父容器,可以是 string 表示选择器,也可以是 HTMLElement 对象
|
||||
* Grid 控件构造函数
|
||||
* _构造时可以不进行赋值,但是调用 init 函数时则必须进行赋值_
|
||||
* @param {GridLanguageCallback} [getText] 获取多语言文本的函数代理
|
||||
*/
|
||||
constructor(container, getText) {
|
||||
this._var.parent = typeof container === 'string' ? document.querySelector(container) : container;
|
||||
if (typeof getText === 'function') {
|
||||
@ -123,21 +508,31 @@ export class Grid {
|
||||
reset: r('reset', 'Reset'),
|
||||
cancel: r('cancel', 'Cancel'),
|
||||
null: r('null', '( Null )'),
|
||||
addLevel: r('', 'Add level'),
|
||||
deleteLevel: r('', 'Delete level'),
|
||||
copyLevel: r('', 'Copy level'),
|
||||
asc: r('', 'Ascending'),
|
||||
desc: r('', 'Descending'),
|
||||
column: r('', 'Column'),
|
||||
order: r('', 'Order'),
|
||||
sort: r('', 'Sort'),
|
||||
requirePrompt: r('', 'Column required.'),
|
||||
duplicatePrompt: r('', 'Column duplicated: "{column}"')
|
||||
addLevel: r('addLevel', 'Add level'),
|
||||
deleteLevel: r('deleteLevel', 'Delete level'),
|
||||
copyLevel: r('copyLevel', 'Copy level'),
|
||||
asc: r('asc', 'Ascending'),
|
||||
desc: r('desc', 'Descending'),
|
||||
column: r('column', 'Column'),
|
||||
order: r('order', 'Order'),
|
||||
sort: r('sort', 'Sort'),
|
||||
requirePrompt: r('requirePrompt', 'All sort criteria must have a column specified. Check the selected sort criteria and try again.'),
|
||||
duplicatePrompt: r('duplicatePrompt', '{column} is being sorted more than once. Delete the duplicate sort criteria and try again.')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Grid 的页面元素
|
||||
* @readonly
|
||||
* @type {HTMLDivElement}
|
||||
*/
|
||||
get element() { return this._var.el }
|
||||
|
||||
/**
|
||||
* 获取当前 Grid 是否已发生改变
|
||||
* @readonly
|
||||
* @type {boolean}
|
||||
*/
|
||||
get changed() {
|
||||
const source = this._var.source;
|
||||
if (source == null) {
|
||||
@ -146,8 +541,17 @@ export class Grid {
|
||||
return source.find(r => r.__changed) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回所有数据的数据(未过滤)
|
||||
* @readonly
|
||||
* @type {GridItem[]}
|
||||
*/
|
||||
get allSource() { return this._var.source?.map(s => s.values) }
|
||||
|
||||
/**
|
||||
* 获取已过滤的数据数组,或者设置数据并刷新列表
|
||||
* @type {GridItem[]}
|
||||
*/
|
||||
get source() { return this._var.currentSource?.map(s => s.values) }
|
||||
set source(list) {
|
||||
if (this._var.el == null) {
|
||||
@ -166,6 +570,11 @@ export class Grid {
|
||||
this._refreshSource(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置单行数据
|
||||
* @param {number} index - 行索引
|
||||
* @param {GridItem} item - 待设置的行数据对象
|
||||
*/
|
||||
setItem(index, item) {
|
||||
if (this._var.currentSource == null) {
|
||||
throw new Error('no source');
|
||||
@ -174,9 +583,21 @@ export class Grid {
|
||||
// clear dropdown source cache
|
||||
delete it.source;
|
||||
it.values = item;
|
||||
this.refresh();
|
||||
if (this.sortIndex >= 0) {
|
||||
this.sortColumn();
|
||||
} else if (this.sortArray?.length > 0) {
|
||||
this.sort();
|
||||
} else {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行数据
|
||||
* @param {GridItem} item - 待添加的行数据值
|
||||
* @param {number} [index] - 待添加的行索引
|
||||
* @returns {GridItem} 返回已添加的行数据
|
||||
*/
|
||||
addItem(item, index) {
|
||||
if (this._var.currentSource == null) {
|
||||
throw new Error('no source');
|
||||
@ -199,10 +620,22 @@ export class Grid {
|
||||
this._var.source.push(newIt);
|
||||
}
|
||||
}
|
||||
this.reload();
|
||||
if (this.sortIndex >= 0) {
|
||||
this.sortColumn();
|
||||
} else if (this.sortArray?.length > 0) {
|
||||
this.sort();
|
||||
} else {
|
||||
this.reload();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加行数据
|
||||
* @param {GridItem[]} array - 待添加的行数据数组
|
||||
* @param {number} [index] - 待添加的行索引
|
||||
* @returns {GridItem[]} 返回已添加的行数据数组
|
||||
*/
|
||||
addItems(array, index) {
|
||||
if (this._var.currentSource == null) {
|
||||
throw new Error('no source');
|
||||
@ -230,10 +663,21 @@ export class Grid {
|
||||
this._var.source.push(...items);
|
||||
}
|
||||
}
|
||||
this.reload();
|
||||
if (this.sortIndex >= 0) {
|
||||
this.sortColumn();
|
||||
} else if (this.sortArray?.length > 0) {
|
||||
this.sort();
|
||||
} else {
|
||||
this.reload();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除行数据
|
||||
* @param {number} index - 待删除的行索引
|
||||
* @returns {GridItem} 返回已删除的行数据
|
||||
*/
|
||||
removeItem(index) {
|
||||
if (this._var.currentSource == null) {
|
||||
throw new Error('no source');
|
||||
@ -257,6 +701,11 @@ export class Grid {
|
||||
return it.values;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除行数据
|
||||
* @param {number[]} [indexes] - 待删除的行索引数组,未传值时删除所有行
|
||||
* @returns {GridItem[]} 返回已删除的行数据数组
|
||||
*/
|
||||
removeItems(indexes) {
|
||||
if (this._var.currentSource == null) {
|
||||
throw new Error('no source');
|
||||
@ -334,8 +783,18 @@ export class Grid {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前是否为虚模式状态
|
||||
* @readonly
|
||||
* @type {boolean}
|
||||
*/
|
||||
get virtual() { return this._var.currentSource?.length > this.virtualCount }
|
||||
|
||||
/**
|
||||
* 获取当前排序的列关键字,为 null 则当前无排序列
|
||||
* @readonly
|
||||
* @type {string | null}
|
||||
*/
|
||||
get sortKey() {
|
||||
if (this.columns == null) {
|
||||
return null;
|
||||
@ -348,6 +807,10 @@ export class Grid {
|
||||
return Array.prototype.slice.call(this._var.refs.body.children);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或设置当前选中的行索引的数组,设置后会刷新列表
|
||||
* @type {number[]}
|
||||
*/
|
||||
get selectedIndexes() { return this._var.selectedIndexes }
|
||||
set selectedIndexes(indexes) {
|
||||
const startIndex = this._var.startIndex;
|
||||
@ -368,8 +831,17 @@ export class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选中行的索引,为 -1 则当前没有选中行
|
||||
* @readonly
|
||||
* @type {number}
|
||||
*/
|
||||
get selectedIndex() { return (this._var.selectedIndexes && this._var.selectedIndexes[0]) ?? -1 }
|
||||
|
||||
/**
|
||||
* 获取或设置 Grid 当前的加载状态
|
||||
* @type {boolean}
|
||||
*/
|
||||
get loading() { return this._var.refs.loading?.style?.visibility === 'visible' }
|
||||
set loading(flag) {
|
||||
if (this._var.refs.loading == null) {
|
||||
@ -384,6 +856,10 @@ export class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或设置 Grid 当前滚动的偏移量
|
||||
* @type {number}
|
||||
*/
|
||||
get scrollTop() { return this._var.el?.scrollTop; }
|
||||
set scrollTop(top) {
|
||||
if (this._var.el == null) {
|
||||
@ -393,6 +869,10 @@ export class Grid {
|
||||
this.reload(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Grid控件
|
||||
* @param {HTMLElement} [container=.ctor#container] - 父容器元素,若未传值则采用构造方法中传入的父容器元素
|
||||
*/
|
||||
init(container = this._var.parent) {
|
||||
this._var.el = null;
|
||||
this._var.refs = {};
|
||||
@ -488,15 +968,28 @@ export class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据列表,该方法为 [source]{@linkcode Grid#source} 属性的语法糖
|
||||
* @param {GridItem[]} source - 待设置的数据列表
|
||||
*/
|
||||
setData(source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动到指定行的位置
|
||||
* @param {number} index - 待滚动至的行索引
|
||||
*/
|
||||
scrollToIndex(index) {
|
||||
const top = this._scrollToTop(index * (this.rowHeight + 1), true);
|
||||
this._var.el.scrollTop = top;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整 Grid 元素的大小,一般需要在宽度变化时(如页面大小发生变化时)调用
|
||||
* @param {boolean} [force] - 是否强制 [reload]{@linkcode Grid#reload},默认只有待渲染的行数发生变化时才会调用
|
||||
* @param {boolean} [keep] - 是否保持当前滚动位置
|
||||
*/
|
||||
resize(force, keep) {
|
||||
if (this._var.rendering || this._var.el == null) {
|
||||
return;
|
||||
@ -518,6 +1011,10 @@ export class Grid {
|
||||
this._var.bodyClientWidth = body.clientWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算需要渲染的行,并载入元素,一般需要在高度变化时调用
|
||||
* @param {boolean} [keep] - 是否保持当前滚动位置
|
||||
*/
|
||||
reload(keep) {
|
||||
const filtered = this.columns.some(c => c.filterValues != null);
|
||||
if ((filtered ^ this._var.colAttrs.__filtered) === 1) {
|
||||
@ -552,6 +1049,9 @@ export class Grid {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新填充Grid单元格数据
|
||||
*/
|
||||
refresh() {
|
||||
if (this._var.refs.body == null) {
|
||||
throw new Error('body has not been created.');
|
||||
@ -575,6 +1075,9 @@ export class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把所有行重置为未修改的状态
|
||||
*/
|
||||
resetChange() {
|
||||
if (this._var.source == null) {
|
||||
return;
|
||||
@ -608,6 +1111,10 @@ export class Grid {
|
||||
return (a, b) => col.sortFilter(a.values, b.values) * direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前排序字段进行列排序
|
||||
* @param {boolean} [reload] - 为 `true` 则在列排序后调用 [reload]{@linkcode Grid#reload} 方法
|
||||
*/
|
||||
sortColumn(reload) {
|
||||
const index = this.sortIndex;
|
||||
const col = this.columns[index];
|
||||
@ -642,6 +1149,10 @@ export class Grid {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前排序列数组进行多列排序
|
||||
* @param {boolean} [reload] - 为 `true` 则在多列排序后调用 [reload]{@linkcode Grid#reload} 方法
|
||||
*/
|
||||
sort(reload) {
|
||||
const sortArray = this.sortArray;
|
||||
if (sortArray == null || sortArray.length === 0) {
|
||||
@ -689,11 +1200,17 @@ export class Grid {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除列头复选框的选中状态
|
||||
*/
|
||||
clearHeaderCheckbox() {
|
||||
const boxes = this._var.refs.header.querySelectorAll('.ui-check-wrapper>input');
|
||||
boxes.forEach(box => box.checked = false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示多列排序设置面板
|
||||
*/
|
||||
showSortPanel() {
|
||||
const content = createElement('div', 'ui-sort-panel-content');
|
||||
const buttonWrapper = createElement('div', 'ui-sort-panel-buttons');
|
||||
@ -811,7 +1328,7 @@ export class Grid {
|
||||
key: 'column',
|
||||
caption: this.langs.column,
|
||||
width: 270,
|
||||
type: Grid.ColumnTypes.Dropdown,
|
||||
type: GridColumnTypeEnum.Dropdown,
|
||||
dropOptions: {
|
||||
textKey: 'caption',
|
||||
valueKey: 'key'
|
||||
@ -824,7 +1341,7 @@ export class Grid {
|
||||
key: 'order',
|
||||
caption: this.langs.order,
|
||||
width: 150,
|
||||
type: Grid.ColumnTypes.Dropdown,
|
||||
type: GridColumnTypeEnum.Dropdown,
|
||||
source: [
|
||||
{ value: 'asc', text: this.langs.asc },
|
||||
{ value: 'desc', text: this.langs.desc }
|
||||
@ -915,13 +1432,13 @@ export class Grid {
|
||||
continue;
|
||||
}
|
||||
// style
|
||||
const isCheckbox = Grid.ColumnTypes.isCheckbox(col.type);
|
||||
const isCheckbox = GridColumnTypeEnum.isCheckbox(col.type);
|
||||
let type = this._var.colTypes[col.key];
|
||||
if (type == null) {
|
||||
if (isNaN(col.type)) {
|
||||
type = col.type;
|
||||
} else {
|
||||
type = ColumnTypes[col.type];
|
||||
type = ColumnTypeDefs[col.type];
|
||||
}
|
||||
type ??= GridColumn;
|
||||
this._var.colTypes[col.key] = type;
|
||||
@ -1097,7 +1614,7 @@ export class Grid {
|
||||
if (style !== '') {
|
||||
cell.style.cssText = style;
|
||||
}
|
||||
if (Grid.ColumnTypes.isCheckbox(col.type)) {
|
||||
if (GridColumnTypeEnum.isCheckbox(col.type)) {
|
||||
cell.appendChild(GridCheckboxColumn.createEdit(e => this._onRowChanged(e, exists + i, col, e.target.checked, cell)));
|
||||
// this._var.colTypes[col.key] = GridCheckboxColumn;
|
||||
} else {
|
||||
@ -1106,7 +1623,7 @@ export class Grid {
|
||||
if (isNaN(col.type)) {
|
||||
type = col.type;
|
||||
} else {
|
||||
type = ColumnTypes[col.type];
|
||||
type = ColumnTypeDefs[col.type];
|
||||
}
|
||||
type ??= GridColumn;
|
||||
this._var.colTypes[col.key] = type;
|
||||
@ -1184,7 +1701,7 @@ export class Grid {
|
||||
const bgColor = col.bgFilter(item);
|
||||
cell.style.backgroundColor = bgColor ?? '';
|
||||
}
|
||||
const isCheckbox = Grid.ColumnTypes.isCheckbox(col.type);
|
||||
const isCheckbox = GridColumnTypeEnum.isCheckbox(col.type);
|
||||
const type = isCheckbox ? GridCheckboxColumn : this._var.colTypes[col.key] ?? GridColumn;
|
||||
let element;
|
||||
if (!isCheckbox && typeof type.createEdit === 'function') {
|
||||
|
Reference in New Issue
Block a user