JQuery EasyUI TreeGrid控件的使用——支持拖拽与禁止拖拽

 最近在做一些前端的工作,很多用户要求的复杂前端可以使用jq easyui实现,开源且功能强大,相信很多人早就尝到甜头了。

下面进入正题,本篇博文主要介绍treegrid控件。官网DEMO有很多,可以借鉴。想看拖拽相关介绍的直接跳到第三步……

treegrid效果图:



第一步:数据

看到这样的前端控件,我最先关心的是数据是如何存储的。这里以json为例,贴一个来自官网的样例json文件:

  1. [{  
  2.     "id":1,  
  3.     "name":"C",  
  4.     "size":"",  
  5.     "date":"02/19/2010",  
  6.     "type":"folder",  
  7.     "children":[{  
  8.         "id":2,  
  9.         "name":"Program Files",  
  10.         "size":"120 MB",  
  11.         "date":"03/20/2010",  
  12.         "type":"folder",  
  13.         "children":[{  
  14.             "id":21,  
  15.             "name":"Java",  
  16.             "size":"",  
  17.             "date":"01/13/2010",  
  18.             "state":"closed",  
  19.             "type":"folder",  
  20.             "children":[{  
  21.                 "id":211,  
  22.                 "name":"java.exe",  
  23.                 "size":"142 KB",  
  24.                 "date":"01/13/2010",  
  25.                 "type":"pack"  
  26.             },{  
  27.                 "id":212,  
  28.                 "name":"jawt.dll",  
  29.                 "size":"5 KB",  
  30.                 "date":"01/13/2010",  
  31.                 "type":"pack"  
  32.             }]  
  33.         },{  
  34.             "id":22,  
  35.             "name":"MySQL",  
  36.             "size":"",  
  37.             "date":"01/13/2010",  
  38.             "state":"closed",  
  39.             "type":"folder",  
  40.             "children":[{  
  41.                 "id":221,  
  42.                 "name":"my.ini",  
  43.                 "size":"10 KB",  
  44.                 "date":"02/26/2009",  
  45.                 "type":"pack"  
  46.             },{  
  47.                 "id":222,  
  48.                 "name":"my-huge.ini",  
  49.                 "size":"5 KB",  
  50.                 "date":"02/26/2009",  
  51.                 "type":"pack"  
  52.             },{  
  53.                 "id":223,  
  54.                 "name":"my-large.ini",  
  55.                 "size":"5 KB",  
  56.                 "date":"02/26/2009",  
  57.                 "type":"pack"  
  58.             }]  
  59.         }]  
  60.     },{  
  61.         "id":3,  
  62.         "name":"eclipse",  
  63.         "size":"",  
  64.         "date":"01/20/2010",  
  65.         "type":"folder",  
  66.         "children":[{  
  67.             "id":31,  
  68.             "name":"eclipse.exe",  
  69.             "size":"56 KB",  
  70.             "date":"05/19/2009",  
  71.             "type":"pack"  
  72.         },{  
  73.             "id":32,  
  74.             "name":"eclipse.ini",  
  75.             "size":"1 KB",  
  76.             "date":"04/20/2010",  
  77.             "type":"pack"  
  78.         },{  
  79.             "id":33,  
  80.             "name":"notice.html",  
  81.             "size":"7 KB",  
  82.             "date":"03/17/2005",  
  83.             "type":"pack"  
  84.         }]  
  85.     }]  
  86. }]  
[{
	"id":1,
	"name":"C",
	"size":"",
	"date":"02/19/2010",
	"type":"folder",
	"children":[{
		"id":2,
		"name":"Program Files",
		"size":"120 MB",
		"date":"03/20/2010",
		"type":"folder",
		"children":[{
			"id":21,
			"name":"Java",
			"size":"",
			"date":"01/13/2010",
			"state":"closed",
			"type":"folder",
			"children":[{
				"id":211,
				"name":"java.exe",
				"size":"142 KB",
				"date":"01/13/2010",
				"type":"pack"
			},{
				"id":212,
				"name":"jawt.dll",
				"size":"5 KB",
				"date":"01/13/2010",
				"type":"pack"
			}]
		},{
			"id":22,
			"name":"MySQL",
			"size":"",
			"date":"01/13/2010",
			"state":"closed",
			"type":"folder",
			"children":[{
				"id":221,
				"name":"my.ini",
				"size":"10 KB",
				"date":"02/26/2009",
				"type":"pack"
			},{
				"id":222,
				"name":"my-huge.ini",
				"size":"5 KB",
				"date":"02/26/2009",
				"type":"pack"
			},{
				"id":223,
				"name":"my-large.ini",
				"size":"5 KB",
				"date":"02/26/2009",
				"type":"pack"
			}]
		}]
	},{
		"id":3,
		"name":"eclipse",
		"size":"",
		"date":"01/20/2010",
		"type":"folder",
		"children":[{
			"id":31,
			"name":"eclipse.exe",
			"size":"56 KB",
			"date":"05/19/2009",
			"type":"pack"
		},{
			"id":32,
			"name":"eclipse.ini",
			"size":"1 KB",
			"date":"04/20/2010",
			"type":"pack"
		},{
			"id":33,
			"name":"notice.html",
			"size":"7 KB",
			"date":"03/17/2005",
			"type":"pack"
		}]
	}]
}]
JSON格式的文件看起来还是很容易看的,子节点就是children。


