X5中提供了dataTables和grid组件。它们都可以分页显示数据、可以使用CSS控制样式、可以排序、可以显示页脚汇总。grid还可以直接编辑、可以分组,可以显示树形数据。
目录
1、组件展示
dataTables组件展示网格数据
grid组件展示树形数据
2、整体功能
2.1、显示数据——dataTables & grid
- 添加组件——从右侧组件面板中拖拽dataTables或者grid组件到设计器中
- 关联数据——设置组件的data属性,选择一个bizData、baasData或者data组件
- 添加列——在组件上点右键,选择添加列,选择要显示的列,点确定按钮。
- 删除列——用鼠标选中列,按delete键即可删除选中的列
2.2、设置编辑——grid
- 设置列的属性editable为true
- 在列中放入编辑时用的组件,例如:input,gridSelect、textarea
- 设置编辑组件的bind-ref属性,和列的ref指向相同的列
注意:拖拽组件到设计器中,在列的下方出现红色小竖线时,松开鼠标
编辑组件放入列中时,会自动在列的下面创建editor节点,编辑组件就放在editor节点下。
grid组件还有一个directEdit属性,如果希望点击某列即进入编辑状态,设置这个属性为true,否则双击某列才会进入编辑状态。
2.3、显示行号——dataTables & grid
- 设置showRowNumber为true
- grid还可以设置行号列的宽度,设置rowNumberWidth属性
2.4、设置多列头——grid
grid可以实现下面这样多列头的效果,方法是:
1、在grid组件上点右键,选择设置多列头
2、点列头右边的加号,再点增加合并定义按钮,在合并列中选择合并的第一列,输入要合并的列数,以及定义合并后列头的名称。如果要加多层列头,再点列头右边的加号。
3、grid的列头默认是左对齐,设置多列头后,使用居中会比较好看,打开grid组件的class属性,选择列头对齐方式为居中
4、现在效果出来了。
2.5、设置分组——grid
下图展示了grid的多级分组,多级统计的能力,按“类型”和“提交人”分组,统计“金额”字段
1、在grid组件上点右键,选择设置分组
- 1、启用分组——设置是否使用分组
- 2、启用自定义分组栏——启用后,用户可以调整分组
- 3、分组折叠——选中后,grid只显示一级分组,展示一级分组,显示二级分组或数据,逐级展开可以看到全部数据
- 4、默认分组列定义——按顺序勾选需要分组的字段
2、在需要分组统计的列上设置分组属性,例如:设置类型的分组属性
- text——设置分组显示名称,{0}表示分组字段的值,{1}表示分组中的记录数,其它文字根据需要来写,例如:上图是这样设置的:一级分组:{0}
- order——设置分组排序方式,设置是升序还是降序
- columnShow——设置分组后是否显示该列
- summany——设置分组是否统计,设置该级分组是否显示统计行
- summanyType——设置统计方式,选择统计函数
- summanyTpl——设置统计显示模版,{0}表示分组统计值,{1}表示分组指,例如:<b>合计:{0}</b>,其它文字根据需要来写
- summanyPos——设置分组统计显示位置,选择是头部还是尾部
2.6、设置页脚汇总——dataTables & grid
1、显示页脚行——设置组件的useFooter属性为true
2、页脚显示文字——两种方式设置
(1)设置列的footerData属性——支持动态计算,即数据修改后,自动重算统计值
上图中的页脚是这样设置的:
- 类型列的footerData属性设置为’合计”
- 金额列的footerData属性设置为$data.sum(‘sENField11’),其中$data是环境变量,代表组件关联的data组件,sum是求和方法,sENField11是金额列的字段名。
(2)使用setFooterData方法
上图中的页脚可以这样设置
this.comp('taskGrid').setFooterData({sTypeName:'合计',sENField11:1000});
2.7、控制显示——dataTables & grid
如何设置表格的高度?如何设置列的宽度?
dataTables的设置
1、列宽的设置
列的width属性可以有下面三种情况
- 不设置——根据内容,自适应宽度
- 设置为像素值——例如:100px,列宽为100px
- 设置为百分比——例如:25%,列宽占整个组件的四分之一宽
2、表格自动高度和固定高度
- 自动高度——不设置scrollY属性,表格的高度根据数据的多少自适应
- 固定高度——设置scrollY属性为高度像素值,例如:200px,表格的高度为200px。数据多了,会出现垂直滚动条,如果数据没那么多 通过scrollCollapse属性设置表格是否自适应高度,scrollCollapse为true,表格高度适应数据高度,为false,表格高度不变。
3、表格自适应宽度和响应式处理
- 自适应宽度——不用特殊设置,组件就会自适应宽度。当表格有太多列,导致页面出现滚动条的时候,可以通过设置scrollX属性,来开启水平滚动条。设置为1,显示水平滚动条,为空,不显示滚动条。
- 响应式处理——当列多的时候,还可以使用响应式处理的方法,效果如下图,将右边显示不下的列显示在每行的下面,点左侧的绿色按钮,可以显示这些列的内容,点红色按钮,可以隐藏这些内容。使用响应式处理的方法是设置flexibleWidth为false,responsive为true
grid的设置
1、列宽的设置
列的width属性可以有下面两种情况
- 不设置——和其它没有设置宽度的列,平分表格总宽度减去已设置宽度的列的宽度总和
- 设置为像素值——例如:100,列宽为100px
2、表格自动高度和固定高度
- 自动高度——设置height属性为auto
- 固定高度——设置height属性为高度像素值,例如:200px,表格的高度为200px。数据多了,会出现垂直滚动条
2.8、显示树形——grid
grid组件可以显示上面两种树形,左边的是树,也就是只显示一列,右边的是树形表格,可以显示多列。还可以设置虚根,例如:左边的树设置了虚根组织机构,这个组织机构不是数据,不在数据库中。
grid显示为树和显示虚根,是通过下面四个属性设置出来的。
- appearance属性——控制显示样式,设置为grid时,显示为普通表格,设置为tree时,显示为树,设置为treeGrid时,显示为树形表格
- expandColumn属性——当appearance属性为tree或treeGrid时必填,设置为展开列的字段名,例如:上图中名称列是展开列,名称列对应的字段名是sName,就将sName填入expandColumn属性
- useVirtualRoot属性——设置是否使用虚根,设置为true时,表示使用虚根,设置为false时,表示不使用虚根
- virtualRootLabel属性——设置虚根的名称,例如:上图virtualRootLabel属性设置的是组织机构
树和树形数据的展开列上可以显示图标,在onTreeIconRender事件中,可以根据不同的数据,显示不同的图标。下面的代码中展示了使用字体图标和图片的两种方式。
Model.prototype.grid1TreeIconRender = function(event){
if(event.row.val('sOrgKindID')=='psm')
event.html = '<i class="icon-android-contact" style="font-size:16px;color:skyblue;"/>';
else{
var url = require.toUrl('$UI/demo/ogn.gif');
event.html = '<img src="' + url + '" />'; } };
2.9、刷新——grid
grid和data之间是使用行ID进行关联的,因此修改行ID之后,grid和data就失去了关联,必须刷新grid,才能正确显示data中的数据。
刷新grid的方法是refresh();,有两种情况会修改行ID
- 使用setValue方法给行ID赋值
- 使用复制行的方法assign进行整行复制
下面的代码展示了把data1的当前行整行复制给data2的当前行,在调用整行复制assign方法后,改变了data2的当前行的ID,改成了data1的当前行的ID,因此必须刷新显示data2数据的grid2,grid2才能正确显示这行新数据
Model.prototype.copyRowBtnClick = function(event){
var row1 = this.comp('data1').getCurrentRow();
var row2 = this.comp('data2').getCurrentRow();
row2.assign(row1);
this.comp('grid2').refresh();
};
2.10、动态创建——dataTables & grid
表格组件可以动态创建,下面分别展示创建dataTables和grid的代码。代码中创建了一个显示orgData的sName和sCode两列的表格
创建dataTables
//引用dataTables.js
var dataTables = require("$UI/system/components/justep/dataTables/dataTables");
Model.prototype.createGridBtnClick = function(event) {
var parentNode = this.getElementByXid("content1");
var option = {
parentNode : parentNode,
//dataTables的属性,设计时有的属性都可以设置
data : "orgData",
class:'table table-hover table-striped',
flexibleWidth : true,
responsive : false,
// 列定义
columns : [{sName:"sName",xid:"column1"}, {sName:"sCode",xid:"column2"}]
};
new dataTables(option);
};
创建grid
//引用grid.js
var Grid = require("$UI/system/components/justep/grid/grid");
Model.prototype.createGridBtnClick = function(event) {
var parentNode = this.getElementByXid("content1");
var option = {
parentNode : parentNode,
//grid的属性,设计时有的属性都可以设置
data: "orgData",
width: '100%',
height:'auto',
// 列定义
colModel : [{width:"300",name:"sName",xid:"column1" },{width:"200",name:"sCode",xid:"column2"}]
};
new Grid(option);
};
3、列的功能
3.1、显示列、隐藏列——dataTables & grid
//使用组件的hideCol方法隐藏列
this.comp('dataTables1').hideCol('sFName');
this.comp('grid1').hideCol('sFName');
//使用组件的showCol方法显示列
this.comp('dataTables1').showCol('sFName');
this.comp('grid1').showCol('sFName');
3.2、设置列的前端过滤——grid
grid支持在列头出现过滤工具条,可以过滤每一列,还有多种操作符可以选择,这里过滤的是前端数据,也就是只过滤展现出来的数据。 
做法:设置grid组件的useFilterBar属性为true,在源码中给grid的列增加如下的操作符,运行时效果如上图
<column width="150" name="sCreateTime" xid="column16">
<searchoptions>
<sopt>
<item>eq</item>
<item>ne</item>
<item>le</item>
<item>lt</item>
<item>gt</item>
<item>ge</item>
<item>bw</item>
<item>bn</item>
<item>cn</item>
<item>nc</item>
<item>ew</item>
<item>en</item>
</sopt>
</searchoptions>
</column>
3.3、设置列的排序——dataTables & grid
- 服务端排序——对数据库中的数据进行排序,将排序后的数据显示到组件中
- 前端排序——对前端显示的数据进行排序
- 多列排序——象sql的order by一样,对多个列同时进行排序
dataTablers支持两种方式排序:服务端排序和多列排序
- 设置组件允许排序——设置组件的ordering属性为true
- 设置列允许排序——设置列的orderable属性为true,列就可以排序了
- 使用多列排序——按住shift键盘,选择要排序的第二列、第三列…
grid支持两种方式排序:服务端排序和前端排序
- 设置使用服务端排序——设置组件的serverSort属性为true
- 设置使用前端排序——设置组件的erverSort属性为false
- 设置列允许排序——设置列的sortable属性为true,列就可以排序了
- 设置排序方式——排序方式分为文本text、整数int、浮点数float、日期date四种,根据列的类型正确选择列的sorttype属性值
3.4、列的格式化显示——dataTables & grid
dataTables的设置
dataTables只支持格式化显示日期型数据,通过设置列的format属性实现
grid的设置
grid的列支持格式化显示五种数据:分别是整型integer、数值型number、货币型currency、日期型date和电子邮件email。通过设置formatte
r属性来实现。
- 整型integer、数值型number——可以设置千分位thousandsSeparator和小数位数decimalPlaces
- 货币型currency——还可以设置前缀prefix和后缀suffix
- 日期型date——可以设置日期格式
- 电子邮件email——设置为email后,点击邮箱地址,会打开outlook,以这个邮箱地址为收件人,生成新邮件
3.5、列内容对齐——grid
列内容对齐有三种方式:左对齐left、居中center、右对齐right,通过设置列的align属性实现
3.6、设置可调整列宽——grid
设置列的resizable为true,表示可调整列宽,设置为false,表示列宽度固定
4、行的功能
4.1、设置行高、前景色、背景色——dataTables & grid
使用rowAttr属性——静态设置
- 下图为设置了rowAttr属性的前后对比,设置了行高50px和粉色背景色
- rowAttr属性设置为{style:’height:50px;background:pink;’}
使用rowAttr属性——动态设置
- 下图为设置了rowAttr属性的前后对比,编码等于JUSTEP时,背景色为粉色,否则为黄色
- rowAttr属性设置为$row.val(‘sCode’)==’JUSTEP’?{style:’height:50px;background:pink;’}:{style:’height:50px;background:yellow;’}

