表格背景颜色

//在viewConfig 的 getRowClass中
//Wb预定义行背景色种类:wb_red_row, wb_green_row, wb_blue_row, wb_yellow_row, wb_hotpink_row, wb_gold_row, wb_bisque_row, wb_aqua_row
var cls, finalMoney = record.get('FINAL_MONEY');
if (finalMoney == '0'||finalMoney==null)
cls = '';
else
cls = '';
return cls;表格中文字格式
//initialize中加入
Ext.util.CSS.createStyleSheet(".font_red{color:red}","font_red");
//如果是grid表格的背景
Ext.util.CSS.createStyleSheet(".xxx .x-grid-cell {background-color: red}","xxx");
//在viewConfig 的 getRowClass中
//Wb预定义行背景色种类:wb_red_row, wb_green_row, wb_blue_row, wb_yellow_row, wb_hotpink_row, wb_gold_row, wb_bisque_row, wb_aqua_row
var cls, finalMoney = record.get('FINAL_MONEY');
if (finalMoney == '0'||finalMoney==null)
cls = '';
else
cls = '';
return cls;表格合计



// features 中放入feature
// feature 中的 ftype 设置分别表示统计和分组统计
//summaryRenderer代表最终输出的格式 可改变 字体和背景
//summaryType可选 求和 平均等选中合计
grid/bottomHtml
<lable id='underDiv' style = 'margin-left:330px;font-weight:bold;'></lable>tagEvent
{
select: function(editor, e, eOpts) { //e是要选中的行
var resc = app.unRcvGrid.getSelection();
showTotal(resc, "unGridDiv222");
},
deselect: function(editor, e, eOpts) { //e是取消的行
var resc = app.unRcvGrid.getSelection();
showTotal(resc, "unGridDiv222");
}
}function showTotal(recs, divId){
var usd = 0, cny = 0;
Wb.each(recs, function(one) {
if (one.data.CURRENCY === 'USD') { //美元合计
usd += one.data.MONEY;
}
if (one.data.CURRENCY === 'CNY') { //人民币合计
cny += one.data.MONEY;
}
});
var context = '选中合计:';
context += " CNY:<font color='red'>" + Wb.format(cny, '0,000.00')+"</font>";
context += " USD:<font color='red'>" + Wb.format(usd, '0,000.00')+"</font>";
document.getElementById(divId).innerHTML = context;
}表格分组



