赞
踩
easyUI拖拽功能讲解以及多选拖拽的实现
首先我们考虑这样一个业务场景:一个维修部门中分了N个维修组,维修部门的负责人需要将这个部门的维修人员分配到这些组里去。
当然,他可以选中一个维修人员,然后给他分配维修组,但是从人性化角度考虑,若利用拖拽是否更加的快捷和明确呢?
比如我们可以将维修组和维修人员都列出来,然后只需要将维修人员拖动到对应的组里即可完成分组。
另外,由于一个个拖还是太繁琐,还需要实现选中多个维修人员一起分组。那么我们下面一步步来,先实现单个的拖拽功能,再加入多选拖动支持~
单选拖动
首先,根据我们刚才描述的场景,简单设计一个布局:
接下来,我们需要做的是:
1、让维修人员对应的小方块可以拖动起来
这就需要把每个小方块都注册成draggable(这里我为每个小方块添加了class='employee'方便选择)
$('.employee').draggable( {
revert : true,
proxy : 'clone',
onStartDrag : function() {
$(this).draggable('options').cursor = 'not-allowed';
$(this).draggable('proxy').css('z-index', 10);
$(this).draggable('proxy').addClass('dp')
},
onStopDrag : function() {
$(this).draggable('options').cursor = 'move';
}
});
关于draggable中的属性设置,这里也讲解一下:
revert:true表示当停止拖动后,小方块回归原位(false则不回归)
proxy:'clone'表示拖动的那个元素,如果设置成clone,那么它会自动帮你clone一个元素用来给你拖动,如果要自己写的话,返回的必须是一个jQuery对象。这个在后面多选拖动的实现中会讲到。
onStartDrag 开始拖动时会触发,可以看到这里我们设置了一些视觉上的效果,比如添加一个不可防止的这么一个小角标,并且透明度变低(.dp)
onStopDrag 结束拖动时触发,还原角标
2、让小方块可以放置到上面的组里,并显示出来
那么首先需要把上面的组注册成droppable(这里为组的上一层ul添加了.group-list方便选择)
$('.group-list li').droppable( { // 注意,这里要用li,不能直接用 .easyui-datagrid
onDragEnter : function(e, source) {
$(source).draggable('options').cursor = 'auto';
},
onDragLeave : function(e, source) {
$(source).draggable('options').cursor = 'not-allowed';
},
onDrop : function(e, source) {
var empno = $(source).find('p:eq(0)').html();
var name = $(source).find('p:eq(1)').html();
var phone = $(source).find('p:eq(2)').html();
addEmployee(empno.split(':')[1], name.split(':')[1],
phone.split(':')[1], $(this).find('[id^=group]'));
$(source).parent().hide();
}
});
这里几个事件都比较好理解,看名字就可以了
onDragEnter: 当拖动的小方块进入时触发
onDragLeave: 当拖动的小方块离开时触发
onDrop: 当拖动的小方块进入后并放开鼠标时触发
当然,onDrop显然是最重要的,放开鼠标后我们需要将小方块代表的维修人员添加到对应的组中,也就是addEmployee(...)这个函数
function addEmployee(empno, name, phone, dg) {
var data = dg.datagrid('getData');
function add() {
data.total += 1;
data.rows.push( {
empno : empno,
name : name,
phone : phone
});
}
add();
dg.datagrid('loadData', data);
}
这里的dg是通过小方块拖动放开的组来找到的,也就是onDrap函数中$(this).find('[id^=group]')来找的。这里有个小技巧,就是将组的id都命名成group开头,后面加一个组的编号,这主要是由于easyUI对非id访问元素的支持不是很好。
至此,单选拖拽就讲完了,你可以试试拖动小方块到维修组里试试~
多选拖动
下面开始讲解多选拖动,多选拖动的难点在于,如何选?最完美的方式当然是单击小方块后选中,然后一起拖到维修组中。
但是,单击小方块也会被认为是 拖动 而触发onDrapStart,而并不会触发onClick事件。
那么是否可以在小方块中添加一个多选框(checkbox)而不触发拖动事件?
我实践后发现由于在拖动时会clone出一个小方块并且覆盖在之前的小方块上,所以基本上点不到原来的小方块(快速点击倒是会成功,但是显然这种方案也不行)
而我之前做这个的时候用了一种方法,是利用了draggable的deltaX和deltaY两个属性,这两个属性的意思是clone出来的一个小方块相对于原来的小方块的位置
这样的话只要避免遮盖到checkbox就可以多选了!但是由于单击的时候会跳一下,这里并不推荐,有兴趣的朋友可以试试。
另外一种方法,就是将可拖动的小方块和多选框分开,这样一来就不会被遮挡了(为什么之前没想到
),下面就直接上代码了,大家可以和之前单选的对比着看
$('.employee').draggable( {
revert : true,
proxy : function(source){
if($(":checkbox:checked").length == 0){
var clone = $(source).clone();
clone.insertBefore($(source));
return clone;
}else{
var div = $("
$(":checkbox:checked").each(function(){
var clone = $(this).prev().clone();
div.append(clone);
});
div.insertBefore($(source));
return div;
}
},
onStartDrag : function() {
$(this).draggable('options').cursor = 'not-allowed';
$(this).draggable('proxy').css('z-index', 10);
$(this).draggable('proxy').addClass('dp')
},
onStopDrag : function() {
$(this).draggable('options').cursor = 'move';
}
});
我这里将选中checkbox多选的和没选checkbox单选的这两种情况分开,这里唯一不一样的就是proxy属性
关于这个proxy其实就是在界面上clone一个代理小方块出来,用来拖动显示用,那么对于多选来说,我们首先需要克隆出选中的小方块,然后将小方块塞到界面中,然后需要将这些小方块返回给proxy。这里还有个问题就是,我尝试了很多次,只能返回jQuery对象,且不能是jQuery数组。所以只能搞个div然后把选中的小方块都塞到这个div里,最后会有一个一起拖着走的效果,当然这纯粹是为了效果好,用之前的proxy:'clone'也可以达到多选拖动的目的,只不过在拖动过程中的显示上只会出现最后拖动的那个小方块。
$('.group-list li').droppable( { // 注意,这里要用li,不能直接用 .easyui-datagrid
onDragEnter : function(e, source) {
$(source).draggable('options').cursor = 'auto';
},
onDragLeave : function(e, source) {
$(source).draggable('options').cursor = 'not-allowed';
},
onDrop : function(e, source) {
if($(":checkbox:checked").length == 0){
var empno = $(source).find('p:eq(0)').html();
var name = $(source).find('p:eq(1)').html();
var phone = $(source).find('p:eq(2)').html();
addEmployee(empno.split(':')[1], name.split(':')[1],
phone.split(':')[1], $(this)
.find('[id^=group]'));
$(source).parent().hide();
}else{
var li = $(this);// 防止each里访问不到this
var group = li.find('[id^=group]');
$(":checkbox:checked").each(function(){
var empno = $(this).prev().find('p:eq(0)').html();
var name = $(this).prev().find('p:eq(1)').html();
var phone = $(this).prev().find('p:eq(2)').html();
addEmployee(empno.split(':')[1], name.split(':')[1],
phone.split(':')[1], group);
$(this).parent().hide();
$(this).removeAttr("checked");
});
}
}
});
对于拖到维修组中放开鼠标后的处理也要分开讨论了,这个也比较好理解~
那就写到这里~下班回家!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。