ExtJS 4.2 Grid组件单元格合并的方法


Posted in Javascript onOctober 12, 2016

ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能。

目录

1. 原理

2. 多列合并

3. 代码与在线演示

1. 原理

1.1 HTML代码分析

首先创建一个Grid组件,然后查看下的HTML源码。

1.1.1 Grid组件

ExtJS 4.2 Grid组件单元格合并的方法

1.1.2 HTML代码

ExtJS 4.2 Grid组件单元格合并的方法

从这些代码中可以看出,Grid组件可分为grid-header和grid-body 两块区域(若含有工具栏和分页栏,它们都会含有各自的独立区域)。

其中grid-body包含了许多tr元素,每一个tr都是代表Grid组件中的一行数据;每个tr内部都包含了许多td,每个td表示一个单元格。

1.1.3 结构图

ExtJS 4.2 Grid组件单元格合并的方法

1.2 原理

1.2.1 步骤说明

具体的操作是针对tr元素,步骤如下:

1) 比较第一行tr与第二行tr的某个td的值,若两行的值相等:设置第一行tr的td的rowspan属性的值+1;设置第二行tr的td隐藏。

2) 比较第一行tr与第三行tr的某个td的值,若两行的值相等:设置第一行tr的td的rowspan属性的值+1;设置第三行tr的td隐藏。

3) 重复上面的步骤,若两行的值不相等,就跳过本次比较,进行下一次比较:当前行与下一行进行比较。

1.2.2 示例

1) tr1与tr2比较,两者值相等:设置tr1的rowspan属性的值+1;设置第tr2的td隐藏。

ExtJS 4.2 Grid组件单元格合并的方法

2)tr1与tr3比较,两者值相等:设置tr1的rowspan属性的值+1;设置第tr3的td隐藏。

ExtJS 4.2 Grid组件单元格合并的方法

3) tr1与tr4比较,两者的td不相等。跳过本次比较,进行下一次比较:tr4与tr5比较(当前行与下一行进行比较)。

ExtJS 4.2 Grid组件单元格合并的方法

2.多列合并

Gird的合并可分为单列合并和多列合并,其中多列合并可分为两种:

第一种:逐个列合并。

第二种:相同列合并。

2.1 逐个列合并

说明:每个列在前面列合并的前提下可分别合并。

示例:

ExtJS 4.2 Grid组件单元格合并的方法

2.2 全部列合并

说明:只有相邻tr所指定的td都相同才会进行合并。

示例:

ExtJS 4.2 Grid组件单元格合并的方法

3. 代码与在线演示

3.1 代码

 /**
* 合并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指向当前列
  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';; // 纵向居中
   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;
  }
  }
 }
 }
} 

3.2 在线演示

在线演示:http://www.akmsg.com/ExtJS/index.html#App.Demo.MergeGridTab

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS 自定义带默认值的函数
Jul 21 Javascript
一些有用的JavaScript和jQuery的片段分享
Aug 23 Javascript
jQuery学习笔记之总体架构
Jun 03 Javascript
jQuery实现下拉框选择图片功能实例
Aug 08 Javascript
浅谈javascript基础之客户端事件驱动
Jun 10 Javascript
JavaScript仿聊天室聊天记录
Dec 27 Javascript
详解用webpack2.0构建vue2.0超详细精简版
Apr 05 Javascript
微信小程序 开发MAP(地图)实例详解
Jun 27 Javascript
webpack 1.x升级过程中的踩坑总结大全
Aug 09 Javascript
JavaScript中使用Async实现异步控制
Aug 15 Javascript
react中的ajax封装实例详解
Oct 17 Javascript
node.js的exports、module.exports与ES6的export、export default深入详解
Oct 26 Javascript
JS代码实现百度地图 画圆 删除标注
Oct 12 #Javascript
如何使用jquery实现文字上下滚动效果
Oct 12 #Javascript
微信js-sdk界面操作接口用法示例
Oct 12 #Javascript
微信小程序 location API接口详解及实例代码
Oct 12 #Javascript
webpack+vue.js实现组件化详解
Oct 12 #Javascript
微信小程序 加载 app-service.js 错误解决方法
Oct 12 #Javascript
微信js-sdk上传与下载图片接口用法示例
Oct 12 #Javascript
You might like
PHP令牌 Token改进版
2008/07/18 PHP
php数组函数序列之sort() 对数组的元素值进行升序排序
2011/11/02 PHP
php实现文件上传基本验证
2020/03/04 PHP
javascript tips提示框组件实现代码
2010/11/19 Javascript
javascript 得到文件后缀名的思路及实现
2020/05/09 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
微信小程序实现锚点定位楼层跳跃的实例
2017/05/18 Javascript
JS检测是否可以访问公网服务器功能代码
2017/06/19 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
JavaScript 隐性类型转换步骤浅析
2018/03/15 Javascript
详解vuex commit保存数据技巧
2018/12/25 Javascript
JS实现选项卡效果的代码实例
2019/05/20 Javascript
Node.js 路由的实现方法
2019/06/05 Javascript
python循环监控远程端口的方法
2015/03/14 Python
Python环境变量设置方法
2016/08/28 Python
Python基于回溯法子集树模板解决找零问题示例
2017/09/11 Python
python如何重载模块实例解析
2018/01/25 Python
Django 实现下载文件功能的示例
2018/03/06 Python
python贪婪匹配以及多行匹配的实例讲解
2018/04/19 Python
Python 数据处理库 pandas进阶教程
2018/04/21 Python
python实现点对点聊天程序
2018/07/28 Python
在Python 中实现图片加框和加字的方法
2019/01/26 Python
利用python-pypcap抓取带VLAN标签的数据包方法
2019/07/23 Python
Python根据服务获取端口号的方法
2019/09/25 Python
Python 通过监听端口实现唯一脚本运行方式
2020/05/05 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
python与c语言的语法有哪些不一样的
2020/09/13 Python
澳大利亚窗帘商店:Curtain Wonderland
2019/12/01 全球购物
门前三包责任书
2014/04/15 职场文书
小学感恩教育活动总结
2014/07/07 职场文书
离婚协议书应该怎么写
2014/10/12 职场文书
批评与自我批评总结
2014/10/17 职场文书
教师党员整改措施
2014/10/24 职场文书
计生个人工作总结
2015/02/28 职场文书
经典励志格言:每日一句,让你每天充满能量
2019/08/16 职场文书
Android开发之底部导航栏的快速实现
2022/04/28 Java/Android