[js]表格转换为树形结构

/**
 * 表格工具
 * getCellPosition-获取单元格位置
 * getParentCells-获取单元格的所有上级单元格
 * getTree-返回表格的树形结构数据
 * 例子:
 * $('talbe#tab1').table2tree({});
 * var tree = $('talbe#tab1').table2tree('getTree');
 */
(function($){
	function init(target){
		var cells = [];
		var jq = $(target);
		var options = jq.table2tree('options');
		var trselector = 'tr';
		if(options.container){
			trselector = options.container + ' ' + trselector;
		}
		jq.find(trselector).each(function(row, domtr){
			var tr = $(this);
			cells[row] = [];
			var totalCol = 0;
			var mRowCells = [];
			if(row > 0){
				mRowCells = getMultiRowCells();
			}
			tr.find('th,td').each(initCell);
			
			function initCell(col, domtd){
				var colspan = domtd.colSpan;
				var rowspan = domtd.rowSpan;
				var colb = totalCol;
				if(row > 0){
					colb = getCellPosLeft();
				}	
				var cole = colb + colspan;
				var rowb = row;
				var rowe = row + rowspan;		
						
				cells[row][col] = {text:domtd.innerText, colspan:colspan, rowspan:rowspan, pos:{left:colb, right:cole, top:row, bottom:rowe}};
				totalCol = cole;			
				
				function getCellPosLeft(){
					var posLeft = 0;
					if(col > 0){
						posLeft = cells[row][col-1].pos.right;
					}
					for(var i = 0; i < mRowCells.length; i++){
						//若该位置被占用,继续叠加
						if(posLeft >= mRowCells[i].left && posLeft < mRowCells[i].right){
							posLeft += mRowCells[i].colspan;
						}
					}
					return posLeft;
				}			
			}
			
			function getMultiRowCells(){
				var mrcells = [];
				for(var i = 0; i < row; i++){
					for(var j = 0; j < cells[i].length; j++){
						var cell = cells[i][j];
						if(cell.rowspan > (row - i)){
							mrcells.push({colspan:cell.colspan,left:cell.pos.left,right:cell.pos.right});
						}
					}
				}
				return mrcells;
			}
		});
		if(cells.length){
			jq.data('table2tree', $.extend(jq.data('table2tree'),{cells:cells,tree:buildTree(jq,cells)}));
		}
	}
	
	function buildTree(jq, cells){
		var options = jq.data('table2tree').options;
		var tree = {id:options.rootId, text:options.rootName, childNodes:[]};
		for(var i = 0; i < cells[0].length; i++){
			var node = {text:cells[0][i].text};
			var childNodes = getChildren(0, i, cells);
			if(childNodes && childNodes.length){
				node.childNodes = childNodes;
			}
			tree.childNodes.push(node);
		}
		return tree;
	}
	
	function getChildren(row, col, cells){
		var thiscell = cells[row][col];
		if(thiscell.pos.bottom == cells.length){
			return;
		}
		var thispos = cells[row][col].pos;
		var childrow = row + thiscell.rowspan;
		var nodes = [];
		for(var j = 0; j < cells[childrow].length; j++){
			var pos = cells[childrow][j].pos;
			if(thispos.left <= pos.left && thispos.right >= pos.right){
				var node = {text:cells[childrow][j].text};
				var childNodes = getChildren(childrow,j,cells);
				if(childNodes && childNodes.length){
					node.childNodes = childNodes;
				}
				nodes.push(node);
			}
		}
		return nodes;
	}
	
	//获取单元格位置
	function getCellPosition(td){
		if(!td){
			return;
		}
		var nodeName = td.nodeName;
		if(nodeName != 'TD' && nodeName != 'TH'){
			return;
		}
		var jqtd = $(td);
		var colIndex = jqtd.prevAll().length;
		var rowIndex = $('table tr').has(jqtd).prevAll().length;
		return {row:rowIndex, col:colIndex};
	}
	
	//获取所有上级单元格的位置
	function getParentCells(td, cells){
		var cellpos = getCellPosition(td);
		if(!cellpos || cellpos.row == 0){
			return;
		}
		var thispos = cells[cellpos.row][cellpos.col].pos;
		var upcells = [];
		for(var i = cellpos.row - 1; i >= 0; i--){
			for(var j = 0; j < cells[i].length; j++){
				var pos = cells[i][j].pos;
				if(thispos.left >= pos.left && thispos.right <= pos.right){
					upcells.push({row:i, col:j});
					thispos = pos;
					break;
				}
			}
		}
		return upcells;
	}
	
	function isLoaded(jq){
		var state = jq.data('table2tree');
		if(state && state.cells){
			return true;
		}else{
			return false;
		}
	}
	
	$.fn.table2tree = function(options, param){
		if (typeof options == 'string'){
			var method = $.fn.table2tree.methods[options];
			if (method){
				return method(this, param);
			}
		}
		
		options = options || {};
		return this.each(function(){
			var state = $.data(this, 'table2tree');
			if (state){
				$.extend(state.options, options);
			} else {
				$.data(this, 'table2tree', {
					options: $.extend({}, $.fn.table2tree.defaults, options)
				});
			}
			init(this);
		});
	};
	
	$.fn.table2tree.methods = {
		options: function(jq){
			return $.data(jq[0], 'table2tree').options;
		},getCellPosition: function(jq, target){
			return getCellPosition(target);
		},getParentCells: function(jq, target){
			if(isLoaded(jq)){
				return getParentCells(target, jq.data('table2tree').cells);
			}
		},getTree: function(jq){
			if(isLoaded(jq)){
				return jq.data('table2tree').tree;
			}
		},isLoaded: isLoaded
	};
	
	$.fn.table2tree.defaults = {
		author:'attwice@qq.com',
		date:'2013/12/11',	
		container: '',		//顶层容器:'',thead,tbody
		rootId:'-1',		//树根节点ID
		rootName:'树形表格'	//树更节点名称
	};
})(jQuery);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值