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
这是个好东西呀