/** * jQuery ligerUI 1.2.4 * * http://ligerui.com * * Author daomi 2014 [ gd_star@163.com ] * */ (function ($) { $.fn.ligerPortal = function (options) { return $.ligerui.run.call(this, "ligerPortal", arguments); }; $.ligerDefaults.Portal = { width: null, /*行元素:组件允许以纵向方式分割为几块 每一块(行)允许自定义N个列(column) 每一列允许自定义N个Panel(最小元素) rows:[ {columns:[ { width : '50%', panels : [{width:'100%',content:'内容'},{width:'100%',url:@url1}] },{ width : '50%', panels : [{width:'100%',url:@url2}] } ]} ] */ rows: null, /* 列元素: 组件将认为只存在一个row(块), 这一块 允许自定义N个列(column),结构同上 */ columns:null, url: null, //portal结构定义URL method: 'get', //获取数据http方式 parms: null, //提交到服务器的参数 draggable: false, //是否允许拖拽 onLoaded:null //url模式 加载完事件 }; $.ligerDefaults.Portal_rows = { width: null, height: null }; $.ligerDefaults.Portal_columns = { width: null, height: null }; $.ligerMethos.Portal = {}; $.ligerui.controls.Portal = function (element, options) { $.ligerui.controls.Portal.base.constructor.call(this, element, options); }; $.ligerui.controls.Portal.ligerExtend($.ligerui.core.UIComponent, { __getType: function () { return 'Portal'; }, __idPrev: function () { return 'Portal'; }, _extendMethods: function () { return $.ligerMethos.Portal; }, _init: function () { var g = this, p = this.options; $.ligerui.controls.Portal.base._init.call(this); if ($(">div", g.element).length) //如果已经定义了DIV子元素,那么这些元素将会转换为columns,这里暂时保存到tempInitPanels { p.columns = []; $(">div", g.element).each(function (i, jpanel) { p.columns[i] = { panels :[] }; }); g.tempInitPanels = $("
"); $(">div", g.element).appendTo(g.tempInitPanels); } if (!p.rows && p.columns) { p.rows = [{ columns: p.columns }]; } }, _render: function () { var g = this, p = this.options; g.portal = $(g.element).addClass("l-portal").html(""); g.set(p); }, _setRows: function (rows) { var g = this, p = this.options; g.rows = []; if (rows && rows.length) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; var jrow = $('
').appendTo(g.portal); g.rows[i] = g._renderRow({ row: row, rowIndex: i, jrow: jrow }); jrow.append('
'); } } }, _renderRow : function(e) { var row = e.row, rowIndex = e.rowIndex, jrow = e.jrow; var g = this, p = this.options; var rowObj = { element : jrow[0] }; if (row.width) jrow.width(row.width); if (row.height) jrow.height(row.height); if (row.columns) rowObj.columns = []; if (row.columns && row.columns.length) { for (var i = 0; i < row.columns.length; i++) { var column = row.columns[i]; var jcolumn = $('
').appendTo(jrow); rowObj.columns[i] = g._renderColumn({ column: column, columnIndex: i, jcolumn: jcolumn, rowIndex : rowIndex }); } } return rowObj; }, remove: function (e) { var g = this, p = this.options; var rowIndex = e.rowIndex, columnIndex = e.columnIndex, index = e.index; if (index == null) index = -1; if (index >= 0 && g.rows[rowIndex] && g.rows[rowIndex].columns && g.rows[rowIndex].columns[columnIndex] && g.rows[rowIndex].columns[columnIndex].panels) { var panel = g.rows[rowIndex].columns[columnIndex].panels[index]; panel && panel.close(); g._updatePortal(); } }, add: function (e) { var g = this, p = this.options; var rowIndex = e.rowIndex, columnIndex = e.columnIndex, index = e.index, panel = e.panel; if (index == null) index = -1; if (!(g.rows[rowIndex] && g.rows[rowIndex].columns && g.rows[rowIndex].columns[columnIndex])) return; var gColumn = g.rows[rowIndex].columns[columnIndex], pColumn = p.rows[rowIndex].columns[columnIndex], ligerPanel, jcolumn = $(gColumn.element); pColumn.panels = pColumn.panels || []; gColumn.panels = gColumn.panels || []; pColumn.panels.splice(index, 0, panel); if (index < 0) { var jpanel = $('
').insertBefore(gColumn.jplace); ligerPanel = jpanel.ligerPanel(panel); } else if(gColumn.panels[index]) { var jpanel = $('
').insertBefore(gColumn.panels[index].panel); ligerPanel = jpanel.ligerPanel(panel); } if (ligerPanel) { ligerPanel.bind('closed', g._createPanelClosed()); g.setPanelEvent({ panel: ligerPanel }); gColumn.panels.splice(index, 0, ligerPanel); } g._updatePortal(); }, _createPanelClosed : function () { var g = this, p = this.options; return function () { var panel = this;//ligerPanel对象 var panels = g.getPanels(); var rowIndex, columnIndex, index; $(panels).each(function () { if (this.panel == panel) { rowIndex = this.rowIndex; columnIndex = this.columnIndex; index = this.index; } }); p.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); g.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); }; }, _renderColumn: function (e) { var column = e.column, columnIndex = e.columnIndex, jcolumn = e.jcolumn; var rowIndex = e.rowIndex; var g = this, p = this.options; var columnObj = { element : jcolumn[0] }; if (column.width) jcolumn.width(column.width); if (column.height) jcolumn.height(column.height); if (column.panels) columnObj.panels = []; if (column.panels && column.panels.length) { for (var i = 0; i < column.panels.length; i++) { var panel = column.panels[i]; var jpanel = $('
').appendTo(jcolumn); columnObj.panels[i] = jpanel.ligerPanel(panel); columnObj.panels[i].bind('closed', g._createPanelClosed()); g.setPanelEvent({ panel: columnObj.panels[i] }); } } else if(g.tempInitPanels) { var tempPanel = g.tempInitPanels.find(">div:eq(" + columnIndex + ")"); if (tempPanel.length) { columnObj.panels = []; var panelOptions = {}; var jelement = tempPanel.clone(); if (liger.inject && liger.inject.getOptions) { panelOptions = liger.inject.getOptions({ jelement: jelement, defaults: $.ligerDefaults.Panel, config: liger.inject.config.Panel }); } columnObj.panels[0] = jelement.appendTo(jcolumn).ligerPanel(panelOptions); columnObj.panels[0].bind('closed', g._createPanelClosed()); g.setPanelEvent({ panel: columnObj.panels[0] }); } } columnObj.jplace = $('
').appendTo(jcolumn); return columnObj; }, setPanelEvent: function(e) { //panel:ligerui对象,jpanel:jQuery dom对象 var panel = e.panel, jpanel = panel.panel; var g = this, p = this.options; //拖拽支持 if ($.fn.ligerDrag && p.draggable) { jpanel.addClass("l-panel-draggable").ligerDrag({ proxy: false, revert: true, handler: ".l-panel-header span:first", onRendered: function () { }, onStartDrag: function (current, e) { g.portal.find(">.l-row").addClass("l-row-dragging"); this.jplace = $('
'); this.jplace.height(jpanel.height()); jpanel.width(jpanel.width()); jpanel.addClass("l-panel-dragging"); jpanel.css("position", "absolute"); jpanel.after(this.jplace); g._updatePortal(); }, onDrag: function (current, e) { var pageX = e.pageX || e.screenX, pageY = e.pageY || e.screenY; var height = jpanel.height(), width = jpanel.width(), offset = jpanel.offset(); var centerX = offset.left + width / 2, centerY = offset.top + 10; var panels = g.getPanels(), emptyColumns = g.getEmptyColumns(); var result = getPositionIn(panels, emptyColumns, centerX, centerY); if (result) { //判断是否跟上次匹配的位置一致 if (this.placeStatus) { if (this.placeStatus.panel && result.panel) { if (this.placeStatus.panel.rowIndex == result.panel.rowIndex && this.placeStatus.panel.columnIndex == result.panel.columnIndex && this.placeStatus.panel.index == result.panel.index && this.placeStatus.position == result.position) { return; } } if (this.placeStatus.column && result.column) //定位到空元素行 { if (this.placeStatus.column.rowIndex == result.column.rowIndex && this.placeStatus.column.columnIndex == result.column.columnIndex && this.placeStatus.position == result.position) { return; } } } if (result.position == "top") { this.jplace.insertBefore(result.panel ? result.panel.jpanel : result.column.jplace); this.savedPosition = result.panel ? result.panel : result.column this.savedPosition.inTop = true; } else if (result.position == "bottom") { this.jplace.insertAfter(result.panel.jpanel); this.savedPosition = result.panel; this.savedPosition.inTop = false; } this.placeStatus = result; } else//没有匹配到 { this.placeStatus = null; } //从指定的元素集合匹配位置 function getPositionIn(panels, columns, x, y) { for (i = 0, l = panels.length; i < l; i++) { var o = panels[i]; if (o.panel == panel) //如果是本身 { continue; } var r = positionIn(o, null, x, y); if (r) return r; } for (i = 0, l = columns.length; i < l; i++) { var column = columns[i]; var r = positionIn(null, column, x, y); if (r) return r; } return null; } //坐标在目标区域范围内 x,y为panel标题栏中间的位置 function positionIn(panel, column, x, y) { var jelement = panel ? panel.jpanel : column.jplace; if (!jelement) return null; var height = jelement.height(), width = jelement.width(); var left = jelement.offset().left, top = jelement.offset().top; var diff = 3; if (x > left - diff && x < left + width + diff) { if (y > top - diff && y < top + height / 2 + diff) { return { panel: panel, column: column, position: "top" }; } if (y > top + height / 2 - diff && y < top + height + diff) { return { panel: panel, column: column, position: panel ? "bottom" : "top" }; } } return null; } }, onStopDrag: function (current, e) { g.portal.find(">.l-row").removeClass("l-row-dragging"); panel.set('width', panel.get('width')); jpanel.removeClass("l-panel-dragging"); //将jpanel替换到jplace的位置 if (this.jplace) { jpanel.css({ "position": "relative", "left": null, "top": null }); jpanel.insertAfter(this.jplace); g.portal.find(">.l-row > .l-column >.l-panel-place").remove(); if (this.savedPosition) { var panels = g.getPanels(); var rowIndex, columnIndex, index; $(panels).each(function () { if (this.panel == panel) { rowIndex = this.rowIndex; columnIndex = this.columnIndex; index = this.index; } }); var oldPanelOptions = p.rows[rowIndex].columns[columnIndex].panels[index]; var oldPanel = g.rows[rowIndex].columns[columnIndex].panels[index]; p.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); g.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); if (this.savedPosition.panel) { p.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels.splice(this.savedPosition.index + this.savedPosition.inTop ? -1 : 0, 0, oldPanelOptions); g.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels.splice(this.savedPosition.index + this.savedPosition.inTop ? -1 : 0, 0, oldPanel); } else { p.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels = [oldPanelOptions]; g.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels = [oldPanel]; } } } g._updatePortal(); return false; } }); } }, _updatePortal:function() { var g = this, p = this.options; $(g.rows).each(function (rowIndex) { $(this.columns).each(function (columnIndex) { if (this.panels && this.panels.length) { $(this.element).removeClass("l-column-empty"); } else { $(this.element).addClass("l-column-empty"); } }); }); }, getPanels : function () { var g = this, p = this.options; var panels = []; $(g.rows).each(function (rowIndex) { $(this.columns).each(function (columnIndex) { $(this.panels).each(function (index) { panels.push({ rowIndex: rowIndex, columnIndex: columnIndex, index: index, panel : this, jpanel : this.panel }); }); }); }); return panels; }, getPanel: function (e) { var g = this, p = this.options; e = $.extend({ rowIndex: 0, columnIndex: 0, index : 0 }, e); var panel = null; $(g.rows).each(function (rowIndex) { $(this.columns).each(function (columnIndex) { $(this.panels).each(function (index) { if (panel) return; if (rowIndex == e.rowIndex && columnIndex == e.columnIndex && index == e.index) { panel = this; } }); }); }); return panel; }, getEmptyColumns:function(){ var g = this, p = this.options; var columns = []; $(g.rows).each(function (rowIndex) { $(this.columns).each(function (columnIndex) { if (!this.panels || !this.panels.length) { columns.push({ rowIndex: rowIndex, columnIndex: columnIndex, jplace : this.jplace }); } }); }); return columns; }, _setUrl: function (url) { var g = this, p = this.options; if (!url) return; $.ajax({ url: url, data: p.parms, type: p.method, dataType: 'json', success: function (rows) { g.set('rows', rows); } }); }, _setWidth: function (value) { value && this.portal.width(value); }, collapseAll: function () { var g = this, p = this.options; var panels = g.getPanels(); $(panels).each(function (i,o) { var panel = o.panel; panel.collapse(); }); }, expandAll: function () { var g = this, p = this.options; var panels = g.getPanels(); $(panels).each(function (i, o) { var panel = o.panel; panel.expand(); }); } }); })(jQuery);