基于jQuery的可拖拽选择
父级拖拽至右侧框即可全选其子节点
子节点可单独拖拽添加
右侧节点可拖拽回左侧窗口(暂时右侧无父节点,需求父节点不加入最后返回值故未考虑)
生成对象的原始数据格式为json
这里是JSON格式
{id:'sjw',name:'市纪委、市两院',ind:'2',children:[{id:'{BFA811EA-0000-0000-4562-2C66000015FB}',name:'市纪委',gzname:'市纪委',ind:'1'},{id:'{BFA811EA-0000-0000-4553-591600000237}',name:'市中级法院',gzname:'市中级法院',ind:'2'},{id:'{BFA811EA-0000-0000-455F-98EE000013C0}',name:'市检察院',gzname:'市检察院',ind:'3'}]}
下面是主体代码,返回值是对象
/**新增代码 purecolor@foxmail.com 2011.08.08**/ var resultbox={}; //待发送的对象 var checkboxs={}; //左侧选中的对象 var delboxs={}; //右侧待删除的对象 var _temps={}; //缓存对象 var defalut_nums=5; var node=function(id,name,checked,parentid,nums){ this.id=id; //主键 this.name=name; //节点名 this.checked=!!checked; //是否选中 this.parentid=parentid; //父级id this.nums=nums; //发件数 this.serial=''; //扩展的编号 }; var js=0,jl=json.length; for(js;js<jl;js++){ var pid=json[js].id; var pname=json[js].name; var children=json[js].children; var si=0,sl=children.length; _temps[pid]=new node(pid,pname,false,null,defalut_nums); for(si;si<sl;si++){ var sid=children[si].id; var sname=children[si].name; _temps[sid]=new node(sid,sname,false,pid,defalut_nums); } } //事件优化 $('DIV[sdata]').live('click',function(e){ //全选事件 //var t=e.srcElement||e.target; var pi=$(this).find('input').attr('checked'); var id=$(this).attr('sdata'); if(pi){ checkboxs[id]=_temps[id]; }else{ delete checkboxs[id]; } //设置父checkbox状态 $(this).find('input').attr('disabled',pi); //选中全部子checkbox $('.c_'+id).find('label').each(function(){ var id=$(this).attr('sdata'); if(!_temps[id].checked){ $(this).find('input').attr('checked',pi); if(!pi){ delete checkboxs[id]; }else{ checkboxs[id]=_temps[id]; } } }); }).live('mousedown',function(ev){ //拖拽全选事件 var t=ev.srcElement||ev.target; var disalbe=$(this).find('input').attr('checked'); if(t.nodeName=='LABEL'&&!disalbe){ var id=$(this).attr('sdata'); var name=_temps[id].name; var html='<label for="r_'+id+'" sdata="'+id+'" class="tempbox"><input name="r_'+id+'" type="checkbox" id="r_'+id+'" value="'+id+'" />'+name+'</label>'; var _el=$(html).appendTo('body'); ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); $(document).bind('mousemove',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); }).bind('mouseup',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); var _x=mousePos.x ,_y=mousePos.y; //minL:540 minT:40 maxL: var minL=$('#fw_right').position().left ,minT=$('#fw_right').position().top; var maxL=minL+$('#fw_right').width(),maxT=minT+$('#fw_right').height(); if(_x>minL&&_x<maxL&&_y>minT&&_y<maxT){ var id=_el.attr('sdata'); $('.c_'+id).find('label').each(function(){ var id=$(this).attr('sdata'); if(!_temps[id].checked){ $(this).find('input').attr('checked',true); _addOne(_temps[id]); } }); // } $(document).unbind('mousemove').unbind('mouseup'); _el.remove(); delete _el; //开启可选中 document.onselectstart = null; if(!$.browser.msie) window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP); }); //禁止可选中 document.onselectstart = new Function("return false"); if(!$.browser.msie) window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); } }); //单元素 $('label[pdata]',$('#fw_left')).live('click',function(){ //单元素选择事件 var pi=$(this).find('input').attr('checked'); var id=$(this).attr('sdata'); if(pi){ checkboxs[id]=_temps[id]; }else{ delete checkboxs[id]; } }).live('mousedown',function(ev){ //单元素拖拽事件 var t=ev.srcElement||ev.target; var disalbe=$(this).find('input').attr('checked'); if(t.nodeName=='LABEL'&&!disalbe){ var id=$(this).attr('sdata'); var name=_temps[id].name; var parentid=_temps[id].parentid; var html='<label for="r_'+id+'" pdata="'+parentid+'" sdata="'+id+'" class="tempbox"><input name="r_'+id+'" type="checkbox" id="r_'+id+'" value="'+id+'" />'+name+'</label>'; var _el=$(html).appendTo('body'); ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); $(document).bind('mousemove',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); }).bind('mouseup',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); var _x=mousePos.x ,_y=mousePos.y; //minL:540 minT:40 maxL: var minL=$('#fw_right').position().left ,minT=$('#fw_right').position().top; var maxL=minL+$('#fw_right').width(),maxT=minT+$('#fw_right').height(); if(_x>minL&&_x<maxL&&_y>minT&&_y<maxT){ _addOne(_temps[_el.attr('sdata')]); } $(document).unbind('mousemove').unbind('mouseup'); _el.remove(); delete _el; //开启可选中 document.onselectstart = null; if(!$.browser.msie) window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP); }); //禁止可选中 document.onselectstart = new Function("return false"); if(!$.browser.msie) window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); } }); //右侧单元素 //修改发文数 $('label[pdata]',$('#fw_right')).find('.nums').live('blur',function(){ resultbox[$(this).attr('nid')].nums=chk_nums($(this).val()); }) //修改扩展的数字 $('label[pdata]',$('#fw_right')).find('.serial').live('blur',function(){ resultbox[$(this).attr('sid')].serial=chk_nums($(this).val()); }) //点击待删 $('label[pdata]',$('#fw_right')).live('click',function(){ var pi=$(this).find('input').attr('checked'); if(pi){ delboxs[$(this).attr('sdata')]=_temps[$(this).attr('sdata')]; }else{ delete delboxs[$(this).attr('sdata')]; } }).live('mousedown',function(ev){ //单元素反向拖拽事件 var t=ev.srcElement||ev.target; if(t.nodeName=='LABEL'){ var id=$(this).attr('sdata'); var name=_temps[id].name; var parentid=_temps[id].parentid; var html='<label for="r_'+id+'" pdata="'+parentid+'" sdata="'+id+'" class="tempbox"><input name="r_'+id+'" type="checkbox" id="r_'+id+'" value="'+id+'" />'+name+'</label>'; //var bghtml='<div class="tempboxbg"></div>'; //var _elbg=$(bghtml).appendTo('body'); var _el=$(html).appendTo('body'); ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); //_elbg.css({height:$(document).height()}); $(document).bind('mousemove',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); _el.css({left:mousePos.x-30,top:mousePos.y-10}); }).bind('mouseup',function(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); var _x=mousePos.x ,_y=mousePos.y; var $this=$('#fw_left'); var $that=$('#fw_right'); var id=_el.attr('sdata'); //minL:540 minT:40 maxL: var minL=$this.position().left ,minT=$this.position().top; var maxL=minL+$this.width(),maxT=minT+$this.height(); if(_x>minL&&_x<maxL&&_y>minT&&_y<maxT){ $('label[for=r_'+id+']',$that).remove(); _delOne(resultbox[id]); } $(document).unbind('mousemove').unbind('mouseup'); _el.remove(); delete _el; //开启可选中 document.onselectstart = null; if(!$.browser.msie) window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP); }); //禁止可选中 document.onselectstart = new Function("return false"); if(!$.browser.msie) window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); } }); //构造场景 function creatHtml(o){ if(!o) return; for(n in o){ var id=o[n].id; var name=o[n].name; var checked=o[n].checked; var parentid=o[n].parentid; if(parentid==null){ var html='<div class="t_'+id+' title" sdata="'+id+'" id="t_'+id+'"><label for="'+id+'"><input name="'+id+'" type="checkbox" id="'+id+'" value="'+id+'" />'+name+'</label></div>'; var el=$(html).appendTo($('#fw_left')); $('<div class="c_'+id+' content"></div>').appendTo($('#fw_left')); /**增加事件**/ /**end**/ /**全选拖拽实现**/ /**end**/ }else{ var html='<label for="'+id+'" pdata="'+parentid+'" sdata="'+id+'"><input name="'+id+'" type="checkbox" id="'+id+'" value="'+id+'" />'+name+'</label>'; var el=$(html).appendTo($('.c_'+parentid)); /**增加事件**/ /**拖拽实现**/ /**end**/ } } } //拖拽添加 function _addOne(obj){ if (isNaN($("#fenshu").val()) || $("#fenshu").val() < 1) { alert("请输入正确发送分数!"); return false; } if(!obj) return; var o=obj; var id=o.id; var name=o.name; var checked=o.checked; var parentid=o.parentid; var nums=o.nums; var serial=o.serial; _temps[id].checked=true; if(parentid!=null){ var html='<label for="r_'+id+'" pdata="'+parentid+'" sdata="'+id+'"><input name="r_'+id+'" type="checkbox" id="r_'+id+'" value="'+id+'"/>'+name+'[ <input class="nums" name="nums" type="text" nid="'+id+'" value="'+nums+'" />] [ <input class="serial" name="serial" type="text" sid="'+id+'" value="'+serial+'" />]</label>'; var el=$(html).appendTo($('#fw_right')); //保存待发送的单位 resultbox[id]=_temps[id]; checkboxs[id]=_temps[id]; var $this=$('#fw_left'); $('label[for='+id+']',$this).addClass('fcc').find('input').attr('checked',true).attr('disabled',true); //判断是否全选 if(!_temps[parentid].checked) isCheckAll(parentid); /**增加事件**/ /**end**/ //反向拖拽实现 //反向拖拽实现 /**end**/ } } //添加单位 function _add(obj){ if (isNaN($("#fenshu").val()) || $("#fenshu").val() < 1) { alert("请输入正确发送分数!"); return; } var ckAll={}; var isr=false; if(!obj) { obj=checkboxs; isr=true; } $('#fw_right').html(''); for(n in obj){ var o=obj[n]; var id=o.id; var name=o.name; var checked=o.checked; var parentid=o.parentid; var nums=o.nums; var serial=o.serial; //保存返回的nums、serial if(!isr){ _temps[id].nums=nums; _temps[id].serial=serial; checkboxs[id]=_temps[id]; } _temps[id].checked=true; if(parentid!=null){ var html='<label for="r_'+id+'" pdata="'+parentid+'" sdata="'+id+'"><input name="r_'+id+'" type="checkbox" id="'+id+'" value="'+id+'"/>'+name+'[ <input class="nums" name="nums" type="text" nid="'+id+'" value="'+nums+'" />] [ <input class="serial" name="serial" type="text" sid="'+id+'" value="'+serial+'" />]</label>'; var el=$(html).appendTo($('#fw_right')); //保存待发送的单位 resultbox[id]=_temps[id]; var $this=$('#fw_left'); $('label[for='+id+']',$this).addClass('fcc').find('input').attr('checked',true).attr('disabled',true); //判断是否全选 //if(!_temps[parentid].checked) ckAll[parentid]=parentid; /**增加事件**/ /**end**/ //反向拖拽实现 //反向拖拽实现 /**end**/ } } //优化后的全选检查 for(c in ckAll){ isCheckAll(c); } ckAll={}; delete ckAll; } //检查子项是否全选 function isCheckAll(pid){ var allc=true; var $this=$('#fw_left'); $('.c_'+pid,$this).find('label').each(function(){ var id=$(this).attr('sdata'); if(!_temps[id].checked) allc=false; }); if(allc){ $('label[for='+pid+']',$this).find('input').attr('checked',true).attr('disabled',true); _temps[pid].checked=true; checkboxs[pid]=_temps[pid]; }else{ $('label[for='+pid+']',$this).find('input').attr('checked',false).attr('disabled',false); _temps[pid].checked=false; delete checkboxs[pid]; } } //删除全部单位 function _allDel(){ var ckAll={}; for(n in resultbox){ var o=resultbox[n]; var id=o.id; var parentid=o.parentid; o.checked=false; $('label[for='+id+']').removeClass('fcc').find('input').attr('checked',false).attr('disabled',false); ckAll[parentid]=parentid; delete checkboxs[id]; } $('#fw_right').html(''); resultbox={}; //优化后的全选检查 for(c in ckAll){ isCheckAll(c); } ckAll={}; delete ckAll; } //删除选择的单位 function _del(){ for(n in delboxs){ var o=delboxs[n]; var id=o.id; var pid=o.parentid; o.checked=false; $('label[for=r_'+id+']' ,$('#fw_right')).remove(); $('input[id='+id+']' ,$('#fw_left')).attr('checked',false).attr('disabled',false); $('label[for='+id+']' ,$('#fw_left')).removeClass('fcc'); if(_temps[pid].checked){ _temps[pid].checked=false; $('input[id='+pid+']' ,$('#fw_left')).attr('checked',false).attr('disabled',false); } delete checkboxs[id]; delete resultbox[id]; } delboxs={}; } //删除单个单位 function _delOne(obj){ if(obj){ var o=obj; var id=o.id; var pid=o.parentid; o.checked=false; $('input[id='+id+']' ,$('#fw_left')).attr('checked',false).attr('disabled',false); $('label[for='+id+']' ,$('#fw_left')).removeClass('fcc'); if(_temps[pid].checked){ _temps[pid].checked=false; $('input[id='+pid+']' ,$('#fw_left')).attr('checked',false).attr('disabled',false); } delete checkboxs[id]; delete resultbox[id]; delete delboxs[id]; } } //获得信息 //demo _getValue(['id','name','parentid'],'|') function _getValue(fields,splitstr){ var result=[],str=''; for(n in resultbox){ var o=resultbox[n]; var parentid=o.parentid; if(parentid!=null){ str=""; var i=0,l=fields.length; for(i;i<l;i++){ if(str!=''&&l>1){ str+=splitstr; } str+=o[fields[i]]; } result.push(str); } } return result; } //保存分组信息 function _saveGroup(){ var submit_str = _getValue(['name','id','nums','parentid'],'|').join(';'); if(submit_str=="") { alert("请添加收文单位"); return; } var obj = new Object(); obj.name=submit_str; window.showModalDialog("govtalk/newGroup.jsp",obj, 'dialogWidth: 300px;dialogHeight: 30px; status: no; scrollbars: no; Resizable: no; help: no;'); } //选择存在的组 function _getGroup(){ var retVal=""; retVal=window.showModalDialog("govtalk/selectgroup.jsp?rnd="+Math.random(), "", 'dialogWidth: 300px;dialogHeight: 450px; status: no; scrollbars: no; Resizable: no; help: no;'); if (retVal != null){ tmparry = retVal.split(";"); var temarr = new Array(); for(var i=0,l=tmparry.length;i<l;i++) { var id=tmparry[i].split('|')[1]; var name=tmparry[i].split('|')[0]; checkboxs[id]=_temps[id]; resultbox[id]=_temps[id]; } _add(resultbox); } } //验证输入的发文份数 function chk_nums(str) { str = str.replace(/[^\d]/g,''); if (str < 1){str = defalut_nums} return str; } //提交操作 function _submit(){ var o={}; o.src= resultbox; o.num=defalut_nums; window.returnValue = o; window.close(); } //重设默认单位 $(document).ready(function (){ creatHtml(_temps); var objDlg = window.dialogArguments; //接主窗口传参 if(typeof objDlg.dep=='object' ){ //checkboxs=objDlg.dep; resultbox=objDlg.dep; if(objDlg.num>0){ defalut_nums=objDlg.num; } $('#fenshu').val(defalut_nums); $('#fw_left').focus(); //默认的发文分数 setTimeout(function(){ $('#fenshu').bind('blur',function(){ var str=$(this).val(); str=chk_nums(str); defalut_nums=str; var $this=$('#fw_right'); for(n in resultbox){ var o=resultbox[n]; o.nums=defalut_nums; $('input[nid='+o.id+']',$this).val(defalut_nums); } }); },500); _add(resultbox); } }); //获取鼠标位置 function mousePosition(ev){ if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; }
具体的demo地址:点这里