zui
Version:
一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。
1,773 lines (1,481 loc) • 63.1 kB
Markdown
# 数据表格②
数据表格2(在下文中简称为数据表格)是一个全新的数据表格视图组件,相比较[数据表格](#view/datatable)提供更强大的功能,支持远程数据显示、排序、搜索以及海量数据显示。
## 综合示例
### 引入资源
数据表格2为独立组件,你需要从本地或 CDN 单独引入 lib 目录下的资源:
```html
<link href="lib/datagrid/zui.datagrid.min.css" rel="stylesheet">
<script src="lib/datagrid/zui.datagrid.min.js"></script>
```
<div class="example">
<div id="datagridExample" class="datagrid datagrid-borderless">
<header class="clearfix">
<div class="input-control search-box search-box-circle has-icon-left has-icon-right pull-right" id="searchboxExample1">
<input id="inputSearchExample1" type="search" class="form-control search-input" placeholder="搜索">
<label for="inputSearchExample1" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a href="#" class="input-control-icon-right search-clear-btn"><i class="icon icon-remove"></i></a>
</div>
<h3>数据表格功能综合演示</h3>
</header>
<div class="datagrid-container"></div>
<div class="pager"></div>
</div>
</div>
```html
<div id="datagridExample" class="datagrid"></div>
```
```js
$('#datagridExample').datagrid({
dataSource: [...],
...
});
```
当所有选项都可以通过 `data-*` 属性设置时,则可以通过 `data-ride="datagrid"` 来在页面加载后自动进行初始化。
```html
<div id="datagridExample" class="datagrid" data-ride="datagrid"></div>
```
## 数据源
数据源是用于定义数据网格数据的格式和获取方式。数据源通过 `dataSource` 选项进行配置。`dataSource` 选项值为一个对象,可用的属性包括:
* `cols`:一个列定义对象数组,用于定义数据源上要显示的列,数组内对象的顺序即是列排列显示的顺序,列对象定义参见下文;
* `array`:可选,当使用静态数组定义数据时,使用此属性来定义所有数据;
* `remote`:可选,当从远程加载数据时,使用此属性来指定远程请求的地址,或者使用此属性指定一个函数用于动态生成每次请求所使用的 ajax 参数对象;
* `remoteConverter`:可选,当从远程加载数据时,使用此属性来转换远程内容,确保远程数据符合数据表格所要求的格式,如果远程数据已经通过 JSON 返回了符合要求的数据,则无需使用此属性进行转换操作;
* `getByIndex`:可选,当使用动态数据时,使用此属性指定一个函数用于动态返回数据项目;
* `cache`: 如果设置为 `true`,则启用数据查询缓存,如果设置为 `false`,则不启用数据查询缓存,默认为 `true`;
* `cacheSize`: 设置启用数据查询缓存时最大缓存数量,默认为 `1`。
### 数据项定义
数据项使用一个简单的 JavaScript 对象来表示。数据项对象中应该包含列定义(需要在界面上显示的列)中的所有属性,并且需要包含一个 `id` 属性用于行编号,如果没有指定 `id` 属性,则使用行序号作为行编号。
### 数据源列定义
数据表格上要显示的列通过列定义数组来设置。一个列定义对象数组,用于定义数据源上要显示的列,数组内对象的顺序即是列排列显示的顺序。每一个列定义对象包含如下属性:
* `name`: 列上要显示的数据属性名称;
* `label`: 可选,列标题文本,如果不定义此属性则使用 `name` 属性作为标题文本;
* `html`: 默认为 `false`,如果设置为 `true`,则在渲染列时将内容作为 html 源码更新到页面上;
* `style`: 可选,在该列上所以单元格元素上要添加的样式(使用 jQuery CSS 样式定义对象规则);
* `width`: 列宽度,如果设置为小于 `1` 的浮点数,则将此值用于自适应时计算最终宽度的权值;
* `minWidth`:列最小宽度,当启用自适应时,最终计算的宽度不会小于该值;
* `className`: 可选,在该列上所有单元格元素上要添加的类名;
* `checkbox`: 默认为 `false`,如果设置为 `true`,则在此列单元格内显示勾选框;
* `valueType`:该列值类型,默认 `string`;
* `valueOperator`: 可选,该列上的值转换器;
* `sort`:是否为当前列开启排序功能,默认为 `true`,如果设置为 `false`,即便 `sortable` 选项设置为 `true` 也无法使用该列进行排序;
* `sortFunc`:可选,当使用该列排序时的比较函数。
```js
$('#myDataGrid').datagrid({
dataSource: {
cols:[
{name: 'time', label: '时间', width: 132},
{name: 'hero', label: '英雄', width: 134},
{name: 'action', label: '动作', width: 109},
{name: 'target', label: '目标', width: 109},
{name: 'desc', label: '描述', width: 287}
],
// ... Data source 其他属性
},
// ... 其他初始化选项
});
```
### 静态数据源
定义数据源最简单的方式是给定一个静态对象数组。
```js
$('#myDataGrid').datagrid({
dataSource: {
cols:[
{name: 'time', label: '时间', width: 132},
{name: 'hera', label: '英雄', width: 134},
{name: 'action', label: '动作', width: 109},
{name: 'target', label: '目标', width: 109},
{name: 'desc', label: '描述', width: 287}
],
array:[
{time: '00:11:12', hero:'幻影刺客', action: '击杀', target: '斧王', desc: '幻影刺客击杀了斧王。'},
{time: '00:13:22', hero:'幻影刺客', action: '购买了', target: '隐刀', desc: '幻影刺客购买了隐刀。'},
{time: '00:19:36', hero:'斧王', action: '购买了', target: '黑皇杖', desc: '斧王购买了黑皇杖。'},
{time: '00:21:43', hero:'力丸', action: '购买了', target: '隐刀', desc: '力丸购买了隐刀。'}
]
},
// ... 其他初始化选项
});
```
### 远程数据源
有时需要从远程获取数据,数据表格支持通过 Ajax 获取远程数据作为数据源,而且使用起来非常灵活。通过数据源对象的 `remote` 和 `remoteConverter` 属性来配置远程数据源。
#### 远程请求参数
远程请求参数通过 `remote` 属性来配置。如果是静态地址,则直接使用远程连接地址作为 `remote` 配置的值,如果要根据当前请求的页码和搜索文本等信息进行动态请求配置,则可以将 `remote` 配置的值指定为一个回调函数来动态返回配置。`remote` 配置回调函数参数定义如下:
* `params`: 请求的参数信息对象;
* `datagrid`: 数据网格实例对象。
其中 `params` 对象包含如下属性:
* `page`: 当前显示的页码;
* `recPerPage`: 当前设定每页显示的数据个数;
* `search`: 当前用于检索数据的文本;
* `sortBy`: 当前排序依据的列名;
* `order `: 当前排序的顺序,包括顺序(`'asc'`)和倒序(`'desc'`)。
远程请求参数对象可以使用 [jQuery.ajax](https://github.com/easysoft/zui/commits/master) 方法接受的所有选项。
#### 远程数据格式
远程数据必须返回一个 JSON 格式的对象,此对象包含如下属性:
```js
// 原创数据对象
{
// 数据请求结果(必须),当值为 'succes'、'ok' 或 200 时则是为请求成功
"result": "success",
// 远程数据内容(必须)
"data": [
// ... 原创数据对象数组
],
// 用户界面提示消息,当请求结果失败时,可以使用此属性返回文本显示在用户界面上
"message": "",
// 远程数据的分页信息对象(必须),其中
"pager": {
"page": 1, // 当前数据对应的页码
"recTotal": 1001, // 总的数据数目
"recPerPage": 10, // 每页数据数目
}
}
```
当远程请求返回的内容不符合上面的格式时,则需要使用 `remoteConverter` 指定一个回调函数来将远程数据转换为符合要求的格式。`remoteConverter` 回调函数包含如下参数:
* `responseData`:远程请求返回的文本内容;
* `textStatus`:原创请求状态;
* `jqXHR`:jQuery 的 xhr 对象;
* `datagrid`:数据网格实例对象。
<div class="example">
<div id="remoteDataGridExample" class="datagrid"></div>
</div>
```html
<div id="remoteDataGridExample" class="datagrid"></div>
```
```js
$('#remoteDataGridExample').datagrid({
dataSource: {
cols:[
{name: 'time', label: '时间', width: 132},
{name: 'hera', label: '英雄', width: 134},
{name: 'action', label: '动作', width: 109},
{name: 'target', label: '目标', width: 109},
{name: 'desc', label: '描述', width: 287}
],
remote: function(params) {
return {
// 原创请求地址
url: 'docs/partial/remote-data.json',
// 请求类型
type: 'GET',
// 数据类型
dataType: 'json'
};
}
}
});
```
### 动态数据
动态数据允许使用一个函数来生成数据,数据只在需要显示的时候获取。通过这种方式,可以实现上亿的海量数据显示。
要启用动态数据源,只需要为数据源对象(`dataSource` 选项)的 `getByIndex` 属性设置一个回调函数,在该回调函数中返回对应索引的对象即可。该回调函数参数定义如下:
* `index`:要获取的数据行索引;
* `params`:数据检索参数。
其中 `params` 对象包含如下属性:
* `page`: 当前显示的页码;
* `recPerPage`: 当前设定每页显示的数据个数;
* `search`: 当前用于检索数据的文本;
* `sortBy`: 当前排序依据的列名;
* `order `: 当前排序的顺序,包括顺序(`'asc'`)和倒序(`'desc'`)。
<div class="alert alert-warning">
<h4>动态数据源性能提示</h4>
<p>当使用动态数据源时,如果一次性展示的数据比较多,受限于计算机性能,应该关闭排序、搜索、行选中等操作,否则可能导致界面无响应。</p>
</div>
<div class="alert alert-primary">
<h4>动态数据源使用限制</h4>
<p>当使用动态数据源时,不支持分页功能。</p>
</div>
<div class="example">
<div id="dynamicDataGridExample" class="datagrid">
<header>
<h1>动态数据</h1>
<p class="small">使用动态数据源实现上亿的海量数据展示。</p>
</header>
</div>
</div>
```html
<div id="dynamicDataGridExample" class="datagrid"></div>
```
```js
$('#dynamicDataGridExample').datagrid({
dataSource: {
getByIndex: function(index, param) {
return {
// ...
}
}
},
checkable: false, // 禁用勾选
sortable: false, // 禁用排序
});
```
### 使用原生表格初始化
与旧版本数据表格一致,数据表格2仍然支持直接使用一个原生的数据表格进行初始化。
<div class="example">
<table class="table table-bordered" id="tableDataGridExample">
<thead>
<tr>
<th>时间</th>
<th>英雄</th>
<th>动作</th>
<th>目标</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>00:11:12</td>
<td>幻影刺客</td>
<td>击杀</td>
<td>斧王</td>
<td>幻影刺客击杀了斧王。</td>
</tr>
<tr>
<td>00:13:22</td>
<td>幻影刺客</td>
<td>购买了</td>
<td>隐刀</td>
<td>幻影刺客购买了隐刀。</td>
</tr>
<tr>
<td>00:19:36</td>
<td>斧王</td>
<td>购买了</td>
<td>黑皇杖</td>
<td>斧王购买了黑皇杖。</td>
</tr>
<tr>
<td>00:21:43</td>
<td>力丸</td>
<td>购买了</td>
<td>隐刀</td>
<td>力丸购买了隐刀。</td>
</tr>
</tbody>
</table>
</div>
```html
<table class="table table-bordered" id="tableDataGridExample">
<thead>
<tr>
<th>时间</th>
<th>英雄</th>
<th>动作</th>
<th>目标</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>00:11:12</td>
<td>幻影刺客</td>
<td>击杀</td>
<td>斧王</td>
<td>幻影刺客击杀了斧王。</td>
</tr>
...
</tbody>
</table>
```
```js
$('#tableDataGridExample').datagrid();
```
## 固定行和列
数据表格支持将行和列固定在表格的一侧,当视图滚动时,固定的行和列仍然保持原来的位置。固定行和列功能通过 `states` 选项进行设置,为 `states` 设置如下属性来启用该功能:
* `fixedLeftUntil`:左侧固定列索引的终止值,当列索引小于或等于该值时则将列固定在表格左侧,默认为 `0`(即固定左侧行编号所在列);
* `fixedRightFrom`: 右侧固定列索引的起始值,当列索引大于或等于该值时则将列固定在表格右侧,默认为 `-1`(不在右侧固定列);
* `fixedTopUntil`: 顶部固定列索引的终止值,当列索引小于或等于该值时则将列固定在表格上方,默认为 `0`(即固定上方标题所在列);
* `fixedBottomFrom`: 底部固定列索引的起始值,当列索引大于或等于该值时则将列固定在表格下方,默认为 `-1`(不在下方固定列)。
<div class="example">
<div id="datagridFixedExample" class="datagrid">
<header class="clearfix">
<h3>数据表格固定行和列演示 <small>行和列分别可以固定在表格上、下、左、右四个方向</small></h3>
</header>
<div class="datagrid-container"></div>
</div>
</div>
```html
<div id="datagridFixedExample" class="datagrid"></div>
```
```js
$('#datagridFixedExample').datagrid({
dataSource: {...}
states: {
pager: {page: 1, recPerPage: 100},
fixedLeftUntil: 0, // 固定左侧第一列
fixedRightFrom: 12, // 从第12列开始固定到右侧
fixedTopUntil: 0, // 固定顶部第一行(标题行)
fixedBottomFrom: 100, // 从第100行(在此例中是最后一行)开始固定到底部
}
});
```
## 排序
数据表格支持按照任意列进行排序,并且可以自定义排序比较函数。要启用排序功能需要将 `sortable` 选项设置为 `true`。当启用排序功能后,标题行(第一行)上的单元格会显示排序指示图标,用户可以点击标题行上的单元格按照所在列进行排序,排序方式会在每次点击时进行顺序切换,切换顺序为升序排序、降序排序、不排序。如果需要禁用根据某些列排序,则可以在列定义中将 `sort` 属性设置为 `false`。
默认排序算法使用 JavaScript 内置的默认比较算法,如果需要自定义排序函数,可以通过 `sortFunc` 选项设置一个回调函数,该回调函数参数定义如下:
* `value1`:第一个要比较的值,相当于 `item1[sortBy]`;
* `value2`:第二个要比较的值,相当于 `item2[sortBy]`;
* `item1`:第一个要比较的数据条目;
* `item2`:第二个要比较的数据条目;
* `sortBy`:当前用于排序的列名;
* `datagrid`:当前数据表格实例对象。
当第一个值大于第二个值时,排序函数应该返回大于 `0` 的数值,当第一个值小于第二个值时,排序函数应该返回小于 `0` 的值,如果相等则返回 `0`。
如果仅仅需要为单独的列应用自定义排序函数,则可以在列定义中使用 `sortFunc` 属性设置该列的排序函数,列排序函数参数定义及返回值约定与选项 `sortFunc` 一致。
<div class="alert alert-warning">
<h4>排序的限制</h4>
<p>内置的完整排序功能仅支持本地静态数据源的排序,如果是远程数据源,会将排序参数发送给远端服务器,需要在服务器进行排序返回排序后的数据;动态数据源的排序也需要自己进行处理,可以根据回调函数参数应用排序规则。</p>
</div>
<div class="example">
<div id="datagridSortExample" class="datagrid">
<header class="clearfix">
<h3>数据表格排序功能演示 <small>点击表头进行排序</small></h3>
</header>
<div class="datagrid-container"></div>
</div>
</div>
```html
<div id="datagridSortExample" class="datagrid"></div>
```
```js
$('#datagridSortExample').datagrid({
dataSource: {...},
sortable: true
});
```
要手动操作排序,可以使用数据表格的实例方法 `sortBy(sortBy, order)`,该方法参数定义如下:
* `sortBy`:当前用于排序的列名;
* `order`:排序顺序,可选值包括 `asc`(升序),`desc`(降序)。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridSortExample').data('zui.datagrid');
// 按照 `name` 列降序排序
myDataGrid.sortBy('name', 'desc');
```
可以通过选项 `states` 上的如下属性设置初始状态下的排序规则:
* `sortBy`:当前用于排序的列名;
* `order`:排序顺序,可选值包括 `asc`(升序,默认),`desc`(降序)。
## 分页
数据表格支持对数据进行分页,支持静态数据源和远程数据源分页操作,并且可以结合[分页器插件](#javascript/pagerjs)一起使用。要启用分页功能,需要为 `states` 选项设置 `pager` 属性。`pager` 属性为一个对象,包含如下属性:
* `page`:当前页码,默认为`0`(不启用分页)
* `recPerPage`: 每页记录数目,默认为 `10`。
分页可以与[分页器插件](#javascript/pagerjs)一起使用,在 `.datagrid` 元素内包含 `.pager` 元素即可自动绑定分页器组件。
<div class="example">
<div id="datagridPageExample" class="datagrid">
<header class="clearfix">
<h3>数据表格分页功能演示</h3>
</header>
<div class="datagrid-container"></div>
<div class="pager"></div>
</div>
</div>
```html
<div id="datagridPageExample" class="datagrid">
<div class="datagrid-container"></div>
<div class="pager"></div>
</div>
```
```js
$('#datagridPageExample').datagrid({
dataSource: {...},
states: {
pager: {page: 1, recPerPage: 20}
}
});
```
要手动操作分页,可以使用数据表格的实例方法 `gotoPage(page)`,方法参数定义如下:
* `page`:要切换的页码。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridPageExample').data('zui.datagrid');
// 到第二页
myDataGrid.gotoPage(2);
```
<div class="alert alert-primary">
<h4>不再需要滚动</h4>
<p>当启用分页时,可以通过将 `height` 选项设置为特殊值 `'page'`,从而实现自动调整数据表格高度为当前页所有行的高度,实现没有垂直滚动条的情况下显示当前页的所以数据。</p>
</div>
## 搜索
数据表格支持对静态数据源和原创数据源数据进行检索。当使用远程数据源时,搜索是在服务器端进行的,服务器应该根据搜索字符串参数筛选数据;如果是静态数据,搜索是在浏览器进行的,默认的搜索策略非常到位,允许搜索字符串通过空格包含多个关键字,并且自动根据批评程序进行排序,批评程度更高的会显示在前面(搜索结果自动排序仅当用户没有进行排序时有效)。
当对静态数据源进行浏览器端搜索时,可以通过 `searchFunc` 选项指定一个搜索回调函数来自定义如何筛选数据,该函数参数定义如下:
* `item`:当前检测是否符合条件的数据条目对象;
* `searchKeyArr`:当前搜索关键词数组;
* `index`:当前条目在数据源中的索引;
* `params`:其他检索条件;
* `datagrid`:当前数据表格实例对象。
其中 `params` 参数为一个对象,包含如下属性:
* `page`: 当前显示的页码;
* `recPerPage`: 当前设定每页显示的数据个数;
* `search`: 当前用于检索数据的文本;
* `sortBy`: 当前排序依据的列名;
* `order `: 当前排序的顺序,包括顺序(`'asc'`)和倒序(`'desc'`)。
在 `.datagrid` 元素内包含一个[搜索框组件](#javascript/searchbox),数据表格会自动监听搜索框变更事件并自动更新结果。
<div class="example">
<div id="datagridSearchExample" class="datagrid">
<div class="input-control search-box search-box-circle has-icon-left has-icon-right" id="searchboxExample2" style="margin-bottom: 10px; max-width: 300px">
<input id="inputSearchExample2" type="search" class="form-control search-input" placeholder="搜索">
<label for="inputSearchExample2" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a href="#" class="input-control-icon-right search-clear-btn"><i class="icon icon-remove"></i></a>
</div>
<div class="datagrid-container"></div>
</div>
</div>
```html
<div id="datagridSearchExample" class="datagrid">
<div class="input-control search-box search-box-circle has-icon-left has-icon-right" id="searchboxExample2" style="margin-bottom: 10px; max-width: 300px">
<input id="inputSearchExample2" type="search" class="form-control search-input" placeholder="搜索">
<label for="inputSearchExample2" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a href="#" class="input-control-icon-right search-clear-btn"><i class="icon icon-remove"></i></a>
</div>
<div class="datagrid-container"></div>
</div>
```
```js
$('#datagridSearchExample').datagrid({
// ...
});
```
可以使用数据表格的实例方法 `search(searchStr)` 手动设置搜索关键字,方法参数定义如下:
* `searchStr`:用于搜索的关键字字符串,多个关键字使用空格连接。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridPageExample').data('zui.datagrid');
// 搜索同时包含 '数据' 和 '表格' 两个关键字的条目
myDataGrid.search('数据 表格');
```
可以通过选项 `states` 上的 `search` 属性设置初始状态下搜索关键字字符串。
## 行选择
数据表格允许用户通过点击行或者在界面上拖拽来选定并标记行。要启用行选择功能,需要将 `checkable` 设置为 `true`。如果启用了行选中,并且页面已导入[拖拽选取插件](#javascript/selectable),则允许用户在界面上进行拖拽框选多行,禁用此功能,可以将 `selectable` 设置为 `false`。`selectable` 还可以接受一个对象作为拖拽选取插件初始化参数,用于自定义拖拽选取交互方式。
当启用行选择功能,并且序号列设置为显示的情况下,会自动在序号列上添加勾选框,方便用户勾选行和查阅行选中状态。如果不需要显示勾选框,可以在序号列配置中将 `checkbox` 属性设置为 `false`,如果需要在其他列上显示勾选框,则可以在对应的列定义对象上将 `checkbox` 属性设置为 `true`。
当启用行选择功能,默认情况下,用户点击行上任意位置都会切换行的选中状态,如果不需要此功能,可以将 `checkByClickRow` 选项设置为 `false`,这样只有用户点击勾选框才能够切换选中状态。
<div class="example">
<div id="datagridCheckableExample" class="datagrid">
<div class="datagrid-container"></div>
</div>
</div>
```html
<div id="datagridCheckableExample" class="datagrid">
<div class="datagrid-container"></div>
</div>
```
```js
$('#datagridCheckableExample').datagrid({
dataSource: {...},
checkable: true,
checkByClickRow: true
});
```
通过 `getCheckItems()` 获取已选中的行数据项。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridPageExample').data('zui.datagrid');
// 获取当前已选中的行数据项
var selectedItems = myDataGrid.getCheckItems();
```
通过 `isRowChecked(rowId)` 检查指定的行是否已选中,其中 `rowId` 为要检查的行编号。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridPageExample').data('zui.datagrid');
// 检测编号为 2 的行是否选中
var isSelect = myDataGrid.isRowChecked(2);
```
通过 `checkRow(rowIndex, checked)` 手动设置指定行选中状态,其中参数定义如下:
* `rowIndex`:要设置的行序号;
* `checked`:如果为 `true` 设置为选中,如果为 `false` 设置为非选中,否则根据之前第状态切换为另一个状态。
```js
// 获取数据表格实例
var myDataGrid = $('#datagridPageExample').data('zui.datagrid');
// 将第2行设置为选中
var isSelect = myDataGrid.checkRow(2, true);
```
可以通过选项 `states` 上的 `selections` 属性设置初始状态下行选中的状态。
```js
$('#myDataGrid').datagrid({
states: {
// 设置初始状态下行编号为 1 和 3 的行为选中状态
selections: {
'1': true,
'3': true,
}
}
})
```
## 跨行跨列的单元格
数据表格支持跨行跨列的单元格,该功能通过 `configs` 选项进行设置。例如设置第 1 行第一个单元格在水平方向上跨越 2 个单元格,设置第 2 行第 3 个单元格在垂直方向上跨越 3 行,则 `configs` 选项设置如下:
<div class="example">
<div id="datagridSpanExample" class="datagrid">
<div class="datagrid-container"></div>
</div>
</div>
```html
<div id="datagridSpanExample" class="datagrid">
<div class="datagrid-container"></div>
</div>
```
```js
$('#datagridSpanExample').datagrid({
configs: {
R1C1: {colspan: 2},
R2C3: {rowspan: 3}
},
// ...
});
```
## 值转换器
值转换器为一个对象,包含如下属性,用于在读取值和设置值时对值进行转换操作。值转换器上可以包含如下属性:
* `getter`:转换函数,用于将值转换为界面上显示的值;
* `setter`:转换函数,用于将用户编辑的值更新到数据源中(暂不支持)。
值转换器 `getter` 函数包含如下参数:
* `value`:用于转换的原始值;
* `cell`:当前单元格信息对象;
* `datagrid`:当前数据表格实例对象。
<div class="example">
<div id="datagridValueOperatorExample" class="datagrid">
<header class="clearfix">
<h3>数据表格值转换器例子 <small>时间列通过值转换器进行来转换操作</small></h3>
</header>
<div class="datagrid-container"></div>
</div>
</div>
值转换器可以通过如下途径进行设置,不同途径生效范围不同。
通过 `valueOperator` 选项进行设置,会影响特定类型的数据,例如下例将所有事件戳类型转换为中文日期格式:
```js
$('#myDataGrid').datagrid({
dataSource: {
cols: [
{name: 'time', valueType: 'date', label: '时间'},
// ... 其他列定义
]
},
valueOperator: {
// date 值转换器会影响所以 valueType 为 `date` 的列
date: {
getter: function(dataValue, cell, dataGrid) {
return new Date(dataValue).toLocaleString();
}
}
}
})
```
<div class="alert alert-primary">
<h4>内置的日期值转换器</h4>
<p>数据表格已经内置了对日期类型(`valueType` 为 `date`)的转换支持,可以简单的通过 `defaultDateFormater` 来设置转换的日期格式。</p>
</div>
值转换器还可以通过列定义参数进行设置。上例可以写为:
```js
$('#myDataGrid').datagrid({
dataSource: {
cols: [
{
name: 'time',
label: '时间',
// 值转换器仅仅影响当前列
valueOperator: {
getter: function(dataValue, cell, dataGrid) {
return new Date(dataValue).toLocaleString();
}
}
},
// ... 其他列定义
]
}
});
```
值转换器还可以通过 `configs` 选项单独为某个单元格或某行进行设置。例如仅仅为第 2 行第 1 列应用日期值转换器“
```js
$('#myDataGrid').datagrid({
dataSource: {
cols: [
{name: 'time', valueType: 'date', label: '时间'},
// ... 其他列定义
]
},
configs: {
R2C1: {
// 值转换器仅影响第 2 行第 1 列的单元格
valueOperator: {
getter: function(dataValue, cell, dataGrid) {
return new Date(dataValue).toLocaleString();
}
}
}
}
})
```
## 自适应列宽
默认情况下列宽如果没有指定的话会自动进行调整,在保证最小列宽的情况下自动根据调整其他列的宽度,确保所以列宽能够填满水平空间,如果水平空间不够显示所以列,则会允许用户在水平方向上滚动浏览其他列。如果不需要自适应列宽功能可以将 `responsive` 选项设置为 `false`,并且在列定义中为每一列手动设置宽度。
当启用自适应列宽功能时,所有没有指定宽度的列会平分剩余的水平空间,但仍然可以通过配置为列宽设置一个权值,使得拥有更大权值的列获得更多的空间。权值通过 列定义的 `width` 属性设置,必须小于 `1`。
```js
$('#myDataGrid').datagrid({
dataSource: {
cols:[
{name: 'time', label: '时间', width: 132},
{name: 'hera', label: '英雄', width: 134},
{name: 'action', label: '动作', width: 109},
// target 列自适应,占据剩余列宽的 1/4
{name: 'target', label: '目标', width: 0.25},
// desc 列自适应,占据剩余列宽的 3/4
{name: 'desc', label: '描述', width: 0.75}
],
}
});
```
## 个性化配置
通过 `configs` 选项可以为某行、某列或某个单元格应用个性化配置。`configs` 选项为一个对象,键值为要配置的行、列或单元格标识,对应值为配置项。
配置标识格式通常是 `R行号C列号`,可以是如下形式:
* `#10`:表示数据项 ID 属性为 `10` 的数据对应的行;
* `R0`:表示第 0 行,即标题行,相当于 `#header`;
* `R1`:表示第 1 行;
* `C0`:表示第 0 列,即序号列;
* `C2`:表示第 2 行;
* `R1C1`:表示第 1 行第 1 列的单元格;
* `#11C2`:表示数据项 ID 属性为 `10` 的数据对应的行,第 2 列的单元格。
配置项支持如下属性:
* `html`: 默认为 `false`,如果设置为 `true`,则在渲染所匹配单元格时将内容作为 html 源码更新到页面上;
* `style`: 可选,在所匹配的单元格元素上要添加的样式(使用 jQuery CSS 样式定义对象规则);
* `className`: 可选,在所匹配的单元格元素上要添加的类名。
下面的例子中将第 2 列的单元格添加 `.text-right` 类实现单元格内文本靠右对齐,并且更改文本颜色和背景色,将第 1 列 第 1 个单元格添加下划线样式:
<div class="example">
<div id="datagridConfigsExample" class="datagrid"></div>
</div>
```html
<div id="datagridConfigsExample" class="datagrid"></div>
```
```js
$('#datagridConfigsExample').datagrid({
dataSource: {...},
configs: {
C2: {
className: 'text-right',
style: {
color: '#00b8d4',
backgroundColor: '#e0f7fa'
}
},
R1C1: {
style: {textDecoration: 'underline'}
}
}
})
```
`configs` 选项还可以为一个回调函数,该回调函数包含一个参数 `selector` 为当前要获取配置项的标识。
```js
$('#myDataGrid').datagrid({
dataSource: {...},
configs: function(selector) {
if (selector === 'R1C1') {
return {color: 'red'};
}
}
});
```
## 自定义模板
只需要为数据表格提供一个空的 `.datagrid` 元素即可进行初始化。在 `.datagrid` 元素内添加其他内容仍然是受支持的。默认情况下,数据表格渲染容器元素 `.datagrid-container` 是被自动添加到 `.datagrid` 元素内部最后位置,如果需要控制 `.datagrid-container` 的位置,只需要手动在合适到位置添加一个空的 `.datagrid-container` 元素。
```html
<div class="datagrid">
<h1>标题</h1>
<div class="search-box">...搜索框</div>
<div class="datagrid-container">...数据表格显示区域</div>
<div>其他内容</div>
</div>
```
## 外观选项
### 移除垂直边框
使用 `.datagrid-borderless` 来移除垂直边框。
<div class="example">
<div id="datagridBorderlessExample" class="datagrid datagrid-borderless"></div>
</div>
```html
<div id="datagridBorderlessExample" class="datagrid datagrid-borderless"></div>
```
### 隔行变色
<div class="example">
<div id="datagridStripedExample" class="datagrid datagrid-striped"></div>
</div>
```html
<div id="datagridStripedExample" class="datagrid datagrid-striped"></div>
```
## 选项
所有可用的选项包括:
<table class="table table-bordered">
<thead>
<tr>
<th style="width: 140px">选项</th>
<th style="width: 150px">名称</th>
<th style="width: 150px">可用值</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>width</code></td>
<td>显示区域宽度</td>
<td>默认为 `'auto'`</td>
<td>允许设置为 CSS 所支持的宽度表示形式。</td>
</tr>
<tr>
<td><code>height</code></td>
<td>显示区域高度</td>
<td>默认为 `400`</td>
<td>当启用分页功能时,如果设置为 `'page'`,则自动将显示区域高度设置为当前页所有行的高度总和。</td>
</tr>
<tr>
<td><code>dataSource</code></td>
<td>数据源</td>
<td>默认为 `null`</td>
<td>参见上文 "数据源" 相关内容。</td>
</tr>
<tr>
<td><code>configs</code></td>
<td>个性化配置</td>
<td>默认为 `null`</td>
<td>参见上文 "个性化配置" 等章节相关内容。</td>
</tr>
<tr>
<td><code>states</code></td>
<td>初始化状态</td>
<td>默认为 `null`</td>
<td>
<p>支持如下属性:</p>
<ul>
<li>`pager`:初始状态下的分页信息,参见上文“分页”内容;</li>
<li>`sortBy`:初始状态下的排序列,参见上文“排序”内容;</li>
<li>`order`:初始状态下的排序顺序,参见上文“排序”内容;</li>
<li>`selections`:初始状态下的行选中状态,参见上文“行选中”内容;</li>
<li>`search`:初始状态下的搜索关键字,参见上文“搜索”内容;</li>
<li>`fixedLeftUntil`:左侧固定列序号最大值,参见上文“固定行和列”内容;</li>
<li>`fixedTopUntil`:上方侧固定行序号最大值,参见上文“固定行和列”内容;</li>
<li>`fixedRightFrom`:右侧固定列序号最小值,参见上文“固定行和列”内容;</li>
<li>`fixedBottomFrom`:底部侧固定行序号最小值,参见上文“固定行和列”内容;</li>
</ul>
</td>
</tr>
<tr>
<td><code>borderWidth</code></td>
<td>单元格边框宽度</td>
<td>默认为 `1`</td>
<td>如果设置为 `0`,则不显示单元格边框。</td>
</tr>
<tr>
<td><code>rowDefaultHeight</code></td>
<td>行高</td>
<td>默认为 `36`</td>
<td></td>
</tr>
<tr>
<td><code>colAutoDefaultWidth</code></td>
<td>自适应列默认宽度</td>
<td>默认为 `80`</td>
<td></td>
</tr>
<tr>
<td><code>colAutoMinWidth</code></td>
<td>自适应列最小宽度</td>
<td>默认为 `50`</td>
<td></td>
</tr>
<tr>
<td><code>showHeader</code></td>
<td>是否显示标题行</td>
<td>默认为 `true`</td>
<td>如果设置为 `false`,则不显示标题行,即行序号为 `0` 的行。</td>
</tr>
<tr>
<td><code>headerHeight</code></td>
<td>标题行高度</td>
<td>默认为 `36`</td>
<td></td>
</tr>
<tr>
<td><code>showRowIndex</code></td>
<td>是否显示行序号列</td>
<td>默认为 `true`</td>
<td>如果设置为 `false`,则不显示行序号列,即列序号为 `0` 的列。</td>
</tr>
<tr>
<td><code>rowIndexWidth</code></td>
<td>行序号列宽度</td>
<td>默认为 `'auto'`</td>
<td>自动计算行序号列宽度</td>
</tr>
<tr>
<td><code>hoverRow</code></td>
<td>是否显示行悬停效果</td>
<td>默认为 `true`</td>
<td>启用后,鼠标悬停在行上会高亮行。</td>
</tr>
<tr>
<td><code>hoverCol</code></td>
<td>是否显示列悬停效果</td>
<td>默认为 `true`</td>
<td>启用后,鼠标悬停在列标题上会高亮对应的列。</td>
</tr>
<tr>
<td><code>hoverCell</code></td>
<td>是否显示单元格悬停效果</td>
<td>默认为 `false`</td>
<td>启用后,鼠标悬停在单元格上会高亮单元格。</td>
</tr>
<tr>
<td><code>responsive</code></td>
<td>是否启用自适应列宽</td>
<td>默认为 `true`</td>
<td>参见上文"自适应列宽"内容。</td>
</tr>
<tr>
<td><code>valueOperator</code></td>
<td>类型值转换器</td>
<td>默认为 `null`</td>
<td>参见上文"值转换器"内容。</td>
</tr>
<tr>
<td><code>defaultDateFormater</code></td>
<td>默认日期转换格式</td>
<td>默认为 `yyyy-MM-dd hh:mm`</td>
<td>参见上文"值转换器"内容。</td>
</tr>
<tr>
<td><code>partialRendering</code></td>
<td>是否启用局部渲染</td>
<td>默认为 `'auto'`</td>
<td>当启用分页时,此选项自动设置为 `true`,否则默认开启。</td>
</tr>
<tr>
<td><code>scrollDelay</code></td>
<td>滚动事件响应延迟</td>
<td>默认为 `0`</td>
<td>单位毫秒,当提高此值可以提高性能,但滚动效果存在延迟。</td>
</tr>
<tr>
<td><code>renderDelay</code></td>
<td>渲染延迟</td>
<td>默认为 `100`</td>
<td>单位毫秒,当提高此值可以提高性能,但可能存在更新较慢的情况。</td>
</tr>
<tr>
<td><code>searchFunc</code></td>
<td>搜索筛选函数</td>
<td>默认为 `null`</td>
<td>参见上文"搜索"内容。</td>
</tr>
<tr>
<td><code>sortFunc</code></td>
<td>排序比较函数</td>
<td>默认为 `null`</td>
<td>参见上文"排序"内容。</td>
</tr>
<tr>
<td><code>sortable</code></td>
<td>是否启用排序</td>
<td>默认为 `false`</td>
<td>当设置为 `true` 后允许用户点击标题行进行排序,参见上文"排序"内容。</td>
</tr>
<tr>
<td><code>checkable</code></td>
<td>是否启用行选择</td>
<td>默认为 `false`</td>
<td>当设置为 `true` 后允许用户选中行,参见上文"行选中"内容。</td>
</tr>
<tr>
<td><code>checkByClickRow</code></td>
<td>是否允许用户点击行任意位置选中行</td>
<td>默认为 `true`</td>
<td>当 `checkable` 设置为 `true` 时生效,参见上文"行选中"内容。</td>
</tr>
<tr>
<td><code>selectable</code></td>
<td>是否允许用户拖拽范围选中行</td>
<td>默认为 `true`</td>
<td>当 `checkable` 设置为 `true` 时生效,参见上文"行选中"内容。</td>
</tr>
<tr>
<td><code>cellCreator</code></td>
<td>单元格生成器</td>
<td>默认为 `null`</td>
<td>
<p>可以设置一个回调函数用于创建单元格元素,回调函数参数包括:</p>
<ul>
<li>`cell`:要创建的单元格对象;</li>
<li>`datagrid`:数据表格对象实例。</li>
</ul>
</td>
</tr>
<tr>
<td><code>cellFormator</code></td>
<td>单元格格式化函数</td>
<td>默认为 `null`</td>
<td>
<p>可以设置一个回调函数用于格式化单元格元素,回调函数参数包括:</p>
<ul>
<li>`$cell`:要格式化的单元格元素;</li>
<li>`cell`:当前单元格对象;</li>
<li>`datagrid`:数据表格对象实例。</li>
</ul>
</td>
</tr>
<tr>
<td><code>rowCreator</code></td>
<td>行生成器</td>
<td>默认为 `null`</td>
<td>
<p>可以设置一个回调函数用于创建行元素,回调函数参数包括:</p>
<ul>
<li>`rowIndex`:要创建的行序号;</li>
<li>`datagrid`:数据表格对象实例。</li>
</ul>
</td>
</tr>
<tr>
<td><code>showMessage</code></td>
<td>出现错误时是否显示消息</td>
<td>默认为 `true`</td>
<td></td>
</tr>
<tr>
<td><code>mouseWheelFactor</code></td>
<td>滚动鼠标滚轮时的滚动速度</td>
<td>默认为 `1`</td>
<td></td>
</tr>
</tbody>
</table>
## 属性和方法
### `setPager(page, recTotal, recPerPage)`
设置分页信息,参数定义如下:
* `page`:要设置的当前页码,如果传递值为 `-1`,则不设置此值;
* `recTotal`:记录总数,如果传递值为 `-1`,则不设置此值;
* `recPerPage`:每页记录数,如果传递值为 `-1`,则不设置此值。
该方法还有另一种参数形式:`setPager(pager)`,其中 `pager` 参数为一个对象,对象上的属性涵盖列上述参数。
```js
// 获取数据表格实例
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
// 设置第 2 页
myDataGrid.setPager(2);
```
### `gotoPage(page)`
设置当前页码,并重新渲染界面,参数定义如下:
* `page`:要设置的当前页码;
```js
// 获取数据表格实例
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
// 设置第 2 页
myDataGrid.gotoPage(2);
```
### `setSearch(searchString)`
设置搜索关键字,参数定义如下:
* `searchString`:用于搜索的关键字字符串,多个关键字使用空格分隔。
```js
// 获取数据表格实例
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
// 搜索 “老虎”
myDataGrid.setSearch('老虎');
```
### `search(searchString)`
相当于 `setSearch(searchString)`,但执行完后会重新渲染界面。
### `setSorter(sortBy, order)`
设置排序规则,参数定义如下:
* `sortBy`:当前用于排序的列名;
* `order`:排序顺序,可选值包括 asc(升序),desc(降序)。
```js
// 获取数据表格实例
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
// 按照名称 name 降序排列
myDataGrid.setSorter('name', 'desc');
```
### `sortBy(sortBy, order)`
相当于 `setSorter(sortBy, order)`,但执行完后会重新渲染界面。
### `setDataSource(dataSource)`
重新设置数据源,参数定义如下:
* `dataSource`:要设置的新的数据源对象。
### `getFilterParams()`
获取当前数据筛选信息,返回一个对象包含如下属性:
* `page`: 当前显示的页码;
* `recPerPage`: 当前设定每页显示的数据个数;
* `search`: 当前用于检索数据的文本;
* `sortBy`: 当前排序依据的列名;
* `order`: 当前排序的顺序,包括顺序(`'asc'`)和倒序(`'desc'`)。
### `showMessage(message, type, autoCloseTime)`
在界面上显示一个消息,参数定义如下:
* `message`:要显示的消息文本;
* `type`:消息类型,允许值包括 `'primary'`、 `'success'`、 `'danger'`、 `'warning'`、 `'info'`、 `'default'`;
* `autoCloseTime`:消息自动关闭的时间,默认为 `5000`,如果设置为 `0`,则不自动关闭。
```js
// 获取数据表格实例
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
// 在界面上显示 'haha' 消息。
myDataGrid.showMessage('haha', 'success');
```
### `renderLoading(loading)`
切换显示加载中状态指示器,其中参数定义如下:
* `loading`:当设置为 `true` 时则显示加载中状态指示器,否则隐藏状态指示器,也可以设置为一个字符串,用于显示加载中指示器上的提示文本。
```js
var myDataGrid = $('#myDataGrid').data('zui.datagrid');
myDataGrid.renderLoading('正在努力获取数据...');
```
### `getData()`
获取当前界面上显示对数据。
### `getRowLayout(rowIndex)`
获取指定行布局信息,其中参数定义如下:
* `rowIndex`:要获取的行序号。
### `updateLayout()`
更新布局信息。
### `getCell(rowIndex, colIndex)`
获取指定单元格信息,其中参数定义如下:
* `rowIndex`:要获取的单元格所在行序号;
* `colIndex`:要获取的单元格所在列序号。
### `getRowConfig(rowIndex)`
获取行配置信息,其中参数定义如下:
* `rowIndex`:要获取的行序号。
### `getColConfig(colIndex)`
获取列配置信息,其中参数定义如下:
* `colIndex`:要获取的列序号。
### `getColConfigByName(colName)`
根据列名称获取列配置信息,其中参数定义如下:
* `colName`:要获取的列名称。
### `getCellConfig(rowIndex, colIndex)`
获取指定单元格配置信息,其中参数定义如下:
* `rowIndex`:要获取的单元格所在行序号;
* `colIndex`:要获取的单元格所在列序号。
### `isRowChecked(rowId)`
检查指定的行是否被选中,其中参数定义如下:
* `rowId`:要要检查对行编号。
### `checkRow(rowIndex, checked)`
手动设置指定行选中状态,其中参数定义如下:
* `rowIndex`:要设置的行序号;
* `checked`:如果为 true 设置为选中,如果为 false 设置为非选中,否则根据之前第状态切换为另一个状态。
### `getCheckItems()`
获取所有被选中的数据项。
### `renderCell(rowIndex, colIndex)`
重新渲染单元格,其中参数定义如下:
* `rowIndex`:要操作的单元格所在行序号;
* `colIndex`:要操作的单元格所在列序号。
### `renderRow(rowIndex)`
重新渲染行,其中参数定义如下:
* `rowIndex`:要操作的行序号。
### `renderData()`
重新渲染所有行及单元格。
### `renderScrolls()`
重新渲染滚动条。
### `renderFixeds()`
重新渲染固定的行和列。
### `render()`
重新从数据源获取数据并渲染整个数据表格,包括行、列、滚动条等。
### `setScrollbarOffset(offsetX, offsetY)`
设置滚动条位置,其中参数定义如下:
* `offsetX`:滚动条距离左侧的距离,如果设置为 `null`,则不设置左侧滚动条距离;
* `offsetY`:滚动条距离上方的距离,如果设置为 `null`,则不设置上方滚动条距离。
### `scroll(scrollLeft, scrollTop)`
设置滚动距离,其中参数定义如下:
* `scrollLeft`:水平滚动距离,如果设置为 `null`,则不设置水平滚动距离;
* `scrollTop`:垂直滚动距离,如果设置为 `null`,则不设置垂直滚动距离。
## 事件
### `onRender`
当数据表格重新渲染后触发。
```js
// 在初始化的时候设置事件回调函数
$('#dataGrid').datagrid({
onRender: function() {
// 表格已重新渲染
}
});
```
```js
// 使用 jquery 的 $().on() 方法监听事件
$('#dataGrid').on('onRender', function(event) {
// 表格已重新渲染
});
```
### `onScroll`
当滚动位置发生变更时触发,其中回调函数参数包括:
* `scrollLeft`:水平滚动距离;
* `scrollTop`:垂直滚动距离;
* `scrollInfo`:其他信息。
```js
// 在初始化的时候设置事件回调函数
$('#dataGrid').datagrid({
onScroll: function(scrollLeft, scrollLeft, scrollInfo) {
// 处理滚动后的操作
}
});
```
```js
// 使用 jquery 的 $().on() 方法监听事件
$('#dataGrid').on('onScroll', function(event, scrollLeft, scrollLeft, scrollInfo) {
// 处理滚动后的操作
});
```
### `onLoad`
当重新从数据源加载数据后触发,其中回调函数参数包括:
* `result`:如果加载成功,则为加载后的数据列表,否则为 `false`。
```js
// 在初始化的时候设置事件回调函数
$('#dataGrid').datagrid({
onLoad: function(result) {
if (result !== false) {
console.log('数据加载成功', result);
}
}
});
```
```js
// 使用 jquery 的 $().on() 方法监听事件
$('#dataGrid').on('onLoad', function(event, result) {
if (result === false) {
console.log('数据加载失败。');
}
});
```
### `onSelectRow`
当选中或取消选中表格行时触发,其中回调函数参数包括:
* `rowId`:选中状态变更的行 ID;
* `checked`:`true` 表示选中,`false` 表示取消选中;
* `selections`:当前所有选中的行。
```js
// 在初始化的时候设置事件回调函数
$('#dataGrid').datagrid({
onSelectRow: function(rowId, checked, selections) {
console.log('行', rowID, checked ? '选中了' : '取消选中了');
}
});
```
```js
// 使用 jquery 的 $().on() 方法监听事件
$('#dataGrid').on('onLoad', function(event, result) {
if (result === false) {
console.log('数据加载失败。');
}
});
```
<script src="dist/lib/selectable/zui.selectable.js"></script>
<script src="dist/lib/datagrid/zui.datagrid.js"></script>
<link href="dist/lib/datagrid/zui.datagrid.css" rel="stylesheet">
<script>
function afterPageLoad() {
// 获取示例数据
var getSampleData = function() {
var getRandomInt = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
var getRandomData = function(arr, start, end) {
if (start === undefined) {
start = 0;
}
if (end === undefined) {
end = arr.length;
}
return arr[getRandomInt(start, end - 1)];
};
var getLuckInt = window.getLuckInt = function(min, max, luck) {
return (luck % (max - min) + min);
};
var getLuckData = window.getLuckData = function(arr, start, end, luck) {
if (start === undefined || start === null) {
start = 0;
}
if (end === undefined || end === null) {
end = arr.length;
}
return arr[getLuckInt(start, end - 1, luck)];
};
var createDataSample = function(size) {
size = size || 100;
var heros = ['力丸', '幻影刺客', '祈求者', '斧王', '巫医', '天辉防御塔', 'Roshan', '嗜血狂魔', '宙斯', '影魔', '米波', '树精卫士'];
var actions = ['击杀', '拾取', '购买', '治疗'];
var items = ['圣剑', '虚灵之刃', '真视宝石', '恐鳌之心', '远行鞋', '治疗指环', '黑皇杖', '刷新球', '金箍棒', '蝴蝶', '诡计之雾', '显影之尘', '侦查守卫', '岗哨守卫', '漩涡', '天堂之戟', '刃甲', '希瓦的守护', '强袭胸甲', '阿托斯之棍', '银月之晶', '斯嘉蒂之眼', '玲珑心', '撒旦之邪力', '否决挂饰', '隐刀', '血棘', '邪恶镰刀', '白银之锋', '辉耀', '代达罗斯之殇', '幻影斧', '林肯法球', '阿哈利姆神杖', '死灵书'];
var runes = ['赏金神符', '双倍神符', '魔法神符', '极速神符', '不朽之守护', '奶酪'];
var cols = [
{label: '时间', name: 'time', width: 130, valueType: 'gametime', sort: true},
{label: '英雄', name: 'hero', width: 80},
{label: '动作', name: 'action', width: 80},
{label: '队友', name: 'teammate', width: 80},
{label: '敌人', name: 'enemy', width: 80},
{label: '物品/神符', name: 'item', width: 80},
{label: '获得经验', name: 'gotexps', width: 80, valueType: 'number'},
{label: '获得金钱', name: 'gotgolds', width: 80, valueType: 'number'},
{label: '累计经验', name: 'exps', width: 80, valueType: 'number'},
{label: '剩余金钱', name: 'golds', width: 80, valueType: 'number'},
{label: '描述', name: 'desc', width: 'auto', minWidth: 200},
{label: '累计人头', name: 'kills', width: 110, valueType: 'number'},
];
var createDataItem = function(index) {
var luckNumber = parseInt((Math.sin(index + 1) + '').substr(3));
var time = 600 + 5*index + getLuckInt(0, 5, luckNumber);
var action = getLuckData(actions, null, null, luckNumber);
var heroIndex = getLuckInt(0, action === '击杀' ? 6 : 4, luckNumber);
var hero = heros[heroIndex];
var teammate, enemy, item;
var heroData = {
golds: heroIndex*500*heroIndex + 71*index + getLuckInt(0, 71, luckNumber),
exps: heroIndex*300*heroIndex + 43*index + getLuckInt(0, 43, luckNumber),
kills: heroIndex + Math.floor(index/10)
};
var gotExps = 0;
var gotGolds = 0;
switch (action) {
case '击杀':
enemy = getLuckData(heros, 6, 9, luckNumber);
gotExps += getLuckInt(0, 1000 + index * 10, luckNumber);
gotGolds += getLuckInt(0, 200 + index * 8, luckNumber);
if (hero === '力丸') {
action = '偷摸';
} else if (hero === '斧王') {
action = '斩杀';
}
break;
case '购买':
item = getLuckData(items, null, null, luckNumber);
break;
case '拾取':
item = getLuckData(runes, null, null, luckNumber);
if (item === '赏金神符') {
gotExps += getLuckInt(0, 50 + index, luckNumber);
gotGolds += getLuckInt(0, 50 + index * 2, luckNumber);
}
break;
case '治疗':
teammate = getLuckData(heros, 0, 4, luckNumber);
if (hero === '巫医') {
action = '奶';
}
break;
}
heroData.golds += gotGolds;
heroData.exps += gotExps;
var desc = hero + action + '了“' + (item || teammate || enemy) + '”';
if (gotGolds) {
desc += ',获得了金钱 ' + gotGolds;
}
if (gotExps) {
desc += ',' + (gotGolds ? '并' : '') + '获得了经验 ' + gotExps;
}
desc += '。';
var dataItem = {
id: time,
time: time,
hero: hero,
action: action,
teammate: teammate || '',
enemy: enemy || '',
item: item || '',
gotgolds: gotGolds || '',
gotexps: gotExps || '',
exps: heroData.exps,
golds: heroData.golds,
kills: heroData.kills,
desc: desc
};
return dataItem;
};
return {
dataSource: {
cols: cols,
length: size,
getByIndex: createDataItem
},
valueOperator: {
gametime: {
getter: function(time) {
var hours = Math.floor(time/3600);
if (hours < 10) {
hours = '0' + hours;
}
var mins = Math.floor(time/60)%60;
if (mins < 10) {
mins = '0' + mins;
}
var secs = time%60;
if (secs < 10) {
secs = '0' + secs;
}
return hours + ':' + mins + ':' + secs;
}
}
},
generate: function (size) {
var result = [];
for(var i = 0; i < size; ++i) {
result.push(createDataItem(i));
}
return result;
}
};
};
var sampleSize = 10000000000000;
return createDataSample(sampleSize);
};
var sampleData = getSampleData();
$('#datagridExample,#datagridBorderlessExample,#datagridStripedExample').datagrid({
configs: {
'R0C0': {
label: '#'
},
'C1': {
style: {textAlign: 'right'}
},
'C2': {
style: {fontWeight: 'bold'}
}
},
dataSource: {
cols: sampleData.dataSource.cols,
data: sampleData.generate(100),
cache: true,
},
valueOperator: sampleData.valueOperator,
states: {
pager: {page: 1, recPerPage: 10},
},
height: 300,
renderDelay: 200,
checkable: true,
sortable: true,
hoverCell: true,
onSelectRow: function(rowIndex, checked, selections) {
console.log('>', rowIndex, checked, selections);
}
});
var simpleDataSource = {
cols: sampleData.dataSource.cols,
data: sampleData.generate(50),
};
$('#tableDataGridExample').datagrid({
height: 184
});
$('#remoteDataGridExample').datagrid({
height: 'page',
states: {
pager: {page: 1, recPerPage: 5},
},
dataSource: {
cache: false,
cols:[
{name: 'time', label: '时间', width: 132},
{name: 'hera', label: '英雄', width: 134},
{name: 'action', label: '动作', width: 109},
{name: 'target', label: '目标', width: 109},
{name: 'desc', label: '描述', width: 287}
],
remote: function(params) {
return {
// 原创请求地址
url: 'docs/partial/remote-data-' + params.page + '.json',
// 请求类型
type: 'GET',
// 数据类型
dataType: 'json'
};
}
},
});
$('#dynamicDataGridExample').datagrid($.extend({
defaultDateFormater: 'hh:mm:ss',
states: {
fixedTopUntil: 0,
fixedBottomFrom: sampleData.dataSource.length,
fixedRightFrom: 12,
pager: {page: 0}
},
configs: {
'C1': {
style: {textAlign: 'right'}
},
'C2': {
style: {fontWeight: 'bold', color: '#448aff'}
}
},
renderDelay: 200,
checkable: false,
sortable: false,
}, sampleData));
$('#datagridFixedExample').datagrid({
dataSource: simpleDataSource,
valueOperator: sampleData.valueOperator,
states: {
pager: {page: 1, recPerPage: 100},
fixedLeftUntil: 0,
fixedRightFrom: 12,
fixedTopUntil: 0,
fixedBottomFrom: 100,
},
height: 300,
});
$('#datagridSortExample').datagrid({
dataSource: {
cols: sampleData.dataSource.cols,
data: sampleData.generate(100),
},
valueOperator: sampleData.valueOperator,
sortable: true,
height: 300,
});
$('#datagridPageExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
valueOperator: sampleData.valueOperator,
sortable: true,
height: 300,
});
$('#datagridSearchExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
valueOperator: sampleData.valueOperator,
sortable: true,
height: 300,
});
$('#datagridCheckableExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
valueOperator: sampleData.valueOperator,
checkable: true,
height: 300,
});
$('#datagridSpanExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
configs: {
R1C1: {colspan: 2},
R2C3: {rowspan: 3}
},
valueOperator: sampleData.valueOperator,
height: 300,
});
$('#datagridValueOperatorExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
valueOperator: {
// date 值转换器会影响所以 valueType 为 `date` 的列
gametime: {
getter: function(dataValue, cell, dataGrid) {
return '第' + (Math.floor(dataValue%60)) + '分钟第' + (dataValue%60) + '秒';
}
}
},
height: 300,
});
$('#datagridConfigsExample').datagrid({
dataSource: simpleDataSource,
states: {
pager: {page: 1, recPerPage: 20},
},
configs: {
C2: {
className: 'text-right',
style: {
color: '#00b8d4',
backgroundColor: '#e0f7fa'
}
},
R1C1: {
style: {textDecoration: 'underline'}
}
},
height: 300,
});
}
</script>