/**
* 表格工具
* 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);