基于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'}]}

demo预览图

下面是主体代码,返回值是对象

/**新增代码 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地址:点这里

posted @ 2011-08-22 18:28  Q上的路人甲  阅读(1692)  评论(4编辑  收藏  举报