631 lines
18 KiB
JavaScript
631 lines
18 KiB
JavaScript
//>>built
|
|
define("dojox/layout/GridContainer", [
|
|
"dojo/_base/kernel",
|
|
"dojo/_base/array",
|
|
"dojo/_base/connect",
|
|
"dojo/_base/declare",
|
|
"dojo/_base/html",
|
|
"dojo/_base/lang",
|
|
"dojo/_base/window",
|
|
"dojo/ready", // dojo.ready
|
|
"dojox/layout/GridContainerLite"
|
|
],function(dojo){
|
|
return dojo.declare(
|
|
"dojox.layout.GridContainer",
|
|
dojox.layout.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.
|
|
dojo.ready(dojo.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 = dojo.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(dojo.hasClass(this._grid[i].grip, "gridContainerGripShow")){
|
|
gridContainerGripShow = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!gridContainerGripShow){
|
|
dojo.removeClass(e.target, "gridContainerGrip");
|
|
dojo.addClass(e.target, "gridContainerGripShow");
|
|
}
|
|
})[0],
|
|
this.connect(grip, "onmouseout", function(e){
|
|
if(!this._isResized){
|
|
dojo.removeClass(e.target, "gridContainerGripShow");
|
|
dojo.addClass(e.target, "gridContainerGrip");
|
|
}
|
|
})[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;
|
|
|
|
dojo.forEach(this._grid, function(dropZone){
|
|
if(dropZone.grip){
|
|
grip = dropZone.grip;
|
|
if(!gripWidth){
|
|
gripWidth = grip.offsetWidth / 2;
|
|
}
|
|
|
|
left += dojo.marginBox(dropZone.node).w;
|
|
|
|
dojo.style(grip, "left", (left - gripWidth) + "px");
|
|
//if(dojo.isIE == 6){ do it fot all navigators
|
|
if(!height){
|
|
height = dojo.contentBox(this.gridNode).h;
|
|
}
|
|
if(height > 0){
|
|
dojo.style(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();
|
|
|
|
dojo.body().style.cursor = "ew-resize";
|
|
|
|
this._isResized = true;
|
|
|
|
var tabSize = [];
|
|
var grid;
|
|
var i;
|
|
|
|
for(i = 0; i < this._grid.length; i++){
|
|
tabSize[i] = dojo.contentBox(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;
|
|
|
|
dojo.forEach(childNodes, function(child){
|
|
if(child.nodeType == 1){
|
|
var objectStyle = dojo.getComputedStyle(child);
|
|
var minWidth = (dojo.isIE) ? 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((dojo.marginBox(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 = dojo.connect(dojo.doc, "onmousemove", this, "_resizeColumnMove");
|
|
this._connectOnGripMouseUp = dojo.connect(dojo.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");
|
|
dojo.body().style.cursor = "default";
|
|
|
|
dojo.disconnect(this._connectResizeColumnMove);
|
|
dojo.disconnect(this._connectOnGripMouseUp);
|
|
|
|
this._connectOnGripMouseUp = this._connectResizeColumnMove = null;
|
|
|
|
if(this._activeGrip){
|
|
dojo.removeClass(this._activeGrip, "gridContainerGripShow");
|
|
dojo.addClass(this._activeGrip, "gridContainerGrip");
|
|
}
|
|
|
|
this._isResized = false;
|
|
},
|
|
|
|
_resizeColumnMove: function(/*Event*/e){
|
|
// summary:
|
|
// Change columns size.
|
|
// tags:
|
|
// callback
|
|
|
|
//console.log("dojox.layout.GridContainer ::: _resizeColumnMove");
|
|
e.preventDefault();
|
|
if(!this._connectResizeColumnOff){
|
|
dojo.disconnect(this._connectOnGripMouseUp);
|
|
this._connectOnGripMouseUp = null;
|
|
this._connectResizeColumnOff = dojo.connect(dojo.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");
|
|
dojo.body().style.cursor = "default";
|
|
|
|
dojo.disconnect(this._connectResizeColumnMove);
|
|
dojo.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(dojo.isIE){
|
|
tabSize[i] = dojo.marginBox(node).w;
|
|
testSize[i] = dojo.contentBox(node).w;
|
|
}
|
|
else{
|
|
tabSize[i] = dojo.contentBox(node).w;
|
|
testSize = tabSize;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < testSize.length; i++){
|
|
if(testSize[i] != this._oldTabSize[i]){
|
|
update = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(update){
|
|
var mul = dojo.isIE ? 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){
|
|
dojo.removeClass(this._activeGrip, "gridContainerGripShow");
|
|
dojo.addClass(this._activeGrip, "gridContainerGrip");
|
|
}
|
|
|
|
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){
|
|
dojo.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
|
|
dojo.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 = dojo.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){
|
|
dojo.forEach(grid.gripHandler, function(handler){
|
|
dojo.disconnect(handler);
|
|
});
|
|
dojo.destroy(this.domNode.removeChild(grid.grip));
|
|
grid.grip = null;
|
|
}
|
|
|
|
m.unregister(grid.node);
|
|
dojo.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){
|
|
dojo.forEach(lastGrid.gripHandler, dojo.disconnect);
|
|
dojo.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);
|
|
manager._dropMode.updateAreas(manager._areaList);
|
|
},
|
|
|
|
destroy: function(){
|
|
dojo.unsubscribe(this._dropHandler);
|
|
this.inherited(arguments);
|
|
}
|
|
});
|
|
});
|