合併行的單元格 EXTJS

在Ext JS 4中, 如何合併行的單元格, 已經選取的時候只能選擇某一列, 期望的效果如下:

在Ext JS 中, 合併表頭的列有現成方案, 但是合併行單元格不是extjs的現有功能,這個需要底層擴展, 也就是使用 table 的跨行實現。
而Ext JS 7以及新版本和Ext JS4在最底層的Grid組成上又有差別,所以不同版本的實現又存在一些差異。

實現思路

實現思路主要是兩個:

  1. 在底層使用 rowspan 合併
  2. 設置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 });

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章