可编辑表格判断某行某一列修改没修改
var recsm = Wb.getModified(app.gridContract);
var flag = 0;
Wb.each(recsm.update, function(one) {
if (!Wb.isEmpty(one.APPLYTIM)) {
if (!Wb.isEmpty(one.RELEASE_NO) && one.RELEASE_NO != one["#RELEASE_NO"]) {
//修改了外放箱号,可执行
} else {
flag = 1;
}
}
});可编辑式表格控制符合某种条件的行不可编辑
在 grid 的 tagEvents 事件中添加如下代码,判断条件以实际情况而定
{
beforeedit: function(editor, e, eOpts) {
if(e.record.data.AC_CODE=='CNH004502'){
return false;//不可编辑
}else{
return true;//可以编辑
}
}
}为某一列添加背景色
在该列的renderer方法里设置
metaData.style='background-color:#fff;';
return '<span style="color:#f00">'+value+'</span>';//修改字的颜色为表格中单元格添加点击事件
增加事件
//首先在we_debug.js中添加以下方法
columnClick:function(view,e,columnname,func){
var column = view.getHeaderByCell(e.getTarget(view.getCellSelector()));
if(column && column.dataIndex == columnname){
func();
}
},//grid的itemclick事件添加以下代码
Wb.columnClick(view,e,"CARGO_NAM",function(){
if(!Wb.isEmpty(record.data.SHIP_CARGO_NO))
return;
Wb.reset(app.winTrust);
app.winTrust.show();
...//方法处理
});使用actioncolumn
//handler中写入点击后执行函数
setTimeout(function() {
app.sealWin.show();
var id = record.data.ID;
app.sealGrid.store.load({
params: {
cntrId: id
}
});
}, 100);鼠标悬浮某单元格时显示全部信息
//在某列column的renerder属性添加以下代码
metaData.tdAttr = 'data-qtip="' + Ext.String.htmlEncode(value) + '"'; //给每一个Cell添加tooltip效果
return value;大数据虚拟渲染
bufferedrenderer 是 Ext Grid 的虚拟行渲染插件。它只创建当前可视区域及前后缓冲区的行 DOM;滚动时复用和更新这些行,而不是为每条记录同时创建页面元素。
适用于固定或基本固定行高的普通表格。行展开、频繁变化的自动换行行高、复杂合并单元格等场景可能影响滚动定位,应单独验证。
本地数据测试
插件配置加在 Grid 上,fields 配置加在 Grid 下的 Store 上。下面模块点击 check 后一次写入 10 万条记录,用于验证表格的渲染和滚动性能。
module = {
itemId: "module",
items: [{
itemId: "viewport1",
layout: "fit",
items: [{
itemId: "grid1",
pagingBar: false,
plugins: {
ptype: "bufferedrenderer",
leadingBufferZone: 200,
trailingBufferZone: 100
},
items: [{
itemId: "tbar",
items: [{
iconCls: "accept_icon",
itemId: "item1",
text: "check",
events: {
click: function(item) {
var store = item.up("grid").store;
var rows = new Array(100000);
var i;
for (i = 0; i < 100000; i++) {
rows[i] = {
ID: i + 1,
SEX: i % 2 === 0 ? "男" : "女"
};
}
store.loadData(rows, false);
}
}
}]
}, {
itemId: "store",
fields: ["ID", "SEX"]
}, {
itemId: "columns",
items: [{
dataIndex: "ID",
itemId: "IDCol",
text: "主键",
width: 120
}, {
dataIndex: "SEX",
itemId: "SEXCol",
text: "性别",
width: 100
}]
}]
}]
}]
};不要在循环中执行 store.add()。每次调用都会触发 Store 和 Grid 的更新;先构建数组,再执行一次 store.loadData(rows, false) 才是用于批量测试和导入的合适方式。
此例仍会将 10 万条 Model 保留在浏览器内存中,只是避免创建 10 万行 DOM。因此它用于验证渲染性能,不是生产环境加载海量数据的最终方案。
URL 数据源
对于生产数据,将分页、排序和筛选交由服务端处理。Grid 继续配置 bufferedrenderer,并在 Store 上启用缓冲加载:
{
itemId: "grid1",
pagingBar: false,
plugins: {
ptype: "bufferedrenderer",
leadingBufferZone: 200,
trailingBufferZone: 100
},
items: [{
itemId: "store",
url: "m?xwl=demo/order/query",
fields: ["ID", "SEX"],
buffered: true,
pageSize: 100,
purgePageCount: 5,
remoteSort: true,
remoteFilter: true
}]
}Store 会以 start 和 limit 请求数据。服务端必须使用这两个参数分页查询,并在响应中提供当前页记录和总记录数。例如:
{
"data": [
{ "ID": 1, "SEX": "男" }
],
"total": 100000
}若接口仍一次返回全部记录,不要配置 buffered: true;仅使用 Grid 插件即可减少 DOM 数量。启用 buffered: true 前,也要确认当前 Ext Store Reader 的记录数组字段和总数字段名称与接口响应一致。
参数建议
| 配置 | 建议值 | 作用 |
|---|---|---|
pageSize |
100 |
每次从服务端读取的记录数。可根据单行数据大小在 50 到 200 间调整。 |
leadingBufferZone |
200 |
当前视口之后预先渲染的行数,降低向下滚动时的空白感。 |
trailingBufferZone |
100 |
当前视口之前保留的行数,改善向上回滚。 |
purgePageCount |
5 |
Store 缓存的页数,限制客户端内存占用。 |
不要同时使用传统分页栏和缓冲滚动作为同一张 Grid 的主导航方式。前者适合可明确跳页的业务表格,后者适合持续浏览大量记录的场景。
grid数据以数组形式传参到wb数据层
//参数获取
cntrsdata: app.gridReceipt.store.data.items.map(function(r) {
return r.data;
})
//wb数据层接收示例
cntrsdata = Wb.decode(data.cntrsdata); //grid数据给表格某行某列赋值
var rec = app.workloadGrid.getSelection()[0];//获取当前选中的行
rec.set('PROJECT_NAME',"sssss");//给该行某一列赋值动态选中表格行
app.gridxxx.getSelectionModel().select(records[0]);//选中第一行
var index = app.gridxxx.store.find("ID","123");//选中ID为123的行
app.gridxxx.getSelectionModel().select(index);//选中第一行
//选中某些符合条件的行
Wb.request({
url: 'm?xwl=imtos/basecode/C_Client/selectTypeByClientType',
params: {
ID:clientId
},
success: function(resp) {
var respArr = JSON.parse(resp.responseText).rows;
var roleRec, selRecs = [];
console.log(respArr);
Wb.each(respArr, function(rec) {
roleRec = Wb.find(app.gridmessage.store, 'TYPE_CODE', rec.CLIENT_TYPE_CODE);
if (roleRec)
selRecs.push(roleRec);
});
app.gridmessage.setSelection(selRecs);
}
});表格内容竖向展示
//在需要竖向展示的列的render方法中添加以下代码
return '<div style="writing-mode:tb-rl">'+value+'</div>'表格前加复选框多选时,禁止点击单元格(数据行)选择,只能点击复选框选择
//在grid的selModel属性中添加以下代码
new Ext.selection.CheckboxModel({ checkOnly: true })合并行

