treeTable实现排序

/*

 * 

 * TreeTable 0.1 - Client-side TreeTable Viewer!

 * @requires jQuery v1.3

 * 

 * Dual licensed under the MIT and GPL licenses:

 * http://www.opensource.org/licenses/mit-license.php

 * http://www.gnu.org/licenses/gpl.html

 *

 * 

 */



	(function($){

		$.extend({

			treetable: new function() {

			

				this.defaults = {

					id_col: 0,

					parent_col: 1,

					handle_col: 2,

					order_col: -1,

					open_img: "lib/plugin/treetable/images/minus.gif",

					close_img: "lib/plugin/treetable/images/plus.gif",

					expanded: true//@author GaoBing

				};

				

				//jquery的trim处理不了 产生的"空格"

				function trim(str){

					return str.replace(/(^[\s\xA0]*)|([\s\xA0]*$)/g, "");

				}

				

				this.construct = function(settings){

				

					if(this.size()!=1)return;//只处理一个表格

					

					if(this[0].tagName.toUpperCase()!="TBODY")return;//只应用于tbody

				

					var config = $.extend({}, $.treetable.defaults, settings);

					

					if(config.id_col==null || config.parent_col==null || config.handle_col==null ) return;

					

					var $this = $(this);

					var tr_arr = new Array();

					var tr_sort = new Array();

	

					//构建行对象数组

					$this.find("tr").each(function(){

						var id = $.trim($(this).find("td:eq("+config.id_col+")").text());

						var parent = $.trim($(this).find("td:eq("+config.parent_col+")").text());

						tr_arr.push({'id':id,'parent':parent,'level':0,'node':'leaf','expanded':config.expanded,'obj':$(this)});

					});

					var len = tr_arr.length;

					var level = 0;

					

					/*

					检查tr_arr中的每一行的父行是否再tr_sort中,

					如果有则插入到tr_sort的父行后,从tr_arr中删除

					直到tr_arr都为null,生成排好序的tr_sort

					*/

					while(len>0){

						for(var i=0;i<tr_arr.length;i++){

							var o = tr_arr[i];

							

							if(o==null)continue;

							

							if(o.parent==""){//根行直接压入tr_sort

								tr_sort.push(o);

								tr_arr[i]=null;

								len=len-1;

							}else{

								if (tr_sort.length > 0){

									for(var j=0;j<tr_sort.length;j++){

										if(tr_sort[j].id==o.parent){

											o.level = tr_sort[j].level+1;//从父行累计生成层次level

											tr_sort[j].node='node';

											tr_sort.splice(j+1,0,o);//数组插入

											tr_arr[i]=null;

											len=len-1;

											break;

										}

									}

								}else{

									for(var k=0;k<tr_arr.length;k++){

										var ok = tr_arr[k];

										if(ok == null) continue;

										if (o.id != ok.parent && ok.parent != ""){

											ok.level = tr_arr[k].level+1;

											tr_sort.push(ok);

											tr_arr[i]=null;

											len=len-1;

										}else{

											if (tr_sort[k]){

												o.level = tr_sort[k].level+1;//从父行累计生成层次level

												tr_sort[k].node='node';

												tr_sort.splice(k+1,0,o);//数组插入

												tr_arr[i]=null;

												len=len-1;

												break;

											}

										}

									}

								}

							}

						}

						level=level+1;

					}//while

		

					

					

					

					//展开事件动作函数

					var fn_click = function(){



						var id = trim($(this).parent().parent().find("td:eq("+config.id_col+")").text());//获取当前行ID

						var v = -1;

						for(var j=0;j<tr_sort.length;j++){

							var o = tr_sort[j];

							if(o.id==id){//在tr_sort找到行对象

						

								if(o.node=='leaf')return;

								

								v = o.level;

								var img = o.obj.find("td:eq("+config.handle_col+") img")[0];

								

								if(!o.expanded){//通过图标判断是展开还是收起

									img.src=config.open_img;

									o.expanded=true;

								}else{

									img.src=config.close_img;

									o.expanded=false;

								}

								

								var show = o.expanded;

								var f = false;//父行收起标志

								var tmp = 0;//父行的层次

								

								for(var i=j+1;i<tr_sort.length;i++){//根据level更新后续的子行

									o = tr_sort[i];

									

									var img = o.obj.find("td:eq("+config.handle_col+") img")[0];

									

									var t = !o.expanded;//判断是否是收起状态

									

									if(o.level>v && show){//展开操作

										if(!f&&!t){//父行未收起,且当前行是展开状态

											o.obj.show();

										}else if(!f&&t){//父行未收起,且当前行是收起状态

											tmp = o.level;

											f = true;

											o.obj.show();

										}else if(f&&o.level<=tmp){//同级的前一行是收起状态

											if(!t){

												f=false;

											}else{

												tmp = o.level;

											}

											o.obj.show();

										}else{

											;

										}

								

									}else if(o.level>v && !show){//收起操作则隐藏所以子行

										o.obj.hide();

									}else if(o.level<=v){//到达非子行,处理完毕

										break;

									}

								}

							

								break;

							}

						}

					};

				

					//重新绘制表格,添加展开动作图标

					for(var j=tr_sort.length-1;j>-1;j--){//prepend插入tbody内需使用反序

						var o = tr_sort[j];

						

						var img = $("<img src='"+config.open_img+"'>");

						img.click(fn_click);

						

						var tr=o.obj.find("td:eq("+config.handle_col+")");

						

						//避免重复添加图标

						var imgEle = tr.find("img");

						if(imgEle.length == 0){

							tr.prepend(" ");

							tr.prepend(img);

							var s = new Array((o.level+1)*5).join(" ");//生成缩进空格

							tr.prepend(s);

							

							$this.prepend(o.obj);

						}

						

					}//for

		

				

					/*

					 * @author GaoBing

					 * 是否展开 当expanded为false时,父节点收缩  

					 * */

					if(tr_sort.length > 0){

						for(var i=0;i<tr_sort.length;i++){

							var o = tr_sort[i];//行对象

							var img = o.obj.find("td:eq("+config.handle_col+") img");//父节点图标元素

							if(o.expanded == false){//收缩

								//检查是否有父节点,如有父节点则隐藏本行节点

								if (o.parent != ""){

									o.obj.hide();//隐藏子节点

								}

								//检查是否有子节点,有子节点则替换图标

								for(var j=0;j<tr_sort.length;j++){

									if (tr_sort[j].parent != "" && tr_sort[j].parent == o.id){//有子节点

										$(img).attr("src",config.close_img);//替换父节点图标

									}

								}

							}

						}

					}

					

					

				}//construct

			}//treetable



		});

		

		$.fn.extend({

			treetable: $.treetable.construct

		});

		

	})(jQuery);

	

	

	/** 

	 * @author GaoBing

	 * 功能:对树状表格进行排序 父节点在前 子节点在后 

	**/

	function treetable_sort(tableId,parentColumn){

		

		var trs = new Array();

		

		//拿到所有行

		$("#" + tableId + " tbody tr[role='row']").each(function(index){

			trs[index] = $(this).clone(true);

		});

		

		//清空之前的行数据

		$("#" + tableId + " tbody").empty();

		

		//递归

		sort_tr_root(trs,tableId,parentColumn);

		

	}

	

	/*根节点排序*/

	function sort_tr_root(trs,tableId,parentColumn){

		var rootArr = new Array();

		for(var i=0;i<trs.length;i++){

			if (null != trs[i]){

				var trsData = trs[i].attr("data");

				var trsDataObj = eval('(' + trsData + ')');

				var trsId = trsDataObj['id'];

				var trsParentId = trsDataObj[ parentColumn ];

				if (null == trsParentId || trsParentId == "" || undefined == trsParentId){//最外层的根

					trs[i].attr("id",trsId);

					$("#" + tableId + " tbody").append(trs[i]);

					rootArr.push(trs[i]);

					trs[i] = null;

				}

			}

		}

		

		//子节点排序

		var treeData = changeDataToMap(trs);

		var result = createSearchMap(trs,parentColumn);

		for(var i=0;i<rootArr.length;i++){

			var rootData = rootArr[i].attr("data");

			var rootDataObj = eval('(' + rootData + ')');

			var rootId = rootDataObj['id'];

			var rootParentId = rootDataObj[ parentColumn ];

			buildChild(tableId,treeData,result,rootId,rootParentId);

		}

		

	}

	

	function createSearchMap(data,parentColumn){

		//创建搜索键值对

		var result = {};

		for(var i=0;i<data.length;i++) {

			if (null != data[i]){

				var trsData = data[i].attr("data");

				var trsDataObj = eval('(' + trsData + ')');

				var trId = trsDataObj['id'];

				var trParentId = trsDataObj[parentColumn];

				if(trParentId){

					if(!result[trParentId] && trParentId != null && trParentId != ""){

						result[trParentId] = [];

					}

					result[trParentId].push(trId);

				}

			}

		}

		return result;

	}

	

	function changeDataToMap(trs){

		var deepMap = new Array();

		for(var i=0;i<trs.length;i++){

			if (null != trs[i]){

				var trsData = trs[i].attr("data");

				var trsDataObj = eval('(' + trsData + ')');

				var trId = trsDataObj['id'];

				if(trId){

					deepMap[trId] = trs[i];

				}

			}

		}

		return deepMap;

	}

	

	

	function buildChild(tableId,treeData,result,id,parentId){

		if (parentId){

			var trObj = treeData[id];

			trObj.attr("id",id);

			$("#" + tableId + " tbody tr[role=row][id=" + parentId + "]").after(trObj);

		}

		var childrenIds = result[id];

		if(childrenIds){

			for(var i=0;i<childrenIds.length;i++){

				buildChild(tableId,treeData,result,childrenIds[i],id);

			}

		}

	}

	

	

	/*判断是否包含某个元素*/

	Array.prototype.contains = function (element) { // 利用Array的原型prototype点出一个我想要封装的方法名contains

		for (var i = 0; i < this.length; i++) { 

			if (this[i] == element) { // 如果数组中某个元素和你想要测试的元素对象element相等,则证明数组中包含这个元素,返回true

				return true; 

			} 

		}

	}; 

	

	/** 

	 * @author GaoBing

	 * 功能:表格树 供datatable调用接口 

	**/

	function initTreeTable(obj){

		

		//参数

		var tableId = obj.tableId;//表格ID

		var tbodyId = obj.tbodyId;//表格中tbodyID

		var isExpanded = obj.isExpanded;//是否展开所有节点

		var viewConfig = obj.viewConfig;//展示配置

		var parentColumn = obj.parentColumn;//父列

		

		//排序 父节点排在子节点前面

		treetable_sort(tableId,parentColumn);

		

		//默认属性

    	$.treetable.defaults={

			id_col: viewConfig[0],//ID td列 {从0开始}

			parent_col: viewConfig[1],//父ID td列

			handle_col: viewConfig[2],//操作展开操作的 td列

			open_img: "lib/plugin/treetable/images/minus.gif",//展开时图标

			close_img: "lib/plugin/treetable/images/plus.gif",//收缩时图标

			expanded: isExpanded//true为展开,false为收缩

		};

    	

		//生成树

    	$("#" + tbodyId).treetable();

    	

		//隐藏数据列

		$("#" + tbodyId + " tr").find("td:eq(" + viewConfig[0] + ")").hide();

		$("#" + tbodyId + " tr").find("td:eq(" + viewConfig[1] + ")").hide();

		$("#" + tableId + " tr:eq(0)").find("th:eq(" + viewConfig[0] + ")").hide();

		$("#" + tableId + " tr:eq(0)").find("th:eq(" + viewConfig[1] + ")").hide();

	}

  

你可能感兴趣的:(table)