Jquery easyui treegrid实现树形表格的行拖拽

Jquery easyui treegrid实现树形表格的行拖拽

前几天修改了系统的一个功能——实现树形列列表的行拖拽,以达到排序的目的。现在基本上功能实现,现做一个简单的总结。

1.拿到这个直接网上搜,有好多,但是看了后都觉得不是太复杂就是些不是特别想看的例子,自己太懒(对自己不是很熟悉的东西是不愿意第一去看的)。结果选择良久,还是jquery easyui treegrid这个例子自己看起来比较熟悉。于是就专心研究了,从官方网站 http://www.jeasyui.net/ 下载了demo,开始研读。先把jsp页面一些代码贴出

<link rel="stylesheet" type="text/css" href="../css/treegrid/default/easyui.css">

<link rel="stylesheet" type="text/css" href="../css/treegrid/icon.css">

<link rel="stylesheet" type="text/css" href="../css/treegrid/treegrid.css">

<script type="text/javascript" src="../js/jquery-1.8.0.min.js"></script>

<script type="text/javascript" src="../js/jquery.easyui.min.js"></script>

<script type="text/javascript" src="../js/treegrid-dnd.js"></script>

<script type="text/javascript">

$(function(){  
	  //初始化弹出对话框
			$('#win').window('close');
		   
			
			$('#tt').treegrid({ 
//				 data:data,
				url:'catalogListItem',
				method:'post',
				dataType:'json',
				rownumbers: true,
				singleSelect:true,
				idField: 'id',
				treeField: 'title',				
				animate:true,
				columns:[[ 
					{field:'id',title:'ckc',checkbox:true},
					{field:'title',title:'分类名称',width:400,align:'left',editor:'text'}, 
					{field:'sortid',title:'排序值',width:100,align:'left',editor:'text'},
					{field:'creatorNick',title:'创建者',width:100},	
					{field:'createdTime',title:'创建时间',width:220},
					{field:'operate',title:'操作',width:220,
						formatter: function(value,row,index){
							var html='';
							html+='<a οnclick="showedit(\'编辑\','+row.id+')" >编辑 </a> ';		
							//html+=value+'<a οnclick="editrow('+row+')" >编辑 </a> <a id="cancel" οnclick="cancel()"></a>';		
							if(row.level==0){
								html+=' <a href="#" οnclick="Confirm(\'确认删除这个分类及其子类\','+row.id+')">删除</a> ';
								html+='<a href="#" οnclick="showedit(\'新建\','+row.id+')">新建子节点</a> ';//默认只有二级节点
							}
							else
								html+=' <a href="#" οnclick="Confirm(\'确认删除这个记录\','+row.id+')">删除</a> ';
							
							return html;
						}

					}
				]],
			  
			    onLoadSuccess: function(row){
					//$(this).treegrid('enableDnd', row?row.id:null);
				   //上面的代码是demo中的,但是对于要保存更改到数据库显然走不通,需要向其他办法

				   //启用拖动排序
				    enableDnd($('#tt'));
				}			
			}); 
	  });
	//进入修改/添加	type:操作类型  id:编辑时,当前记录的id;添加时当前记录的id(添加第一级节点id要作特殊处理)
	  function showedit(type,id){
		  $("#form")[0].reset();
		  $('#win').window('open');
		  if(type=='编辑'){			 
			  $.ajax({
				  url:'catalogGet?id='+id,
				  type:'post',
				  dataType:'json',
				  cache:false,
				  success:function(data){
					  $("#title").val(data[0].title);
					  $("#sortid").val(data[0].sortid);
					  $("#id").val(id);
				  }
						  
			  });
		  }
		  else
			 {			  
			  $("#parentId").val(id);
			 }		
	  }	 
	  //保存
	  function save(){
		  var title= $("#title").val();
		  var sortid=$("#sortid").val();
		  var id=$("#id").val(); 
		  var parentId=$("#parentId").val();  
		  $.ajax({
			  url:'catalogEdit',
			  data:{"title":title,"sortid":sortid,"id":id,"parentId":parentId},
			  type:'post',
			  dataType:'json',
			  success:
				  function(data)
				  {	   
					  if(data.result){
						 $('#win').window('close');
						 $('#tt').treegrid('reload');						
					  }
					  else						
						 alert(data.result);						
				  }		 
		  });
	  }
	  //是否删除
	  function Confirm(msg,id) {  
			$.messager.confirm("确认", msg, function (r) {  
				if (r) {  
					//请求
					$.ajax({url:'catalogDelete?id='+id,
						type:'post',
						dataType: 'json',   
						success://
						 function (data) {
							if(data){
							  $('#tt').treegrid('reload');
							}
							else
								alert("faile");							
						}
					 });
				}  
			});  
			return false;  
		}  