mergeGrid(app.gridFee, [2,3,4], true);//列标从0开始
/**
* 合并Grid的数据列
* @param grid {Ext.Grid.Panel} 需要合并的Grid
* @param colIndexArray {Array} 需要合并列的Index(序号)数组;从0开始计数,序号也包含。
* @param isAllSome {Boolean} 是否2个tr的colIndexArray必须完成一样才能进行合并。true:完成一样;false:不完全一样
*/
function mergeGrid(grid, colIndexArray, isAllSome) {
isAllSome = isAllSome == undefined ? true : isAllSome; // 默认为true
// 1.是否含有数据
var gridView = document.getElementById(grid.getView().getId() + '-body');
if (gridView == null) {
return;
}
// 2.获取Grid的所有tr
var trArray = [];
if (grid.layout.type == 'table') { // 若是table部署方式,获取的tr方式如下
trArray = gridView.childNodes;
} else {
trArray = gridView.getElementsByTagName('tr');
}
// 3.进行合并操作
if (isAllSome) { // 3.1 全部列合并:只有相邻tr所指定的td都相同才会进行合并
var lastTr = trArray[0]; // 指向第一行
// 1)遍历grid的tr,从第二个数据行开始
for (var i = 1, trLength = trArray.length; i < trLength; i++) {
var thisTr = trArray[i];
var isPass = true; // 是否验证通过
// 2)遍历需要合并的列
for (var j = 0, colArrayLength = colIndexArray.length; j < colArrayLength; j++) {
var colIndex = colIndexArray[j];
// 3)比较2个td的列是否匹配,若不匹配,就把last指向当前列
// console.info(lastTr.childNodes[colIndex].innerText);
// console.info(thisTr.childNodes[colIndex].innerText);
if(colIndex != 11 && colIndex != 16){
if (lastTr.childNodes[colIndex].innerText != thisTr.childNodes[colIndex].innerText) {
lastTr = thisTr;
isPass = false;
break;
}
}
}
// 4)若colIndexArray验证通过,就把当前行合并到'合并行'
if (isPass) {
for (var j = 0, colArrayLength = colIndexArray.length; j < colArrayLength; j++) {
var colIndex = colIndexArray[j];
// 5)设置合并行的td rowspan属性
if (lastTr.childNodes[colIndex].hasAttribute('rowspan')) {
var rowspan = lastTr.childNodes[colIndex].getAttribute('rowspan') - 0;
rowspan++;
lastTr.childNodes[colIndex].setAttribute('rowspan', rowspan);
} else {
lastTr.childNodes[colIndex].setAttribute('rowspan', '2');
}
// lastTr.childNodes[colIndex].style['text-align'] = 'center';; // 水平居中
lastTr.childNodes[colIndex].style['vertical-align'] = 'middle'; // 纵向居中
//lastTr.childNodes[colIndex].style['vertical-align'] = 'top'; // 纵向居中
thisTr.childNodes[colIndex].style.display = 'none';
}
}
}
} else { // 3.2 逐个列合并:每个列在前面列合并的前提下可分别合并
// 1)遍历列的序号数组
for (var i = 0, colArrayLength = colIndexArray.length; i < colArrayLength; i++) {
var colIndex = colIndexArray[i];
var lastTr = trArray[0]; // 合并tr,默认为第一行数据
// 2)遍历grid的tr,从第二个数据行开始
for (var j = 1, trLength = trArray.length; j < trLength; j++) {
var thisTr = trArray[j];
// 3)2个tr的td内容一样
if (lastTr.childNodes[colIndex].innerText == thisTr.childNodes[colIndex].innerText) {
// 4)若前面的td未合并,后面的td都不进行合并操作
if (i > 0 && thisTr.childNodes[colIndexArray[i - 1]].style.display != 'none') {
lastTr = thisTr;
continue;
} else {
// 5)符合条件合并td
if (lastTr.childNodes[colIndex].hasAttribute('rowspan')) {
var rowspan = lastTr.childNodes[colIndex].getAttribute('rowspan') - 0;
rowspan++;
lastTr.childNodes[colIndex].setAttribute('rowspan', rowspan);
} else {
lastTr.childNodes[colIndex].setAttribute('rowspan', '2');
}
//lastTr.childNodes[colIndex].style['text-align'] = 'center'; // 水平居中
lastTr.childNodes[colIndex].style['vertical-align'] = 'middle'; // 纵向居中
thisTr.childNodes[colIndex].style.display = 'none'; // 当前行隐藏
}
} else {
// 5)2个tr的td内容不一样
lastTr = thisTr;
}
}
}
}
}表格列展示位复选框形式

