Dhtml Drag Layout
http://www.oschina.net/code/snippet_87084_11666
/* Jquery-portal.js Jquery Portal layout 可拖拽布局 Copyright (C) Jh 2012.4.11 @author xiaofan */ var Jh = { Config:{//CLASS样式配置 tableCls:"form-list", tdCls:"form-text", tdCls2:"single", ulCls : "tag-list", layCls :"layout-list", min :"min", mintext:"收起", max :"max", maxtext:"展开", close :"close", closetext :"关闭", refreshtext:"刷新", refresh :"refresh", _groupItemContent : "itemContent", _groupItemHead : "itemHeader", _groupWrapperClass : "groupWrapper", _groupItemClass : "groupItem" } }; Jh.Layout=function(me){ var _left = "portal_l" , _center ="portal_m", _right ="portal_r"; return me = { location:{//三列容器 left:_left, center:_center, right:_right }, locationId : { left:"#"+_left, center:"#"+_center, right:"#"+_right }, layoutCss : { 0:"1:3", 1:"3:1", 2:"1:2:1", 3:"1:1:2", 4:"2:1:1", 5:"1:1:1" }, layoutText : { 0 :"w250 w750 wnone", 1 :"w750 w250 wnone", 2 :"w250 w500 w250", 3 :"w250 w250 w500", 4 :"w500 w250 w250", 5 :"w250 w250 w250" } } }(); Jh.Util = {//工具类 format : function (str, model) {//格式化指定键值的模板 for (var k in model) { var re = new RegExp("{" + k + "}", "g"); str = str.replace(re, model[k]) } return str }, refresh:function(){//刷新3个布局 $("#"+Jh.Layout.left,"#"+Jh.Layout.center,"#"+Jh.Layout.right).sortable('refresh'); }, toBody:function(o){//往Body添加对象 $("body").append(o); } }; Jh.fn = function(me){//功能区 return me = { init:function(data){//初始化 me._ele = {}; me._create(); me._createWrap(data); me._bindEvent(); }, _create:function(){//创建自己 var _box = $("<div id='header'/>"); me.box = _box; Jh.Util.toBody(_box);//往Body里添加自己 }, _createWrap:function(d){//创建外层容器 var _table = me._createTable(Jh.Config.tableCls); me._ele.table = _table me._createModuleList(d); me._createActionButton(); me._addPanel(_table); }, _createTable:function(clsName){ //创建表格 var _t = $("<table/>").addClass(clsName); $("<tbody/>").append(me._createLayoutTr()) .append(me._createBaseTr()) .append(me._createActionTr()) .appendTo(_t); return _t; }, _createBaseTr:function(){//创建功能模块tr var _td = me._createTd(Jh.Config.tdCls2), _tr = $("<tr>").append(me._createTd(Jh.Config.tdCls,"功能模块设置:")) .append(_td); me._ele.mtd = _td; return _tr; }, _createActionTr:function(){//创建按钮tr var _td = me._createTd(Jh.Config.tdCls2), _tr = $("<tr>").append(me._createTd(Jh.Config.tdCls)) .append(_td); me._ele.atd = _td; return _tr; }, _createLayoutTr:function(){//创建布局 var _td = me._createTd(Jh.Config.tdCls2), _div = $("<div/>").addClass(Jh.Config.layCls) .append(me._createA("1:3")) .append(me._createA("3:1")) .append(me._createA("1:1:2")) .append(me._createA("1:2:1")) .append(me._createA("2:1:1")) .append("<a href='javascript:void(0);' class='active' rel='1:1:1'>默认</a>") .appendTo(_td), _tr = $("<tr>").append(me._createTd(Jh.Config.tdCls,"布局设置:")).append(_td); me._ele.layoutTd = _td; return _tr; }, _createModuleList:function(data){//创建模块list var _ul = $("<ul/>").addClass(Jh.Config.ulCls); me._createLis(data.appL,_ul); me._createLis(data.appM,_ul); me._createLis(data.appR,_ul); me._ele.ul = _ul; _ul.appendTo(me._ele.mtd); }, _createActionButton:function(){//创建功能按钮 var _add = $("<a class='button b' href='#' >添加模块</a>"); var _save= $("<a class='button b' href='#' >保存配置</a>"); me._ele.atd.append(_add).append(_save); me._bindAdd(_add); me._bindSave(_save); }, _createLis:function(obj,_ul){//创建li列表 $.each(obj,function(key,name){ _ul.append(me._createLi(key,name)); }); }, _createA:function(text){//创建A return $("<a href='javascript:void(0);' rel='"+text+"'>"+text+"</a>"); }, _createLi:function(key,name){//创建li return $("<li/>").append("<a href='#' rel='"+key+"'>"+name+"</a>") .append("<span class='ok'></span>"); }, _createTd:function(clsName,text){//创建td var t = $("<td>").addClass(clsName); if(text!=undefined){ t.text(text); } return t; }, _addPanel:function(o){ me.box.append(o); }, _bindAdd:function(obj){//添加模块 obj.click(function(){ var clicked = function(){ var form = $(this).children('form'), name = form.children('#modulename').val(), key = form.children("#modulekey").val(), layout = form.children("input[name='modulelayout']:checked").val(), position ; if(layout=='left'){ position = $("#"+Jh.Layout.location.left); }else if(layout=='center'){ position = $("#"+Jh.Layout.location.center); }else{ position = $("#"+Jh.Layout.location.right); } me._ele.ul.append(me._createLi(key,name));//添加功能标签 position.append(Jh.Portal._createPortalOne(key,name));//添加portal $.fallr('hide'); }; $.fallr('show', { buttons : { button1 : {text: '确定', onclick: clicked}, button2 : {text: '取消'} }, content : '<form style="margin-left:20px">'+ '<p>模块名:</p><input type="text" size="15" id="modulename" />'+ '<p>模块Code:</p><input type="text" size="15" id="modulekey" />'+ '<p>模块位置:</p>左:<input type="radio" name="modulelayout" checked="checked" value="left"/>  '+ '中:<input type="radio" name="modulelayout" value="center"/>  '+ '右:<input type="radio" name="modulelayout" value="right"/>'+ '</form>', icon : 'add', position: 'center' }); }); }, _bindSave:function(obj){//保存模块配置 obj.click(function(){ var _l = $("#"+Jh.Layout.location.left).sortable('toArray'), _m = $("#"+Jh.Layout.location.center).sortable('toArray'), _r = $("#"+Jh.Layout.location.right).sortable('toArray'), _a = $("."+Jh.Config.layCls+" a"), _layout =""; _a.each(function(){ if($(this).hasClass("active")){ _layout = $(this).attr("rel"); } }); if(_layout=="1:1:1"){ _layout="默认"; } var baseConfig="<p>left:["+_l+"]</p><p>center:["+_m+"]</p><p>right["+_r+"]</p>"+ "<p>当前布局:"+_layout+"</p>"; $.fallr('show', { content : baseConfig, position: 'center' }); }); }, _bindEvent:function(){//事件绑定 me._moduleLiClick(); me._layoutAClick(); }, _moduleLiClick:function(){//绑定模块LI单击事件 $("."+Jh.Config.ulCls+" li").live("click",function(){ var _this = $(this), _mName = _this.find("a").attr("rel"),//获取模块名 _m = $("#"+_mName), //模块div _d = _this.find(".ok");//对号 if(_d.is(":visible")){//判断是否显示 _d.hide();//隐藏对号 _m.hide();//隐藏模块 }else{ _d.show();//显示对号 _m.show();//显示模块 } Jh.Util.refresh(); }); }, _layoutAClick:function(){//绑定布局列表A 单击事件 $("."+Jh.Config.layCls+" a").click(function(){ var _this = $(this); var _v = _this.attr("rel"); me._ToLayout(_v); _this.addClass("active").siblings().removeClass("active"); }); }, _ToLayout:function(v){//刷新布局 var CssMode= Jh.Layout.layoutCss, //布局模式 CssText= Jh.Layout.layoutText,//css ModulesId= Jh.Layout.locationId, //模块id CssTextId=0,//默认css数组编号 ModuleItems="";//模块数组 $.each(CssMode, function(m, mn){ if(v==mn) CssTextId=m;//css 赋值 }); $.each(ModulesId, function(s, sn){ var currentModule = $(sn), cssName = CssText[CssTextId], ary = cssName.split(/\s+/);//得到当前布局css数组 switch(s){ case "left": s =0; break; case "center": s =1; break; case "right":s = 2; } if(ary[s]=='wnone') {//出现布局由3->2的变化 ,最右边栏目的内容搬到最左边 ModuleItems=currentModule.sortable('toArray');//获取最新的的元素 $.each( ModuleItems, function(m, mn){ $("#"+Jh.Layout.location.left).append($("#"+mn));//注意在两栏三栏间切换的时候 返回已经丢失的模块,而且只能够逐个添加元素,不可以一次添加多个 }); currentModule.empty();//摧毁原有的元素,以免重复出现冲突 } currentModule.removeClass("w250 w750 w500 wnone").addClass(ary[s]);//增加css }); } } }(); Jh.Portal = function(me){//Portal对象 var _box = "<div id='portal'></div>", _template = {//模板 l :"<div id='"+Jh.Layout.location.left+"' class='"+Jh.Config._groupWrapperClass+" w250'/>", m :"<div id='"+Jh.Layout.location.center+"' class='"+Jh.Config._groupWrapperClass+" w250'/>", r :"<div id='"+Jh.Layout.location.right+"' class='"+Jh.Config._groupWrapperClass+" w250'/>", portalWrap:"<div id='{key}' class='"+Jh.Config._groupItemClass+"'/>", itemHeader:"<div class='"+Jh.Config._groupItemHead+"'><h3>{name}</h3></div>", itemContent:"<div class='"+Jh.Config._groupItemContent+"'/>" }; return me={ init:function(op){//初始化 me._create(); me._bindData(op); me._bindEvent(); }, _create:function(){//创建 me.box = $(_box); me._elements = {}; me._createModulesWrap(); Jh.Util.toBody(me.box); }, _bindData:function(op){//绑定数据 $.each(op,function(key,item){ me._createPortal(key,item); }); }, _createModulesWrap:function(){//创建模块外层容器 me._elements.m_l = $(_template.l); me._elements.m_m = $(_template.m); me._elements.m_r = $(_template.r); me._addPanel(me._elements.m_l); me._addPanel(me._elements.m_m); me._addPanel(me._elements.m_r); }, _addPanel:function(o){//往容器里添加 me.box.append(o); }, _createPortal:function(key,item){//创建portal var mWrap ; switch(key){ case "appL":mWrap = me._elements.m_l; break; case "appM":mWrap = me._elements.m_m; break; case "appR":mWrap = me._elements.m_r; break; } $.each(item,function(k,o){ mWrap.append(me._createPortalOne(k,o)); }); }, _createPortalOne:function(key,name){//创建单个portal item var itemHeader = me._createItemHeader(name),//header itemContent = me._createItemContent(),//content portalWrap = $(Jh.Util.format(_template.portalWrap,{"key":key})) .append(itemHeader) .append(itemContent); return portalWrap; }, _createItemHeader:function(name){//创建Head var _itemHeader = $(Jh.Util.format(_template.itemHeader,{"name":name})),//格式化header _actionWrap = me._createDiv("action").hide().appendTo(_itemHeader);//创建一个div me._createA(Jh.Config.refresh,Jh.Config.refreshtext,true).appendTo(_actionWrap); me._createA(Jh.Config.min,Jh.Config.mintext,true).appendTo(_actionWrap); me._createA(Jh.Config.max,Jh.Config.maxtext,false).appendTo(_actionWrap); me._createA(Jh.Config.close,Jh.Config.closetext,true).appendTo(_actionWrap); _itemHeader.hover(function(){//滑过标题出现删除图标 $(this).find(".action").show(); },function(){ $(this).find(".action").hide(); }); return _itemHeader; }, _createItemContent:function(){//创建content var _content = $(_template.itemContent); $("<ul style='width:250px;'><li>xiaofanV587</li><li>xiaofanV587</li><li>xiaofanV587</li><li>xiaofanV587</li></ul>").appendTo(_content); return _content; }, _createDiv:function(classname){ var _div = $("<div/>").addClass(classname); return _div; }, _createA:function(classname,title,isShow){//创建A var _a = $("<a href='javascript:void(0);' class='"+classname+"' title='"+title+"'/>"); if(!isShow){ _a.hide(); } return _a ; }, _eventMin :function(){ $("."+Jh.Config.min).live("click",function(){//关闭面板 var _me = $(this); var _groupItem = _me.parent().parent().parent(); _groupItem.find("."+Jh.Config._groupItemContent).hide(); _groupItem.find("."+Jh.Config.max).show(); _me.hide(); }); }, _eventMax:function(){ $("."+Jh.Config.max).live("click",function(){//展开面板 var _me = $(this), _groupItem = _me.parent().parent().parent(); _groupItem.find("."+Jh.Config._groupItemContent).show(); _groupItem.find("."+Jh.Config.min).show(); _me.hide(); }); }, _eventRemove:function(){ $("."+Jh.Config.close).live("click",function(){//移除面板 var _this = $(this), _p = _this.parent().parent().parent();//得到当前父级面板 _p.fadeOut('500',function(){//500毫秒后移除 var _this = $(this); var _id = _this.attr("id");//得到模块id var _a = $(".tag-list").find("a[rel='"+_id+"']"); _this.remove(); _a.parent().remove();//移除功能列表中的li }); }); }, _eventRefresh:function(){ $("."+Jh.Config.refresh).live("click",function(){//刷新 var _me = $(this), _groupItem = _me.parent().parent().parent(); _groupItem.find("ul").empty().append("<li>刷新了</li>"); }); }, _eventSortable:function(){//绑定排序 $("."+Jh.Config._groupWrapperClass).sortable({ connectWith: "."+Jh.Config._groupWrapperClass, opacity :"0.6", dropOnEmpty:true }).disableSelection(); }, _bindEvent:function(){ //绑定面板所有事件 me._eventSortable(); me._eventRefresh(); me._eventRemove(); me._eventMax(); me._eventMin(); } }; }();