想到拖动的话,一定会用到jquery easyui 中draggable这个,但是这也不会写啊,看看demo按照那个写了一个,不合适,放弃了。想着着一定会有哪位这方面的前辈写好了,就各种百度和google,经过各种实验,找到一个就是上面  onLoadSuccess  里的  enableDnd($('#tt'));摘自一个论坛 http://www.jeasyui.com/forum/index.php?topic=575.0

function enableDnd(t) {
		var nodes = t.treegrid('getPanel').find('tr[node-id]');
		nodes.find('span.tree-hit').bind('mousedown.treegrid', function() {
			return false;
		});
		nodes.draggable({
			disabled: false,
			revert: true,
			cursor: 'pointer',
			proxy: function(source) {
				var p = $('<div class="tree-node-proxy tree-dnd-no"></div>').appendTo('body');
				p.html($(source).find('.tree-title').html());
				p.hide();
				return p;
			},
			deltaX: 15,
			deltaY: 15,
			onBeforeDrag: function() {
				$(this).next('tr.treegrid-tr-tree').find('tr[node-id]').droppable({ accept: 'no-accept' });
			},
			onStartDrag: function() {
				$(this).draggable('proxy').css({
					left: -10000,
					top: -10000
				});
			},
			onDrag: function(e) {
				$(this).draggable('proxy').show();
				this.pageY = e.pageY;
			},
			onStopDrag: function() {
				$(this).next('tr.treegrid-tr-tree').find('tr[node-id]').droppable({ accept: 'tr[node-id]' });
			}
		}).droppable({
			accept: 'tr[node-id]',
			onDragOver: function(e, source) {
				var pageY = source.pageY;
				var top = $(this).offset().top;
				var bottom = top + $(this).outerHeight();
				$(source).draggable('proxy').removeClass('tree-dnd-no').addClass('tree-dnd-yes');
				$(this).removeClass('row-append row-top row-bottom');
				if (pageY > top + (bottom - top) / 2) {
					if (bottom - pageY < 5) {
						$(this).addClass('row-bottom');
					} else {
						$(this).addClass('row-append');
					}
				} else {
					if (pageY - top < 5) {
						$(this).addClass('row-top');
					} else {
						$(this).addClass('row-append');
					}
				}
			},
			onDragLeave: function(e, source) {
				$(source).draggable('proxy').removeClass('tree-dnd-yes').addClass('tree-dnd-no');
				$(this).removeClass('row-append row-top row-bottom');
			},
			onDrop: function(e, source) {
				var action, point;
				if ($(this).hasClass('row-append')) {
					action = 'append';
				} else {
					action = 'insert';
					point = $(this).hasClass('row-top') ? 'top' : 'bottom';
				}
				$(this).removeClass('row-append row-top row-bottom');
			   // alert(action + ":" + point);
				// your logic code here
				// do append or insert action and reload the treegrid data
				 //==================================
				 //做自己的逻辑处理
				var src  = $('#tt').treegrid('find', $(source).attr('node-id'));
				var dest = $('#tt').treegrid('find', $(this).attr('node-id'));
			   // alert(src.title+","+dest.title);
				$.ajax({
					url: 'updateCatalogList',
					dataType: 'json',
					type:'post',
					data: {
						"srcId": src.id,
						"destId": dest.id
					},
					success:function(data){
						if(data.result)
						{
							$('#tt').treegrid('reload');	//重新加载treegrid		
					   }
					}
				
				});
			   //====================
			}
		});
	}
  

