Here is the structure of my HTML body.
<body class="claro">
<div id="BorderContainerMain" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="width: 100%; border:0; padding:0; margin:0;">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="border: 0;">
<div id="topBanner" data-dojo-type="core.widget.GeneralMainHeader" ></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'left'" style="border: 0;">
<div id="leftNav" data-dojo-type="core.widget.GeneralLeftNavigation"></div>
</div>
<div id="contentStackContainer" data-dojo-type="dijit.layout.StackContainer" data-dojo-props="region:'center', style: 'border: 0; padding: 0; margin: 0;'"></div>
</div>
Now, my desire is to make the whole screen auto grow in height depending on the content of the center region and let the viewport handle the vertical scrolling. I am fairly new into dijit layout and I am using DOJO 1.6. I have already learned that I have to write code to achieve this. So, I am trying to get some experience guidance on this.
Thanks, Rishi
So, I wrote up a custom resize for my purpose but it is not working. Is there any why it not working. Here is the code:
dojo.provide("core.widget.ClientBorderContainer");
dojo.require("dijit.layout.BorderContainer");
dojo.declare("core.widget.ClientBorderContainer", [dijit.layout.BorderContainer], {
totalHeight: 0,
_setupChild: function(/*dijit._Widget*/ child){
// Override BorderContainer._setupChild().
var region = child.region;
console.debug("region :: "+region);
if(region){
this.inherited(arguments);
dojo.addClass(child.domNode, this.baseClass+"Pane");
var ltr = this.isLeftToRight();
if(region == "leading"){ region = ltr ? "left" : "right"; }
if(region == "trailing"){ region = ltr ? "right" : "left"; }
// Create draggable splitter for resizing pane,
// or alternately if splitter=false but BorderContainer.gutters=true then
// insert dummy div just for spacing
if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
var _Splitter = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
var splitter = new _Splitter({
id: child.id + "_splitter",
container: this,
child: child,
region: region,
live: this.liveSplitters
});
splitter.isSplitter = true;
child._splitterWidget = splitter;
dojo.place(splitter.domNode, child.domNode, "after");
// Splitters aren't added as Contained children, so we need to call startup explicitly
splitter.startup();
console.debug("Should not be printed as there is no splitter");
}
child.region = region; // TODO: technically wrong since it overwrites "trailing" with "left" etc.
}
},
resize: function(newSize, currentSize){
// Overrides BorderContainer.resize().
// resetting potential padding to 0px to provide support for 100% width/height + padding
// TODO: this hack doesn't respect the box model and is a temporary fix
if(!this.cs || !this.pe){
var node = this.domNode;
this.cs = dojo.getComputedStyle(node);
this.pe = dojo._getPadExtents(node, this.cs);
this.pe.r = dojo._toPixelValue(node, this.cs.paddingRight);
this.pe.b = dojo._toPixelValue(node, this.cs.paddingBottom);
dojo.style(node, "padding", "0px");
}
//Following section calculates the desired height of the BorderContainer
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
this.totalHeight = 0;
dojo.forEach(this.getChildren(), this.calculateHeight, this);
console.debug("this.totalHeight ::: "+this.totalHeight);
console.debug("newSize "+newSize);
console.debug("currentSize "+currentSize);
////////////////////////////////////////////////
// summary:
// Call this to resize a widget, or after its size has changed.
// description:
// Change size mode:
// When changeSize is specified, changes the marginBox of this widget
// and forces it to relayout its contents accordingly.
// changeSize may specify height, width, or both.
//
// If resultSize is specified it indicates the size the widget will
// become after changeSize has been applied.
//
// Notification mode:
// When changeSize is null, indicates that the caller has already changed
// the size of the widget, or perhaps it changed because the browser
// window was resized. Tells widget to relayout its contents accordingly.
//
// If resultSize is also specified it indicates the size the widget has
// become.
//
// In either mode, this method also:
// 1. Sets this._borderBox and this._contentBox to the new size of
// the widget. Queries the current domNode size if necessary.
// 2. Calls layout() to resize contents (and maybe adjust child widgets).
//
// changeSize: Object?
// Sets the widget to this margin-box size and position.
// May include any/all of the following properties:
// | {w: int, h: int, l: int, t: int}
//
// resultSize: Object?
// The margin-box size of this widget after applying changeSize (if
// changeSize is specified). If caller knows this size and
// passes it in, we don't need to query the browser to get the size.
// | {w: int, h: int}
var node = this.domNode;
// set margin box size, unless it wasn't specified, in which case use current size
if(newSize){
dojo.marginBox(node, newSize);
// set offset of the node
if(newSize.t){ node.style.top = newSize.t + "px"; }
if(newSize.l){ node.style.left = newSize.l + "px"; }
}
// If either height or width wasn't specified by the user, then query node for it.
// But note that setting the margin box and then immediately querying dimensions may return
// inaccurate results, so try not to depend on it.
var mb = currentSize || {};
dojo.mixin(mb, {h: this.totalHeight}); // calculated height overrides currentSize
if( !("h" in mb) || !("w" in mb) ){
mb = dojo.mixin(dojo.marginBox(node), mb); // just use dojo.marginBox() to fill in missing values
}
// Compute and save the size of my border box and content box
// (w/out calling dojo.contentBox() since that may fail if size was recently set)
var cs = dojo.getComputedStyle(node);
var me = dojo._getMarginExtents(node, cs);
var be = dojo._getBorderExtents(node, cs);
console.debug("mb.w "+mb.w);
console.debug("mb.h "+mb.h);
var bb = (this._borderBox = {
w: mb.w - (me.w + be.w),
h: mb.h - (me.h + be.h)
});
var pe = dojo._getPadExtents(node, cs);
console.debug("bb.w "+bb.w);
console.debug("bb.h "+bb.h);
this._contentBox = {
l: dojo._toPixelValue(node, cs.paddingLeft),
t: dojo._toPixelValue(node, cs.paddingTop),
w: bb.w - pe.w,
h: bb.h - pe.h
};
// Callback for widget to adjust size of its children
this.layout();
///////////////////////////////////////////////
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
},
calculateHeight: function(/*dijit._Widget*/ child){
var region = child.region;
console.debug("region :: "+region);
if(region && (region == "top" || region == "center" || region == "bottom")){
var childHeight = 0;
if(child instanceof dijit.layout.StackContainer){
console.debug("selectedChildWidget "+child.selectedChildWidget);
if(child.selectedChildWidget)
childHeight = dojo.contentBox(child.selectedChildWidget.domNode).h;
else
childHeight = dojo.contentBox(child.domNode).h;
}else{
childHeight = dojo.contentBox(child.domNode).h;
}
this.totalHeight = this.totalHeight+childHeight;
console.debug("childHeight = "+childHeight+" child.declaredClass"+child.declaredClass);
}
},
_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
// summary:
// This is the main routine for setting size/position of each child.
// description:
// With no arguments, measures the height of top/bottom panes, the width
// of left/right panes, and then sizes all panes accordingly.
//
// With changedRegion specified (as "left", "top", "bottom", or "right"),
// it changes that region's width/height to changedRegionSize and
// then resizes other regions that were affected.
// changedChildId:
// Id of the child which should be resized because splitter was dragged.
// changedChildSize:
// The new width/height (in pixels) to make specified child
if(!this._borderBox || !this._borderBox.h){
// We are currently hidden, or we haven't been sized by our parent yet.
// Abort. Someone will resize us later.
return;
}
console.debug("custom lay out children called");
// Generate list of wrappers of my children in the order that I want layoutChildren()
// to process them (i.e. from the outside to the inside)
var wrappers = dojo.map(this.getChildren(), function(child, idx){
return {
pane: child,
weight: [
child.region == "center" ? Infinity : 0,
child.layoutPriority,
(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
idx
]
};
}, this);
wrappers.sort(function(a, b){
var aw = a.weight, bw = b.weight;
for(var i=0; i<aw.length; i++){
if(aw[i] != bw[i]){
return aw[i] - bw[i];
}
}
return 0;
});
// Make new list, combining the externally specified children with splitters and gutters
var childrenAndSplitters = [];
dojo.forEach(wrappers, function(wrapper){
var pane = wrapper.pane;
childrenAndSplitters.push(pane);
if(pane._splitterWidget){
childrenAndSplitters.push(pane._splitterWidget);
}
});
// Compute the box in which to lay out my children
console.debug("this._borderBox.h :: "+this._borderBox.h);
var dim = {
l: this.pe.l,
t: this.pe.t,
w: this._borderBox.w - this.pe.w,
h: this._borderBox.h - this.pe.h
};
// Layout the children, possibly changing size due to a splitter drag
dijit.layout.layoutChildren(this.domNode, dim, childrenAndSplitters,
changedChildId, changedChildSize);
}
});
BorderContainer was written to take a sized box and calculate the center based on what's left over, sort of the opposite of what you're trying to do. AFAIK it won't support this.