合并行的单元格 EXTJS
在Ext JS 4中, 如何合并行的单元格, 已经选取的时候只能选择某一列, 期望的效果如下:
在Ext JS 中, 合并表头的列有现成方案, 但是合并行单元格不是extjs的现有功能,这个需要底层扩展, 也就是使用 table 的跨行实现。
而Ext JS 7以及新版本和Ext JS4在最底层的Grid组成上又有差别,所以不同版本的实现又存在一些差异。
实现思路
实现思路主要是两个:
- 在底层使用 rowspan 合并
- 设置Grid的选取方式为 cellmodel
完整代码
1 /** 2 * @param {} grid 要合并单元格的grid对象 3 * @param {} cols 要合并哪几列 例如 [1,2] 4 */ 5 var mergeCells = function (grid, cols) { 6 //==>ExtJs4.2的<tbody>改到上层<table>的lastChild . <tbody>是各个<tr>的集合 7 var arrayTr = document.getElementById(grid.getId() + "-body").firstChild.firstChild.lastChild.getElementsByTagName('tr'); 8 var trCount = arrayTr.length; //<tr>总行数 9 var arrayTd; 10 var td; 11 12 //==>显示层将目标格的样式改为.display='none'; 13 var merge = function (rowspanObj, removeObjs)//定义合并函数 14 { 15 if (0 != rowspanObj.rowspan) { 16 arrayTd = arrayTr[rowspanObj.tr].getElementsByTagName("td"); //合并行 17 td = arrayTd[rowspanObj.td - 1]; 18 td.rowSpan = rowspanObj.rowspan; 19 td.vAlign = "middle"; 20 // td.style.font-size = '20px'; 21 // $(td).hide(); 22 $(td).css("font-size", "15px"); 23 $(td).attr("title", $(td).text()); 24 $(td).find('span').attr("title", $(td).text()); 25 $(td).css('color', 'rgb(148, 201, 36)'); 26 var height = $(td).innerHeight(); 27 if (removeObjs.length > 0) { 28 $(td).css("padding-top", height / 3); 29 // var showIndex = Math.ceil(removeObjs.length/2); 30 } 31 32 //隐身被合并的单元格 33 Ext.each(removeObjs, function (obj) { 34 arrayTd = arrayTr[obj.tr].getElementsByTagName("td"); 35 arrayTd[obj.td - 1].style.display = 'none'; 36 arrayTd[obj.td - 1].style.borderTop = "none"; 37 }); 38 39 } 40 }; 41 //==>显示层将目标格的样式改为.display='none'; 42 43 var rowspanObj = {}; //要进行跨列操作的td对象{tr:1,td:2,rowspan:5} 44 var removeObjs = []; //要进行删除的td对象[{tr:2,td:2},{tr:3,td:2}] 45 var col; 46 //==>逐列靠表内具体数值去合并各个<tr> (表内数值一样则合并) 47 48 try { 49 Ext.each(cols, function (colIndex) { 50 var rowspan = 1; 51 var divHtml = null;//单元格内的数值 52 for (var i = 0; i < trCount; i++)//==>从第一行数据0开始 53 { 54 //==>一个arrayTr[i]是一整行的所有数据, 一个arrayTd是 <td xxxx ><div>具体数值</div></td> , 55 arrayTd = arrayTr[i].getElementsByTagName("td"); 56 var cold = 0; 57 // Ext.each(arrayTd,function(Td){ //获取RowNumber列和check列 58 // if(Td.getAttribute("class").indexOf("x-grid-cell-special") != -1) 59 // cold++; 60 // }); 61 col = colIndex + cold;//跳过RowNumber列和check列 62 63 if (!divHtml) { 64 divHtml = arrayTd[col - 1].innerHTML; 65 divHtml = $(divHtml).text(); //==>拿到真正数值,相比Ext4.1多了一层<div> 66 rowspanObj = { tr: i, td: col, rowspan: rowspan } 67 } 68 else { 69 var cellText = arrayTd[col - 1].innerHTML; 70 cellText = $(cellText).text();//==>拿到真正数值 71 72 73 var addf = function () { 74 rowspanObj["rowspan"] = rowspanObj["rowspan"] + 1; 75 removeObjs.push({ tr: i, td: col }); 76 if (i == trCount - 1) { 77 merge(rowspanObj, removeObjs);//执行合并函数 78 } 79 }; 80 var mergef = function () { 81 merge(rowspanObj, removeObjs);//执行合并函数 82 divHtml = cellText; 83 rowspanObj = { tr: i, td: col, rowspan: rowspan } 84 removeObjs = []; 85 }; 86 87 if (cellText == divHtml) { 88 if (colIndex != cols[0]) { 89 var leftDisplay = arrayTd[col - 2].style.display;//判断左边单元格值是否已display 90 if (leftDisplay == 'none') { 91 addf(); 92 } 93 else { 94 mergef(); 95 } 96 } 97 else { 98 addf(); 99 } 100 } 101 else { 102 mergef(); 103 } 104 } 105 } 106 }); 107 } catch (e) { 108 console.log(e.message) 109 } 110 }; 111 112 113 114 115 Ext.onReady(function () { 116 117 var store = Ext.create('Ext.data.Store', { 118 storeId: 'myStore', 119 autoLoad: false, 120 fields: ['firstClass', 'secondClass'], 121 data: { 122 'items': 123 [{ 124 firstClass: '正极材料', 125 secondClass: '镍钴锰酸锂' 126 }, { 127 firstClass: '正极材料', 128 secondClass: '锰酸锂' 129 }, { 130 firstClass: '负极材料', 131 secondClass: '石墨' 132 }, { 133 firstClass: '负极材料', 134 secondClass: '六弗锰酸锂' 135 }] 136 }, 137 proxy: { 138 type: 'memory', 139 reader: { 140 type: 'json', 141 root: 'items' 142 } 143 } 144 }); 145 146 var grid = Ext.create('Ext.grid.Panel', { 147 renderTo: Ext.getBody(), 148 selType: 'cellmodel', 149 /*tbar: [{ 150 text: '单元格合并', 151 handler: function () { 152 mergeCells(grid, [1]); 153 } 154 }],*/ 155 id: 'mygrid', 156 columns: [{ 157 text: '一级分类', 158 dataIndex: 'firstClass' 159 }, { 160 text: '二级分类', 161 dataIndex: 'secondClass' 162 }], 163 store: store 164 }); 165 166 setTimeout(function(){ 167 mergeCells(grid, [1]); 168 },100) 169 /* grid.getStore().load(function(){ 170 alert('1'); 171 mergeCells(grid, [1]); 172 });*/ 173 });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2008-06-28 [导入]SubVersion 1.5
2008-06-28 [导入]Visual SourceSafe中的权限