写入自己的程序,完全可以,拖动的效果有了,拖动的处理时间自己写“//============”之间的就是逻辑代码,具体就是向后台传送拖拽节点的标识信息(一般是id)和拖拽的目标节点的标识信息,即srcId和destId后台在做处理。

	<div id="win" title="新建/编辑分类" class="easyui-window" style="width:300px;height:180px;">
		<form id="form" style="padding:10px 20px 10px 40px;">
			<p>分类名称: <input id="title" name="title" type="text"></p>
			<p>排序值: <input id="sortid" name="sortid" type="text"></p>
			<input id="id" name="id" type="hidden">
			<input id="parentId" name="parentId" type="hidden">
			<div style="padding:5px;text-align:center;">
				<a href="#" class="easyui-linkbutton" icon="icon-ok" onclick="save()">确定</a>
				<a href="#" class="easyui-linkbutton" icon="icon-cancel" onclick="javascript: $('#win').window('close');">取消</a>
			</div>
			<input id="id" name="id" type="hidden">
		</form>
	</div>
	<table id="tt" class="easyui-treegrid" cellpadding="0" cellspacing="0" border="0" style="width100%;height:450px"></table>

接下来看一下数据源,我的数据源用的json格式,也是demo的给的样例格式。如下:

var data=[{
	"id":1,
	"name":"C",
	"size":"",
	"date":"02/19/2010",
	"children":[{
		"id":2,
		"name":"Program Files",
		"size":"120 MB",
		"date":"03/20/2010",
		"children":[{
			"id":21,
			"name":"Java",
			"size":"",
			"date":"01/13/2010",
			"state":"closed",
			"children":[{
				"id":211,
				"name":"java.exe",
				"size":"142 KB",
				"date":"01/13/2010"
			},{
				"id":212,
				"name":"jawt.dll",
				"size":"5 KB",
				"date":"01/13/2010"
			}]
		},{
			"id":22,
			"name":"MySQL",
			"size":"",
			"date":"01/13/2010",
			"state":"closed",
			"children":[{
				"id":221,
				"name":"my.ini",
				"size":"10 KB",
				"date":"02/26/2009"
			},{
				"id":222,
				"name":"my-huge.ini",
				"size":"5 KB",
				"date":"02/26/2009"
			},{
				"id":223,
				"name":"my-large.ini",
				"size":"5 KB",
				"date":"02/26/2009"
			}]
		}]
	},{
		"id":3,
		"name":"eclipse",
		"size":"",
		"date":"01/20/2010",
		"children":[{
			"id":31,
			"name":"eclipse.exe",
			"size":"56 KB",
			"date":"05/19/2009"
		},{
			"id":32,
			"name":"eclipse.ini",
			"size":"1 KB",
			"date":"04/20/2010"
		},{
			"id":33,
			"name":"notice.html",
			"size":"7 KB",
			"date":"03/17/2005"
		}]
	}]
}];

这就有一点需要注意你传过来的每条数据对象需要有对应的属性(children和state),state属性控制节点的关闭状态。因为只是照猫画虎,也没多想,我就直接把后台的所有数据直接一次性封装好,送给前台了。

注意:1.这在数据量极大地情况下是很低效的。一种思路就是异步加载子节点。

2.每次加载排序效果的好坏,还与系统定义的排序方式有关。

最后,虽简单的实现了功能,但是还有待改进。像 enableDnd($('#tt'));这个函数的东西,自己能看懂,但是还是自己写的少,以至于需要引用他人的。以后要多多加强一下。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值