treeTable实现排序

treeTable实现排序/***TreeTable0.1-Client-sideTreeTableViewer!*@requiresjQueryv1.3**DuallicensedundertheMITandGPLlicenses:*http://www.opensource.org/licenses/mit-license.php…

大家好,又见面了,我是你们的朋友全栈君。

/*
 * 
 * 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();
	}

  

转载于:https://www.cnblogs.com/deepbreath/p/4384247.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144095.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Wireshark安装后打开显示没有找到接口

    我遇到这个问题是出现在Win10系统中,出现这个问题的原因是Wireshark中由于自带的Winpcap不支持Win10。出现如图所示:1.这个问题的解决方法是下载一个Win10支持的Winpcap,下载链接为点击打开链接,界面如图:点击红色区域下载即可。注意:下载下来的红色区域即可。注意:下载下来Win10Pcap后,在安装前先将Wireshark关掉,要不然安装过程中会报错。2.安装完成后,重…

    2022年4月7日
    351
  • Java 删除文件以及文件夹删除不了的问题

    Java 删除文件以及文件夹删除不了的问题问题所在今天在编写一个项目,流程是先创建一个临时文件夹存放生成的文件,再经过压缩导出,待导出成功后删除临时文件夹,但是怎么也删除不了,还以为是写的删除方法有问题,找来找去,试了很多方法也删除不了本来以为是打包的流没关闭,但是发现流都是关闭的,后来发现,是在生成的方法里,直接newFileWriter出来的,没有关闭,在这里提醒一下,关于操作文件或者文件夹一定都会用到流,所以用到的流一…

    2022年6月7日
    33
  • 关于AxisFault的说明[通俗易懂]

    关于AxisFault的说明[通俗易懂]copyfrom:http://tenn.iteye.com/blog/94324一般说来,不可避免的WebService的服务中也会出现异常,举个简单的例子,一个服务接受一个SOAP请求消息,获取有效负载后,进行一个数据库更新操作,而在更新操作过程中发生了SQLException,这个时候就需要告诉客户端(调用WebService)出现异常了,Axis2将异常封装成为一个Axis…

    2025年11月9日
    2
  • vue 加载页面时触发时间_Vue 刷新页面时会触发事件吗「建议收藏」

    vue 加载页面时触发时间_Vue 刷新页面时会触发事件吗「建议收藏」使用localstorage做本地存储,然后我想在刷新页面或者离开页面的调用localstorage方法1、页面刷新使用localstorage,也就是当vue被实例化之后有如下几个可以供你使用:exportdefault{beforecreate(){//创建前状态}created(){//创建完毕状态}beforeMount(){//挂载前状态}mounted(){//…

    2022年8月31日
    7
  • matlab矩阵怎么进行相加,matlab矩阵如何运算相加

    matlab矩阵怎么进行相加,matlab矩阵如何运算相加matlab矩阵如何运算相加发布时间:2020-12-1114:26:52来源:亿速云阅读:61作者:小新这篇文章主要介绍了matlab矩阵如何运算相加,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。matlab矩阵运算相加的方法:首先需要在matlab命令窗口中创建一个矩阵或数组;然后两矩阵相加需维数一致,在MATLAB中输入代码【A…

    2022年6月25日
    99
  • 洛谷P1201 [USACO1.1]贪婪的送礼者Greedy Gift Givers

    洛谷P1201 [USACO1.1]贪婪的送礼者Greedy Gift Givers

    2021年9月17日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号