一:
首先说明算法非原创, 感谢 http://blog.csdn.net/kunoy/article/details/7829395 提供了绝大部分思路 ,
我这儿就是改改代码 使4.1的代码能适应在4.2里而已.
只是看到网上目前还没有4.2合并单元格方法 , 贴出来抛砖引玉 ,也算是全宇宙首发吧 哈哈.
这个方法并不完美(文末会提到) , 还请高手们帮忙改进~
/==>June8
/**
* ruantao1989
* 合并单元格
* @param {} grid 要合并单元格的grid对象
* @param {} cols 要合并哪几列 例如 [1,2,4]
*/
var mergeCells = function( grid , cols )
{
//==>ExtJs4.2的<tbody>改到上层<table>的lastChild . <tbody>是各个<tr>的集合
var arrayTr = document.getElementById(grid.getId()+"-body").firstChild.firstChild.lastChild.getElementsByTagName('tr');
var trCount = arrayTr.length; //<tr>总行数
var arrayTd;
var td;
//==>显示层将目标格的样式改为.display='none';
var merge = function( rowspanObj , removeObjs )//定义合并函数
{
if( 0 != rowspanObj.rowspan )
{
arrayTd = arrayTr[ rowspanObj.tr ].getElementsByTagName("td"); //合并行
td = arrayTd[rowspanObj.td-1];
td.rowSpan = rowspanObj.rowspan;
td.vAlign = "middle";
//隐身被合并的单元格
Ext.each(removeObjs,function(obj)
{
arrayTd = arrayTr[obj.tr].getElementsByTagName("td");
arrayTd[obj.td-1].style.display='none';
});
}
};
//==>显示层将目标格的样式改为.display='none';
var rowspanObj = {}; //要进行跨列操作的td对象{tr:1,td:2,rowspan:5}
var removeObjs = []; //要进行删除的td对象[{tr:2,td:2},{tr:3,td:2}]
var col;
//==>逐列靠表内具体数值去合并各个<tr> (表内数值一样则合并)
Ext.each( cols , function( colIndex )
{
var rowspan = 1;
var divHtml = null;//单元格内的数值
for( var i=0 ; i < trCount ; i++)//==>从第一行数据0开始
{
//==>一个arrayTr[i]是一整行的所有数据, 一个arrayTd是 <td xxxx ><div>具体数值</div></td> ,
arrayTd = arrayTr[i].getElementsByTagName("td");
var cold=0;
// Ext.each(arrayTd,function(Td){ //获取RowNumber列和check列
// if(Td.getAttribute("class").indexOf("x-grid-cell-special") != -1)
// cold++;
// });
col = colIndex + cold;//跳过RowNumber列和check列
if( !divHtml )
{
divHtml = arrayTd[col-1].innerHTML;
divHtml = $(divHtml).text(); //==>拿到真正数值,相比Ext4.1多了一层<div>
rowspanObj = { tr:i,td:col,rowspan:rowspan }
}
else
{
var cellText = arrayTd[col-1].innerHTML;
cellText = $(cellText).text();//==>拿到真正数值
var addf = function()
{
rowspanObj["rowspan"] = rowspanObj["rowspan"]+1;
removeObjs.push({ tr:i,td:col });
if( i == trCount-1)
{
merge(rowspanObj,removeObjs);//执行合并函数
}
};
var mergef = function()
{
merge(rowspanObj,removeObjs);//执行合并函数
divHtml = cellText;
rowspanObj = {tr:i,td:col,rowspan:rowspan}
removeObjs = [];
};
if( cellText == divHtml )
{
if( colIndex != cols[0] )
{
var leftDisplay = arrayTd[col-2].style.display;//判断左边单元格值是否已display
if( leftDisplay == 'none' )
{
addf();
}
else
{
mergef();
}
}
else
{
addf();
}
}
else
{
mergef();
}
}
}
});
};
//==>June8
三: view层里的使用
//==>监听load , 执行合并单元格
Ext.getCmp('fxxxGrid').getStore().on('load',function(){
//==>防止Grid重绘, 人工延迟
setTimeout(function(){
if( state == "xxx" )
{
mergeCells( Ext.getCmp('fxxxGrid') , [1,2,3,4,5,6] );
}
},150);
});
四: 杂项
1.按此方法合并之后 , 添加新数据行后会错位 . 目前还没想到好办法解决 .
建议合并的表格只用于展示数据 , 也就是只读表 .
2.在低版本IE ( IE8以下 ) 中合并之后的单元格 , selType如果用: 'cellmodel', 双击单元格后 ,所选格会偏移(chrome中无此问题) .
建议应用合并的表格用rowmodel (默认值)