You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
633 lines
18 KiB
633 lines
18 KiB
define([ |
|
"dojo/_base/kernel", |
|
"dojo/_base/declare", // declare |
|
"dojo/_base/array", |
|
"dojo/_base/connect", |
|
"dojo/_base/sniff", |
|
"dojo/dom-class", |
|
"dojo/dom-style", |
|
"dojo/dom-geometry", |
|
"dojo/dom-construct", |
|
"dojo/_base/lang", |
|
"dojo/_base/window", |
|
"dojo/ready", // dojo.ready |
|
"dojox/layout/GridContainerLite" |
|
],function(dojo, declare, array, connect, has, domClass, domStyle, geom, domConstruct, lang, win, ready, GridContainerLite){ |
|
return declare( |
|
"dojox.layout.GridContainer", |
|
GridContainerLite, |
|
{ |
|
// summary: |
|
// A grid containing any kind of objects and acting like web portals. |
|
// |
|
// description: |
|
// This component inherits of all features of gridContainerLite plus : |
|
// |
|
// - Resize colums |
|
// - Add / remove columns |
|
// - Fix columns at left or at right. |
|
// example: |
|
// | <div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true"> |
|
// | <div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div> |
|
// | <div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div> |
|
// | <div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div> |
|
// | </div> |
|
// |
|
// example: |
|
// | dojo.ready(function(){ |
|
// | var cpane1 = new dijit.layout.ContentPane({ title:"cpane1", content: "Content Pane 1 : Drag Me !" }), |
|
// | cpane2 = new dijit.layout.ContentPane({ title:"cpane2", content: "Content Pane 2 : Drag Me !" }), |
|
// | cpane3 = new dijit.layout.ContentPane({ title:"cpane3", content: "Content Pane 3 : Drag Me !" }); |
|
// | |
|
// | var widget = new dojox.layout.GridContainer({ |
|
// | nbZones: 3, |
|
// | isAutoOrganized: true |
|
// | }, dojo.byId("idNode")); |
|
// | widget.addChild(cpane1, 0, 0); |
|
// | widget.addChild(cpane2, 1, 0); |
|
// | widget.addChild(cpane3, 2, 1); |
|
// | widget.startup(); |
|
// | }); |
|
|
|
// hasResizableColumns: Boolean |
|
// Allow or not resizing of columns by a grip handle. |
|
hasResizableColumns: true, |
|
|
|
// liveResizeColumns: Boolean |
|
// Specifies whether columns resize as you drag (true) or only upon mouseup (false) |
|
liveResizeColumns : false, |
|
|
|
// minColWidth: Integer |
|
// Minimum column width in percentage. |
|
minColWidth: 20, |
|
|
|
// minChildWidth: Integer |
|
// Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property) |
|
minChildWidth: 150, |
|
|
|
// mode: String |
|
// Location to add/remove columns, must be set to 'left' or 'right' (default). |
|
mode: "right", |
|
|
|
// isRightFixed: Boolean |
|
// Define if the last right column is fixed. |
|
// Used when you add or remove columns by calling setColumns method. |
|
isRightFixed: false, |
|
|
|
// isLeftFixed: Boolean |
|
// Define if the last left column is fixed. |
|
// Used when you add or remove columns by calling setColumns method. |
|
isLeftFixed: false, |
|
|
|
startup: function(){ |
|
// summary: |
|
// Call the startup of GridContainerLite and place grips |
|
// if user has chosen the hasResizableColumns attribute to true. |
|
|
|
//console.log("dojox.layout.GridContainer ::: startup"); |
|
this.inherited(arguments); |
|
if(this.hasResizableColumns){ |
|
for(var i = 0; i < this._grid.length - 1; i++){ |
|
this._createGrip(i); |
|
} |
|
// If widget has a container parent, grips will be placed |
|
// by method onShow. |
|
if(!this.getParent()){ |
|
// Fix IE7 : |
|
// The CSS property height:100% for the grip |
|
// doesn't work anytime. It's necessary to wait |
|
// the end of loading before to place grips. |
|
ready(lang.hitch(this, "_placeGrips")); |
|
} |
|
} |
|
}, |
|
|
|
resizeChildAfterDrop : function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){ |
|
// summary: |
|
// Call when a child is dropped. |
|
// description: |
|
// Allow to resize and put grips |
|
// node: |
|
// domNode of dropped widget. |
|
// targetArea: |
|
// AreaManager Object containing information of targetArea |
|
// indexChild: |
|
// Index where the dropped widget has been placed |
|
|
|
if(this.inherited(arguments)){ |
|
this._placeGrips(); |
|
} |
|
}, |
|
|
|
onShow: function(){ |
|
// summary: |
|
// Place grips in the right place when the GridContainer becomes visible. |
|
|
|
//console.log("dojox.layout.GridContainer ::: onShow"); |
|
this.inherited(arguments); |
|
this._placeGrips(); |
|
}, |
|
|
|
resize: function(){ |
|
// summary: |
|
// Resize the GridContainer widget and columns. |
|
// Replace grips if it's necessary. |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.layout.GridContainer ::: resize"); |
|
this.inherited(arguments); |
|
// Fix IE6 : |
|
// IE6 calls method resize itself. |
|
// If the GridContainer is not visible at this time, |
|
// the method _placeGrips can return a negative value with |
|
// contentBox method. (see method _placeGrip() with Fix Ie6 for the height) |
|
if(this._isShown() && this.hasResizableColumns){ |
|
this._placeGrips(); |
|
} |
|
}, |
|
|
|
_createGrip: function(/*Integer*/ index){ |
|
// summary: |
|
// Create a grip for a specific zone. |
|
// index: |
|
// index where the grip has to be created. |
|
// tags: |
|
// protected |
|
|
|
//console.log("dojox.layout.GridContainer ::: _createGrip"); |
|
var dropZone = this._grid[index], |
|
grip = domConstruct.create("div", { 'class': "gridContainerGrip" }, this.domNode); |
|
dropZone.grip = grip; |
|
dropZone.gripHandler = [ |
|
this.connect(grip, "onmouseover", function(e){ |
|
var gridContainerGripShow = false; |
|
for(var i = 0; i < this._grid.length - 1; i++){ |
|
if(domClass.contains(this._grid[i].grip, "gridContainerGripShow")){ |
|
gridContainerGripShow = true; |
|
break; |
|
} |
|
} |
|
if(!gridContainerGripShow){ |
|
domClass.replace(e.target, "gridContainerGripShow", "gridContainerGrip"); |
|
} |
|
})[0], |
|
this.connect(grip, "onmouseout", function(e){ |
|
if(!this._isResized){ |
|
domClass.replace(e.target, "gridContainerGrip", "gridContainerGripShow"); |
|
} |
|
})[0], |
|
this.connect(grip, "onmousedown", "_resizeColumnOn")[0], |
|
this.connect(grip, "ondblclick", "_onGripDbClick")[0] |
|
]; |
|
}, |
|
|
|
_placeGrips: function(){ |
|
// summary: |
|
// Define the position of a grip and place it on page. |
|
// tags: |
|
// protected |
|
|
|
//console.log("dojox.layout.GridContainer ::: _placeGrips"); |
|
var gripWidth, height, left = 0, grip; |
|
//var scroll = this.domNode.style.overflowY; |
|
|
|
array.forEach(this._grid, function(dropZone){ |
|
if(dropZone.grip){ |
|
grip = dropZone.grip; |
|
if(!gripWidth){ |
|
gripWidth = grip.offsetWidth / 2; |
|
} |
|
|
|
left += geom.getMarginBox(dropZone.node).w; |
|
|
|
domStyle.set(grip, "left", (left - gripWidth) + "px"); |
|
//if(dojo.isIE == 6){ do it fot all navigators |
|
if(!height){ |
|
height = geom.getContentBox(this.gridNode).h; |
|
} |
|
if(height > 0){ |
|
domStyle.set(grip, "height", height + "px"); |
|
} |
|
//} |
|
} |
|
}, this); |
|
}, |
|
|
|
_onGripDbClick: function(){ |
|
// summary: |
|
// Called when a double click is catch. Resize all columns with the same width. |
|
// The method resize of children have to be called. |
|
// tags: |
|
// callback protected |
|
|
|
//console.log("dojox.layout.GridContainer ::: _onGripDbClick"); |
|
this._updateColumnsWidth(this._dragManager); |
|
this.resize(); |
|
}, |
|
|
|
_resizeColumnOn: function(/*Event*/e){ |
|
// summary: |
|
// Connect events to listen the resize action. |
|
// Change the type of width columns (% to px). |
|
// Calculate the minwidth according to the children. |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.layout.GridContainer ::: _resizeColumnOn", e); |
|
this._activeGrip = e.target; |
|
this._initX = e.pageX; |
|
e.preventDefault(); |
|
|
|
win.body().style.cursor = "ew-resize"; |
|
|
|
this._isResized = true; |
|
|
|
var tabSize = []; |
|
var grid; |
|
var i; |
|
|
|
for(i = 0; i < this._grid.length; i++){ |
|
tabSize[i] = geom.getContentBox(this._grid[i].node).w; |
|
} |
|
|
|
this._oldTabSize = tabSize; |
|
|
|
for(i = 0; i < this._grid.length; i++){ |
|
grid = this._grid[i]; |
|
if(this._activeGrip == grid.grip){ |
|
this._currentColumn = grid.node; |
|
this._currentColumnWidth = tabSize[i]; |
|
this._nextColumn = this._grid[i + 1].node; |
|
this._nextColumnWidth = tabSize[i + 1]; |
|
} |
|
grid.node.style.width = tabSize[i] + "px"; |
|
} |
|
|
|
// calculate the minWidh of all children for current and next column |
|
var calculateChildMinWidth = function(childNodes, minChild){ |
|
var width = 0; |
|
var childMinWidth = 0; |
|
|
|
array.forEach(childNodes, function(child){ |
|
if(child.nodeType == 1){ |
|
var objectStyle = domStyle.getComputedStyle(child); |
|
var minWidth = (has("ie")) ? minChild : parseInt(objectStyle.minWidth); |
|
|
|
childMinWidth = minWidth + |
|
parseInt(objectStyle.marginLeft) + |
|
parseInt(objectStyle.marginRight); |
|
|
|
if(width < childMinWidth){ |
|
width = childMinWidth; |
|
} |
|
} |
|
}); |
|
return width; |
|
}; |
|
var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth); |
|
|
|
var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth); |
|
|
|
var minPix = Math.round((geom.getMarginBox(this.gridContainerTable).w * this.minColWidth) / 100); |
|
|
|
this._currentMinCol = currentColumnMinWidth; |
|
this._nextMinCol = nextColumnMinWidth; |
|
|
|
if(minPix > this._currentMinCol){ |
|
this._currentMinCol = minPix; |
|
} |
|
if(minPix > this._nextMinCol){ |
|
this._nextMinCol = minPix; |
|
} |
|
this._connectResizeColumnMove = connect.connect(win.doc, "onmousemove", this, "_resizeColumnMove"); |
|
this._connectOnGripMouseUp = connect.connect(win.doc, "onmouseup", this, "_onGripMouseUp"); |
|
}, |
|
|
|
_onGripMouseUp: function(){ |
|
// summary: |
|
// Call on the onMouseUp only if the reiszeColumnMove was not called. |
|
// tags: |
|
// callback |
|
|
|
//console.log(dojox.layout.GridContainer ::: _onGripMouseUp"); |
|
win.body().style.cursor = "default"; |
|
|
|
connect.disconnect(this._connectResizeColumnMove); |
|
connect.disconnect(this._connectOnGripMouseUp); |
|
|
|
this._connectOnGripMouseUp = this._connectResizeColumnMove = null; |
|
|
|
if(this._activeGrip){ |
|
domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow"); |
|
} |
|
|
|
this._isResized = false; |
|
}, |
|
|
|
_resizeColumnMove: function(/*Event*/e){ |
|
// summary: |
|
// Change columns size. |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.layout.GridContainer ::: _resizeColumnMove"); |
|
e.preventDefault(); |
|
if(!this._connectResizeColumnOff){ |
|
connect.disconnect(this._connectOnGripMouseUp); |
|
this._connectOnGripMouseUp = null; |
|
this._connectResizeColumnOff = connect.connect(win.doc, "onmouseup", this, "_resizeColumnOff"); |
|
} |
|
|
|
var d = e.pageX - this._initX; |
|
if(d == 0){ return; } |
|
|
|
if(!(this._currentColumnWidth + d < this._currentMinCol || |
|
this._nextColumnWidth - d < this._nextMinCol)){ |
|
|
|
this._currentColumnWidth += d; |
|
this._nextColumnWidth -= d; |
|
this._initX = e.pageX; |
|
this._activeGrip.style.left = parseInt(this._activeGrip.style.left) + d + "px"; |
|
|
|
if(this.liveResizeColumns){ |
|
this._currentColumn.style["width"] = this._currentColumnWidth + "px"; |
|
this._nextColumn.style["width"] = this._nextColumnWidth + "px"; |
|
this.resize(); |
|
} |
|
} |
|
}, |
|
|
|
_resizeColumnOff: function(/*Event*/e){ |
|
// summary: |
|
// Disconnect resize events. |
|
// Change the type of width columns (px to %). |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.layout.GridContainer ::: _resizeColumnOff"); |
|
win.body().style.cursor = "default"; |
|
|
|
connect.disconnect(this._connectResizeColumnMove); |
|
connect.disconnect(this._connectResizeColumnOff); |
|
|
|
this._connectResizeColumnOff = this._connectResizeColumnMove = null; |
|
|
|
if(!this.liveResizeColumns){ |
|
this._currentColumn.style["width"] = this._currentColumnWidth + "px"; |
|
this._nextColumn.style["width"] = this._nextColumnWidth + "px"; |
|
//this.resize(); |
|
} |
|
|
|
var tabSize = [], |
|
testSize = [], |
|
tabWidth = this.gridContainerTable.clientWidth, |
|
node, |
|
update = false, |
|
i; |
|
|
|
for(i = 0; i < this._grid.length; i++){ |
|
node = this._grid[i].node; |
|
if(has("ie")){ |
|
tabSize[i] = geom.getMarginBox(node).w; |
|
testSize[i] = geom.getContentBox(node).w; |
|
} |
|
else{ |
|
tabSize[i] = geom.getContentBox(node).w; |
|
testSize = tabSize; |
|
} |
|
} |
|
|
|
for(i = 0; i < testSize.length; i++){ |
|
if(testSize[i] != this._oldTabSize[i]){ |
|
update = true; |
|
break; |
|
} |
|
} |
|
|
|
if(update){ |
|
var mul = has("ie") ? 100 : 10000; |
|
for(i = 0; i < this._grid.length; i++){ |
|
this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%"; |
|
} |
|
this.resize(); |
|
} |
|
|
|
if(this._activeGrip){ |
|
domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow"); |
|
} |
|
|
|
this._isResized = false; |
|
}, |
|
|
|
setColumns: function(/*Integer*/nbColumns){ |
|
// summary: |
|
// Set the number of columns. |
|
// nbColumns: |
|
// Number of columns |
|
|
|
//console.log("dojox.layout.GridContainer ::: setColumns"); |
|
var z, j; |
|
if(nbColumns > 0){ |
|
var length = this._grid.length, |
|
delta = length - nbColumns; |
|
if(delta > 0){ |
|
var count = [], zone, start, end, nbChildren; |
|
// Check if right or left columns are fixed |
|
// Columns are not taken in account and can't be deleted |
|
if(this.mode == "right"){ |
|
end = (this.isLeftFixed && length > 0) ? 1 : 0; |
|
start = (this.isRightFixed) ? length - 2 : length - 1 |
|
for(z = start; z >= end; z--){ |
|
nbChildren = 0; |
|
zone = this._grid[z].node; |
|
for(j = 0; j < zone.childNodes.length; j++){ |
|
if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){ |
|
nbChildren++; |
|
break; |
|
} |
|
} |
|
if(nbChildren == 0){ count[count.length] = z; } |
|
if(count.length >= delta){ |
|
this._deleteColumn(count); |
|
break; |
|
} |
|
} |
|
if(count.length < delta){ |
|
connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]); |
|
} |
|
} |
|
else{ // mode = "left" |
|
start = (this.isLeftFixed && length > 0) ? 1 : 0; |
|
end = (this.isRightFixed) ? length - 1 : length; |
|
for(z = start; z < end; z++){ |
|
nbChildren = 0; |
|
zone = this._grid[z].node; |
|
for(j = 0; j < zone.childNodes.length; j++){ |
|
if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){ |
|
nbChildren++; |
|
break; |
|
} |
|
} |
|
if(nbChildren == 0){ count[count.length] = z; } |
|
if(count.length >= delta){ |
|
this._deleteColumn(count); |
|
break; |
|
} |
|
} |
|
if(count.length < delta){ |
|
//Not enough empty columns |
|
connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]); |
|
} |
|
} |
|
} |
|
else{ |
|
if(delta < 0){ this._addColumn(Math.abs(delta)); } |
|
} |
|
if(this.hasResizableColumns){ this._placeGrips(); } |
|
} |
|
}, |
|
|
|
_addColumn: function(/*Integer*/nbColumns){ |
|
// summary: |
|
// Add some columns. |
|
// nbColumns: |
|
// Number of column to added |
|
// tags: |
|
// private |
|
|
|
//console.log("dojox.layout.GridContainer ::: _addColumn"); |
|
var grid = this._grid, |
|
dropZone, |
|
node, |
|
index, |
|
length, |
|
isRightMode = (this.mode == "right"), |
|
accept = this.acceptTypes.join(","), |
|
m = this._dragManager; |
|
|
|
//Add a grip to the last column |
|
if(this.hasResizableColumns && ((!this.isRightFixed && isRightMode) |
|
|| (this.isLeftFixed && !isRightMode && this.nbZones == 1) )){ |
|
this._createGrip(grid.length - 1); |
|
} |
|
|
|
for(var i = 0; i < nbColumns; i++){ |
|
// Fix CODEX defect #53025 : |
|
// Apply acceptType attribute on each new column. |
|
node = domConstruct.create("td", { |
|
'class': "gridContainerZone dojoxDndArea" , |
|
'accept': accept, |
|
'id': this.id + "_dz" + this.nbZones |
|
}); |
|
|
|
length = grid.length; |
|
|
|
if(isRightMode){ |
|
if(this.isRightFixed){ |
|
index = length - 1; |
|
grid.splice(index, 0, { |
|
'node': grid[index].node.parentNode.insertBefore(node, grid[index].node) |
|
}); |
|
} |
|
else{ |
|
index = length; |
|
grid.push({ 'node': this.gridNode.appendChild(node) }); |
|
} |
|
} |
|
else{ |
|
if(this.isLeftFixed){ |
|
index = (length == 1) ? 0 : 1; |
|
this._grid.splice(1, 0, { |
|
'node': this._grid[index].node.parentNode.appendChild(node, this._grid[index].node) |
|
}); |
|
index = 1; |
|
} |
|
else{ |
|
index = length - this.nbZones; |
|
this._grid.splice(index, 0, { |
|
'node': grid[index].node.parentNode.insertBefore(node, grid[index].node) |
|
}); |
|
} |
|
} |
|
if(this.hasResizableColumns){ |
|
//Add a grip to resize columns |
|
if((!isRightMode && this.nbZones != 1) || |
|
(!isRightMode && this.nbZones == 1 && !this.isLeftFixed) || |
|
(isRightMode && i < nbColumns-1) || |
|
(isRightMode && i == nbColumns-1 && this.isRightFixed)){ |
|
this._createGrip(index); |
|
} |
|
} |
|
// register tnbZoneshe new area into the areaManager |
|
m.registerByNode(grid[index].node); |
|
this.nbZones++; |
|
} |
|
this._updateColumnsWidth(m); |
|
}, |
|
|
|
_deleteColumn: function(/*Array*/indices){ |
|
// summary: |
|
// Remove some columns with indices passed as an array. |
|
// indices: |
|
// Column index array |
|
// tags: |
|
// private |
|
|
|
//console.log("dojox.layout.GridContainer ::: _deleteColumn"); |
|
var child, grid, index, |
|
nbDelZones = 0, |
|
length = indices.length, |
|
m = this._dragManager; |
|
for(var i = 0; i < length; i++){ |
|
index = (this.mode == "right") ? indices[i] : indices[i] - nbDelZones; |
|
grid = this._grid[index]; |
|
|
|
if(this.hasResizableColumns && grid.grip){ |
|
array.forEach(grid.gripHandler, function(handler){ |
|
connect.disconnect(handler); |
|
}); |
|
domConstruct.destroy(this.domNode.removeChild(grid.grip)); |
|
grid.grip = null; |
|
} |
|
|
|
m.unregister(grid.node); |
|
domConstruct.destroy(this.gridNode.removeChild(grid.node)); |
|
this._grid.splice(index, 1); |
|
this.nbZones--; |
|
nbDelZones++; |
|
} |
|
|
|
// last grip |
|
var lastGrid = this._grid[this.nbZones-1]; |
|
if(lastGrid.grip){ |
|
array.forEach(lastGrid.gripHandler, connect.disconnect); |
|
domConstruct.destroy(this.domNode.removeChild(lastGrid.grip)); |
|
lastGrid.grip = null; |
|
} |
|
|
|
this._updateColumnsWidth(m); |
|
}, |
|
|
|
_updateColumnsWidth: function(/*Object*/ manager){ |
|
// summary: |
|
// Update the columns width. |
|
// manager: |
|
// dojox.mdnd.AreaManager singleton |
|
// tags: |
|
// private |
|
|
|
//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth"); |
|
this.inherited(arguments); |
|
if(manager === null){ |
|
manager = this._dragManager; |
|
} |
|
manager._dropMode.updateAreas(manager._areaList); |
|
}, |
|
|
|
destroy: function(){ |
|
connect.unsubscribe(this._dropHandler); |
|
this.inherited(arguments); |
|
} |
|
}); |
|
});
|
|
|