Extjs 实现多行合并(rowspan)效果

引用
声明:
  本效果的本质,只是用css去除边框而已,不包含分组功能。
  代码在IE6-8, FF3下测试通过
  代码依赖于Extjs 3.x



1.加入css样式

Java代码  收藏代码
  1. /*rowspan grid合并行效果*/  
  2. .rowspan-grid .x-grid3-body .x-grid3-row {  
  3.     border:none;  
  4.     cursor:default;  
  5.     width:100%;  
  6. }  
  7. .rowspan-grid .x-grid3-header .x-grid3-cell{  
  8.     /*border-left: 2px solid transparent;*//*ie6的transparent下显示黑色?*/  
  9.     border-left: 2px solid #fff;  
  10. }  
  11. .rowspan-grid .x-grid3-body .x-grid3-row{  
  12.     overflow: hidden;  
  13.     border-right: 1px solid #ccc;  
  14. }  
  15. .rowspan-grid .x-grid3-body .x-grid3-cell {  
  16.     border: 1px solid #ccc;  
  17.     border-top:none;  
  18.     border-right:none;  
  19. }  
  20. .rowspan-grid .x-grid3-body .x-grid3-cell-first {  
  21.     /*border-left: 1px solid transparent;*/  
  22.     border-left: 1px solid #fff;  
  23. }  
  24. .rowspan-grid .x-grid3-body .rowspan-unborder {  
  25.     /*border-bottom:1px solid transparent;*/  
  26.     border-bottom:1px solid #fff;  
  27. }  
  28. .rowspan-grid .x-grid3-body .rowspan {  
  29.     border-bottom: 1px solid #ccc;  
  30. }  



2.引入Ext.ux.grid.RowspanView对象

Java代码  收藏代码
  1. Ext.ns('Ext.ux.grid');  
  2. /** 
  3.  * 实现grid的rowspan效果 
  4.  *  @author: tipx.iteye.com 
  5.  * 
  6.  *  1.在列模型里需要配置合并行的列中设置rowspan属性,如:{dataIndex:'xxx', header:'xxx', rowspan:3} //该列每三行合并一行 
  7.  *  2.为grid设置view属性 => view : new Ext.ux.grid.RowspanView() 
  8.  *  3.为grid设置cls属性 => cls : 'rowspan-grid' 
  9.  *  4.加入css样式 
  10.  */  
  11. Ext.ux.grid.RowspanView = Ext.extend(Ext.grid.GridView, {  
  12.     constructor: function(conf) {  
  13.         Ext.ux.grid.RowspanView.superclass.constructor.call(this, conf);  
  14.     },  
  15.     // private  
  16.     //清除合并的行中,非第一行的数据  
  17.     cleanRenderer : function(column, value, metaData, record, rowIndex, colIndex, store) {  
  18.         var rowspan = column.rowspan;  
  19.         if(!Ext.isEmpty(rowspan) && rowspan !== 0){  
  20.             if(rowIndex % rowspan !== 0){  
  21.                 return '';  
  22.             }  
  23.         }  
  24.         return column.renderer(value, metaData, record, rowIndex, colIndex, store);  
  25.     },  
  26.     // private  
  27.     doRender : function(cs, rs, ds, startRow, colCount, stripe){  
  28.         var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;  
  29.         var tstyle = 'width:'+this.getTotalWidth()+';';  
  30.         // buffers  
  31.         var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;  
  32.   
  33.         //cmConfig列模型  
  34.         var cmConfig = this.cm.config, rowspans=[];  
  35.         for(var i = 0, len = cmConfig.length; i < len; i++){  
  36.             rowspans.push(Math.max((cmConfig[i].rowspan || 0), 0));  
  37.         }  
  38.   
  39.         for(var j = 0, len = rs.length; j < len; j++){  
  40.             r = rs[j]; cb = [];  
  41.             var rowIndex = (j+startRow);  
  42.             for(var i = 0; i < colCount; i++){  
  43.                 c = cs[i];  
  44.                 p.id = c.id;  
  45.                 p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');  
  46.                 p.attr = p.cellAttr = "";  
  47.                 p.value = this.cleanRenderer(cmConfig[i], r.data[c.name], p, r, rowIndex, i, ds);  
  48.                 p.style = c.style;  
  49.                 if(Ext.isEmpty(p.value)){  
  50.                     p.value = "&#160;";  
  51.                 }  
  52.                 if(this.markDirty && r.dirty && typeof r.modified[c.name] !== 'undefined'){  
  53.                     p.css += ' x-grid3-dirty-cell';  
  54.                 }  
  55.                 //------------------------------------------------  
  56.                 //添加rowspan类,用样式实现合并行的效果  
  57.                 if(rowspans[i] !== 0){  
  58.                     //每rowspan行以及最后一行加上rowspan类,即加上border-bottom  
  59.                     if(j == (len-1) || (rowIndex+1) % rowspans[i] === 0){  
  60.                         p.css += ' rowspan';  
  61.                     }else{  
  62.                         p.css += ' rowspan-unborder';  
  63.                     }  
  64.                 }  
  65.                 //------------------------------------------------  
  66.                 cb[cb.length] = ct.apply(p);  
  67.             }  
  68.             var alt = [];  
  69.             if(stripe && ((rowIndex+1) % 2 === 0)){  
  70.                 alt[0] = "x-grid3-row-alt";  
  71.             }  
  72.             if(r.dirty){  
  73.                 alt[1] = " x-grid3-dirty-row";  
  74.             }  
  75.             rp.cols = colCount;  
  76.             if(this.getRowClass){  
  77.                 alt[2] = this.getRowClass(r, rowIndex, rp, ds);  
  78.             }  
  79.             rp.alt = alt.join(" ");  
  80.             rp.cells = cb.join("");  
  81.             buf[buf.length] =  rt.apply(rp);  
  82.         }  
  83.         return buf.join("");  
  84.     }  
  85. });  



3.创建grid
a. 创建列模型时,在需要合并行的列模型中加入配置:“rowspan:行数”(不含双引号)

Java代码  收藏代码
  1. {header: 'Company', dataIndex: 'company', rowspan:4}//本列每4行合并为1行  


b. 创建grid时,为grid配置:“cls:'rowspan-grid',view: new Ext.ux.grid.RowspanView()”

Java代码  收藏代码
  1. // create the Grid  
  2.   var grid = new Ext.grid.GridPanel({  
  3.       title: 'Extjs实现行合并(rowspan)效果',  
  4.       store: store,  
  5.       sm:sm,  
  6.       cm:cm,  
  7.       stripeRows: true,  
  8.       cls: 'rowspan-grid'//******必须配置此样式  
  9.       view: new Ext.ux.grid.RowspanView() //****使用view  
  10.   });  



4.预览效果



5.瑕疵
  由于ie6以外的浏览器的盒模型比较怪异(主因还是我自身不擅处理CSS),列头与数据列的边框有些对不齐(当前的效果已经是尽了最大努力了);

  由于“border-left: 2px solid transparent”中的transparent在ie6下显示黑色,本人对hack又不擅长(=。=都不知道自己到底擅长什么了),所以就干脆将 transparent全部用白色替换了(效果会差一些),如果能直接对ie6进行hack的话,应该会完美一点

6.注意
  从效果图上可以看出,合并行的区域,只显示合并行中的第一行数据,但这并不是分组效果!而是通过view中的cleanRenderer方法将“第x个rowspan区域的非第一行数据”直接返回空串而已。并不是将相同的数据合并!

7.demo下载
见附件 

posted @ 2013-04-18 22:01  牧之丨  阅读(5350)  评论(0编辑  收藏  举报