rowAttr属性只为显示用,当修改数据之后,需要在data组件的onValueChanged事件中写代码重新设置。
例如:使用grid组件的setRowCss方法设置行底色,代码如下
Model.prototype.detailDataValueChanged = function(event){
if(event.col=='sCode'){
var rowid = this.comp('detailData').getRowID(event.row);
if(event.value=='JUSTEP'){
this.comp('detailGrid').setRowCss(rowid,{background:'pink'});
}else{
this.comp('detailGrid').setRowCss(rowid,{background:'yellow'});
}
}
};
4.2、设置奇偶行的背景色——dataTables & grid
dataTables组件的设置
- dataTables使用了Bootstrap的表格样式,可以直接修改Bootstrap的样式。
- 奇行背景色的样式——.table-striped>tbody>tr:nth-of-type(odd)
效果如下图
.blueActive{
background:skyblue !important;
}
grid的设置
.x-state-highlight是选中行的样式
.table-hover>tbody>tr:hover {
background:yellow;
}
grid的设置
tr.x-state-hover是鼠标悬停行的样式
tr.x-state-hover{
background:pink !important;
}
4.5、行的多选——dataTables & grid
1、设置多选行
设置组件的multiselect属性为true,就会在左侧出现一列checkbox,选中checkbox,表示选中checkbox所在的行,需要全选时,可以点列头上的checkbox。
还可以使用代码选中行,调用组件的setRowChecked方法,设置某行选中或不选中。这个方法有两个参数,第一个参数是要操作的行,第二个参数是是否选中。
2、获取多选行
选中checkbox后,调用组件的getCheckeds()方法,返回选中行的行ID数组
3、选中或取消选中时触发的事件
- 选中列头上的checkbox时,表示全选,会触发onRowCheckedAll事件
- 取消选中列头上的checkbox时,表示全取消,会触发onRowCheckedAll事件
- 选中数据行上的checkbox时,表示选中本行,会先触发onRowCheck事件,再触发onRowChecked事件
- 取消选中数据行上的checkbox时,表示取消选中本行,会先触发onRowCheck事件,再触发onRowChecked事件
- 三个事件中,都返回了触发事件的动作,event.checked为true,表示要选中,为false表示要取消选中
- onRowCheck事件和onRowChecked事件中,event返回了选中或取消选中的行信息,event.row为选中或取消选中的行,event.rowID为选中或取消选中的行ID
- 控制是否允许选中或取消选中,在onRowCheck事件中,判断是否允许选中或取消选中,如果不允许,就设置event.cancel=true;,就会取消这次操作
4、grid组件的扩展能力
关于多选,grid组件还提供了下面4个属性
- mutilboxonly属性——控制点击行是不是进行多选;如果为true,表示只能点checkbox才能多选
- mutilselectWidth属性——设置多选列的宽度
- checkedclass属性——设置选中行的样式,例如可以定义一个设置了背景色的样式,将样式名称填入checkedclass属性
- cascade属性——控制树是否级联勾选,设置为true时,选中或取消选中父节点的checkbox,会自动选中或取消选中已展开的子节点的checkbox。设置为false时,则没有上面的效果
5、单元格的功能
5.1、设置单元格的前景色、背景色——dataTables & grid
设置单元格的前景色、背景色,使用dataTables和grid的单元格渲染事件onCellRender似乎很合适。实际上,对于dataTables来说,是很合适,onCellRender事件只在渲染组件时为每个单元格触发一次,以后不再触发。但是对于grid来说,不仅渲染组件时会触发,而且当光标离开可编辑单元格时,也会触发。这样就存在没有修改数据时,仍要执行代码,为了避免这种情况,我们使用onReload和onValueChanged事件。
dataTables的设置
- 设置单元格样式——在dataTables组件的单元格渲染事件onCellRender中设置
Model.prototype.dataTables1CellRender = function(event){
if(event.colName=='sName'){
if(event.colVal.length > 10)
event.html='<font color="red">' + event.html + '</font>';
else
event.html='<font color="blue">' + event.html + '</font>'; } };
grid的设置
- 设置单元格样式的方法——使用grid组件的setCell方法
- 数据加载后设置所有单元格的样式——在grid组件的重新加载事件onReload中设置
- 数据修改后重新设置样式——在data组件的onValueChanged事件设置
Model.prototype.taskGridReload = function(event){
var taskData = this.comp('taskData');
var me = this;
taskData.each(function(option){
me.setNameCellColor(option.row);
});
};
Model.prototype.taskDataValueChanged = function(event){
if(event.col=='sName'){
this.setNameCellColor(event.row);
}
};
Model.prototype.setNameCellColor = function(row){
var style;
if(row.val('sName').length > 10)
style = {color:'#ff0000'};
else
style = {color:'#00ff00'};
this.comp('taskGrid').setCell(row.getID(),'sName',style);
};
5.2、合并单元格——grid
- 获得要合并的第一个单元格——调用组件的getCell方法获得单元格cell(也就是table中的td)
- 在单元格上设置合并——调用cell的jquery方法attr(‘rowspan’,数量)设置合并
- 隐藏其它被合并的单元格——调用cell的jquery方法hide隐藏单元格
下面的代码演示了对于一列的合并算法
Model.prototype.taskGridReload = function(event){
var taskData = this.comp('taskData');
var lastName='';//记录上一个单元格的值,用于比较
var delRowArr = [];//保存被合并的行ID,最后设置隐藏
var spanRowArr = [];//保存要设置合并的行ID,最后设置合并
var spanNum = 0;//记录需要合并几行
var firstRowID;//记录需要合并的行ID
taskData.each(function(option){//在遍历时进行比较,确定合并方式
if(lastName==option.row.val('sCreatorPersonName')){
delRowArr.push(option.row.getID());
spanNum ++;
}else{
if(lastName != '' && spanNum > 1)
spanRowArr.push([firstRowID,spanNum]);
spanNum = 1;
lastName = option.row.val('sCreatorPersonName');
firstRowID = option.row.getID();
}
});
if(spanNum > 1){
spanRowArr.push([firstRowID,spanNum]);
}
if(spanRowArr.length > 0){//设置合并
$.each(spanRowArr,function(i,rowid){
var cell = event.source.getCell(rowid[0],'sCreatorPersonName');
$(cell).attr('rowspan',rowid[1]);
});
}
if(delRowArr.length > 0){//设置隐藏
$.each(delRowArr,function(i,rowid){
var cell = event.source.getCell(rowid,'sCreatorPersonName');
$(cell).hide();
});
}
};
5.3、显示按钮、链接——dataTables & grid
在单元格中显示按钮、链接
- 显示按钮——onCellRender事件中的event.html可以控制单元格的展现,给event.html设置为<button>,就可以展现出按钮。
- 显示链接——onCellRender事件中的event.html可以控制单元格的展现,给event.html设置为<a>,就可以展现出链接。
- 在添加的按钮和链接的单击事件中获得model对象的方法
- v3.3版本及以前:使用justep.Bind.contextFor(this).$model
- v3.4版本及以后:使用justep.Util.getModel(this)
Model.prototype.taskGridCellRender = function(event){
if(event.colName=="sEIField41")//显示按钮
event.html = "<button class='btn btn-default btnDel' onclick='justep.Bind.contextFor(this).$model.delData(event,\"" + event.rowID + "\")'>删除</button>";
//上面这句代码中,第一个event是onclick的dom事件对象,第二个event是onCellRender的事件对象,this是button这个节点
};
Model.prototype.delData = function(event, rowid) {
var row = this.comp("taskData").getRowByID(rowid);
this.comp("taskData").deleteData(row);
event.stopPropagation();//停止事件的传播,否则还会出发RowClick事件
};
5.4、显示图片——dataTables & grid
显示图片——在onCellRender中给event.html设置为,就可以显示出图片
代码如下,根据不同的值,显示不同的图片
Model.prototype.taskGridCellRender = function(event){
if(event.colName=="sEIField41"){
var url;
if(event.colVal==1)
url = require.toUrl("$UI/demo/justep.png");
else
url = require.toUrl("$UI/demo/car.jpg");
event.html = "<img src='" + url + "' width='100'/>";
}
};
上面展示了显示图片文件的写法,还有两种图片,一种是存入数据库的blob图片,另一种是存入文档服务器的附件图片,它们的区别在于获得图片url的方法不同,下面分别进行介绍
1、获得附件图片的url
使用AttachmentImage组件上传图片后,字段里面的值是一个json数组,例如
在这个json数组中,获取docPath和fileID,调用getURLByFileID方法获取附件图片的url
注意,需要引用DocUtils
var DocUtils = require("$UI/system/components/justep/docCommon/docUtil");
Model.prototype.taskGridCellRender = function(event){
if(event.colName=="sETField31"){
var json = event.colVal;
if(json != "" && json != undefined){
var jsonList = eval("("+json+")");
var docPath = jsonList[0]["docPath"]; //获得docPath
var fileID = jsonList[0]["fileID"];; //获得fileID
var url = DocUtils.InnerUtils.getURLByFileID({docPath:docPath,fileID:fileID,context:this.getContext()})
event.html = "<img src='" + url + "' width='100'/>";
}
}
};
2、获得blob图片的url
在queryAction中得不到blob类型的数据,在select中可以增加一列,用来判断blob字段是否有数据。有数据时,再设置用img显示。
Model.prototype.taskGridCellRender = function(event){
if(event.colName=="hasImg"){
if(event.colVal == "1"){
var url = biz.Request.setBizParams(require.toUrl("$UI/system/service/common/bizAction.j")
+ "?blobDataModel=/system/data" //数据模块目录
+ "&blobConcept=SA_Task" //概念名
+ "&blobRelation=sEBField51" //关系名
+ "&blobConceptValue=" + event.rowID //行ID
+ "&process=/erp/buy/process/grid/gridProcess" //流程名称
+ "&activity=mainActivity" //环节名称
+ "&action=blobDownloadAction" //调用的Action
+ "&$query-version=" + justep.UUID.createUUID(),this.getContext().getBSessionID());
event.html = "<img src='" + url + "' width='100'/>";
}
}
};
5.5、使用文本框编辑——grid
- 设置编辑时,放textarea组件,可以编辑多行数据,且编辑后的数据也多行显示
- 设置textarea组件的bind-ref属性,和列的ref指向相同的列
5.6、使用下拉框编辑——grid
- 设置编辑时,放gridSelect组件,可以在编辑时,显示下拉框
- 设置gridSelect组件的bind-ref、bind-labelRef属性,和列的ref指向相同的列
- 设置gridSelect组件的option属性下面的3个属性:data、value、label
- data指向一个data组件或者bizData组件,作为下拉数据的来源
- value指向data中的列名,这个值会写入bind-ref关联的字段
- label指向data中的列名,这个值会写入bind-labelRef关联的字段
6、说明
dataTables组件封装的是jquery的dataTables插件
grid组件封装的是jquery的jqGrid插件
本文由WeX5君整理,WeX5一款开源免费的html5开发工具,H5 App开发就用WeX5!
阅读其他app 开发相关文章:http://doc.wex5.com/?p=3443



























太详尽了,教科书般!
建议编写grid中event下面的事件都有哪些的文档,非常感谢1
这是个好东西呀