//tagConfigs属性添加以下代码
{
getValue: function() {
if (this.value==true||this.value=='1') {
return 1;
} else {
return 0;
}
}
}
//该列 字段查询语句要做转数字:to_number(HIRE_FLAG,'9') HIRE_FLAG符合条件的行禁止选中

if(record.data.DELIVERY_FLAG !='1'&&record.data.DELIVERY_FLAG !=1){
return true;
}else{
return false;
}表格后台分页


SELECT * FROM (
SELECT ROWNUM AS rowno, t.*
FROM emp t
WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')
AND TO_DATE ('20060731', 'yyyymmdd')
AND ROWNUM <= {?bigint.endIndex?}) table_alias
WHERE table_alias.rowno >= {?bigint.beginIndex?};分组合计小计
(1)gird增加合计和分组合计控件

groupingsummary属性配置如下,summary为常规配置

(2)页面区别“合计”和“小计”字眼

var re = summaryData._featureObject instanceof Ext.grid.feature.Summary ? '合计:' : '小计:';
return "<span style='font-weight:bold;'>" + re + "</span>";(3)按某个属性合计显示,该实例中是以箱尺寸分类显示
//在需要显示的列的summaryRenderer中添加代码
/**
* 合计小计按尺寸自定义显示。
*/
var cntr20 = 0,
cntr40 = 0;
if (summaryData._featureObject instanceof Ext.grid.feature.GroupingSummary) { //小计
if (summaryData.CNTR_NUM > 0) {
app.coutStore.each(function(rec) {
if (rec.data.CNTR_NUM > 0) {
if (rec.data.SIZE_CODE === '20') {
cntr20 += rec.data.CNTR_NUM;
} else if (rec.data.SIZE_CODE === '40') {
cntr40 += rec.data.CNTR_NUM;
}
}
});
} else if (summaryData.CNTR_NUM < 0) {
app.coutStore.each(function(rec) {
if (rec.data.CNTR_NUM < 0) {
if (rec.data.SIZE_CODE === '20') {
cntr20 += rec.data.CNTR_NUM;
} else if (rec.data.SIZE_CODE === '40') {
cntr40 += rec.data.CNTR_NUM;
}
}
});
}
} else if (summaryData._featureObject instanceof Ext.grid.feature.Summary) { //合计
app.coutStore.each(function(rec) {
if (rec.data.SIZE_CODE === '20') {
cntr20 += rec.data.CNTR_NUM;
} else if (rec.data.SIZE_CODE === '40') {
cntr40 += rec.data.CNTR_NUM;
}
});
}
return Wb.format("<span style='font-weight:bold;'>" + cntr20 + "<br>" + cntr40 + "<br>{0}</span>", value);满足条件才可进行编辑表格
grid /tagEvent
beforeedit: function(editor, e, eOpts) {
//条件
var condition = e.record.data.xxx;
//控制的字段
var field = e.field;
if(e.field==""&&condition=""){
return false;
}else{
return true;
}
}对单元格中的action进行隐藏
if (record.get('SEX') !=2) {
return 'x-hidden';
} else {
return '';
}隐藏某一列数据
app.xxgrid.down('#BILL_NOCol').hide()grid上单元格的悬浮显示
//
function showTip(data, metadata, record_start, rowindex, columnindex, store) {
if (!Wb.isEmpty(data)) { // 此处对空白文本做过滤。
metadata.tdAttr = "data-qtip='" + data + "'";
return data;
}
}
//renderer
return showTip(record.data.STATE_NOTE_ERROR, metaData, record, rowIndex, colIndex, store);单元格换行 单元格文字颜色
//首先要够长
value=value.replaceAll('\n','</br>');
value=value.replaceAll('新增','<font color="red">新增</font>');
value=value.replaceAll('更新','<font color="red">更新</font>');
value=value.replaceAll('删除','<font color="red">删除</font>');
return value;