第二步:使用

调用treegrid有两种方式,第一种直接使用HTML配置,第二种用JS配置。

官网上也有,这里再贴一下,第一种:

  1. <table id="tt" class="easyui-treegrid" style="width:600px;height:400px"  
  2.         data-options="url:'get_data.php',idField:'id',treeField:'name'">  
  3.     <thead>  
  4.         <tr>  
  5.             <th data-options="field:'name',width:180">Task Name</th>  
  6.             <th data-options="field:'persons',width:60,align:'right'">Persons</th>  
  7.             <th data-options="field:'begin',width:80">Begin Date</th>  
  8.             <th data-options="field:'end',width:80">End Date</th>  
  9.         </tr>  
  10.     </thead>  
  11. </table>  
<table id="tt" class="easyui-treegrid" style="width:600px;height:400px"
        data-options="url:'get_data.php',idField:'id',treeField:'name'">
    <thead>
        <tr>
            <th data-options="field:'name',width:180">Task Name</th>
            <th data-options="field:'persons',width:60,align:'right'">Persons</th>
            <th data-options="field:'begin',width:80">Begin Date</th>
            <th data-options="field:'end',width:80">End Date</th>
        </tr>
    </thead>
</table>

第二种:

HTML中:

  1. <table id="tt" style="width:600px;height:400px"></table>  
<table id="tt" style="width:600px;height:400px"></table>
JS中:

  1. $('#tt').treegrid({  
  2.     url:'get_data.php',  
  3.     idField:'id',  
  4.     treeField:'name',  
  5.     columns:[[  
  6.         {title:'Task Name',field:'name',width:180},  
  7.         {field:'persons',title:'Persons',width:60,align:'right'},  
  8.         {field:'begin',title:'Begin Date',width:80},  
  9.         {field:'end',title:'End Date',width:80}  
  10.     ]]  
  11. });  
$('#tt').treegrid({
    url:'get_data.php',
    idField:'id',
    treeField:'name',
    columns:[[
        {title:'Task Name',field:'name',width:180},
        {field:'persons',title:'Persons',width:60,align:'right'},
        {field:'begin',title:'Begin Date',width:80},
        {field:'end',title:'End Date',width:80}
    ]]
});

注意:我在使用的时候发现了一些问题,情况可能比较特殊。最好使用最新的easyui文件,我用旧版本的文件,结果不认table标签中的data-option属性。对于使用第一种配置方法的童鞋,如果没有加载进入数据的话,可尝试手动加载:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. $.post('treegrid.json',function(data){  
  2.                 $('#test2').treegrid('loadData',data);  
  3.                 },'json');  
$.post('treegrid.json',function(data){
                $('#test2').treegrid('loadData',data);
                },'json');
treegrid.json是你的json数据文件,相对地址。


第三步:扩展

treegrid支持很多功能可以自己定义,使用方法官网上都有(发现我很爱说这句话……)官网DEMO
下边记录一下我在使用拖拽功能时候遇到的问题:

treegrid支持拖拽的官方DEMO

让treegrid支持拖拽还需要treegrid-dnd.js  。这个文件中定义了拖拽相关的接口函数,文件不大,读起来应该问题不大。

1. 禁止drop

在我的需求中,叶子节点是不可以拖到叶子节点上的,demo中,如果把叶子节点放在叶子节点上的话,目标节点就会自动变为被拖动节点的父节点,与我的需求不符合。修改treegrid-dnd.js中的onDrop函数,在onDrop的时候判断是否叶子节点,是的话就返回:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. var dest = this;  
  2.                         var action, point;  
  3.                         var tr = opts.finder.getTr(target, $(this).attr('node-id'));  
  4.                         var dRow = getRow(this);  
  5.                         var sRow = getRow(source);  
  6.                         //alert("destination:"+dRow.type+",source:"+sRow.type)  
  7.                         if(dRow.type=="pack")  
  8.                         {  
  9.                             tr.removeClass('treegrid-row-append treegrid-row-top treegrid-row-bottom');  
  10.                             return;  
  11.                         }  
var dest = this;
						var action, point;
						var tr = opts.finder.getTr(target, $(this).attr('node-id'));
						var dRow = getRow(this);
						var sRow = getRow(source);
						//alert("destination:"+dRow.type+",source:"+sRow.type)
						if(dRow.type=="pack")
						{
							tr.removeClass('treegrid-row-append treegrid-row-top treegrid-row-bottom');
							return;
						}

上边代码中,dRow.type是自定义的,type是我的json数据中的一个属性,来标识是否是叶子节点。

2. 节点处于编辑状态下禁止拖拽

需求中有要求可以修改节点的名字,编辑列中editor="text",进入编辑状态后变为textbox,如果想使用鼠标选中内容的话就会触发拖动事件,因此在编辑的时候要禁止拖拽。

但是treegrid-dnd.js 中没有禁止拖拽的接口,只有enableDnd。查了好多没有查到禁止的用法,而且官网上提供的方法也只有enableDnd。那么就参考enableDnd的写法,自已写一个disableDnd好了:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. $.extend($.fn.treegrid.methods, {  
  2.         disableDnd:function(jq,id){  
  3.             return jq.each(function() {  
  4.                 var target = this;  
  5.                 var state = $.data(this'treegrid');  
  6.                 state.disabledNodes = [];  
  7.                 var t = $(this);  
  8.                 var opts = state.options;  
  9.                 if (id) {  
  10.                     var nodes = opts.finder.getTr(target, id);  
  11.                     var rows = t.treegrid('getChildren', id);  
  12.                     for (var i = 0; i < rows.length; i++) {  
  13.                         nodes = nodes.add(opts.finder.getTr(target, rows[i][opts.idField]));  
  14.                     }  
  15.                 } else {  
  16.                     var nodes = t.treegrid('getPanel').find('tr[node-id]');  
  17.                 }  
  18.                 nodes.draggable({  
  19.                     disabled: true,  
  20.                     revert: true,  
  21.                     cursor: 'pointer'});  
  22.             });  
  23.         }  
  24.     });  
$.extend($.fn.treegrid.methods, {
		disableDnd:function(jq,id){
			return jq.each(function() {
				var target = this;
				var state = $.data(this, 'treegrid');
				state.disabledNodes = [];
				var t = $(this);
				var opts = state.options;
				if (id) {
					var nodes = opts.finder.getTr(target, id);
					var rows = t.treegrid('getChildren', id);
					for (var i = 0; i < rows.length; i++) {
						nodes = nodes.add(opts.finder.getTr(target, rows[i][opts.idField]));
					}
				} else {
					var nodes = t.treegrid('getPanel').find('tr[node-id]');
				}
				nodes.draggable({
					disabled: true,
					revert: true,
					cursor: 'pointer'});
			});
		}
	});
我在调用拖拽的时候是配置的table的data-option,这里也要修改:

  1. <table id="dndtree" title="Folder Browser" class="easyui-treegrid" style="width:700px;height:250px"  
  2.             data-options="  
  3.                 url:'treegrid.json',  
  4.                 rownumbers: false,  
  5.                 idField: 'id',  
  6.                 treeField: 'name',  
  7.                 onContextMenu:onContextMenu,  
  8.                 onLoadSuccess: function(row){  
  9.                     $(this).treegrid('enableDnd', row?row.id:null);  
  10.                 },  
  11.                 onBeforeEdit: function(row){  
  12.                     $(this).treegrid('disableDnd');  
  13.                 },  
  14.                 onAfterEdit: function(row){  
  15.                     $(this).treegrid('enableDnd');  
  16.                 },  
  17.                 onCancelEdit: function(row){  
  18.                     $(this).treegrid('enableDnd');  
  19.                 }  
  20.             ">  
  21.         <thead>  
  22.             <tr>  
  23.                 <th data-options="field:'name',formatter:formatName" width="220" editor="text">Name</th>  
  24.                 <th data-options="field:'size'" width="150" align="right">Size</th>  
  25.                 <th data-options="field:'date'" width="200">Modified Date</th>  
  26.             </tr>  
  27.         </thead>  
  28.     </table>  
<table id="dndtree" title="Folder Browser" class="easyui-treegrid" style="width:700px;height:250px"
			data-options="
				url:'treegrid.json',
				rownumbers: false,
				idField: 'id',
				treeField: 'name',
				onContextMenu:onContextMenu,
				onLoadSuccess: function(row){
					$(this).treegrid('enableDnd', row?row.id:null);
				},
                onBeforeEdit: function(row){
                    $(this).treegrid('disableDnd');
                },
                onAfterEdit: function(row){
                    $(this).treegrid('enableDnd');
                },
                onCancelEdit: function(row){
                    $(this).treegrid('enableDnd');
                }
			">
		<thead>
			<tr>
				<th data-options="field:'name',formatter:formatName" width="220" editor="text">Name</th>
				<th data-options="field:'size'" width="150" align="right">Size</th>
				<th data-options="field:'date'" width="200">Modified Date</th>
			</tr>
		</thead>
	</table>
onBeforeEdit时禁止拖拽,结束编辑或者取消编辑的时候再启用拖拽。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值