PDA

View Full Version : [solved] Ext 3.1 vertical scroll



rblon
18 Dec 2009, 2:17 PM
Ext 3.1.0 introduced a problem with vertical scroll bars.
Easiest way to show it, is using the Portal example.
In Ext 3.0.0, a vertical scrollbar works correct
In Ext 3.1.0, a vertical scrollbar also introduces a horizontal scrollbar.
The attached screenshots show this behaviour.
It is not clear to me how to solve it in this example.

Animal
21 Dec 2009, 1:57 AM
Yes. A change was made in 3.1 in which, to find the available size for laying out in, the CSS style size is requested first in preference to the clientHeight/clientWidth.

This was to work around an IE bug in which the clientHeight was reported incorrectly.

http://i131.photobucket.com/albums/p286/TimeTrialAnimal/IEbugasusual.jpg

Try this in your overrides file:



var pxMatch = /(\d+(?:\.\d+)?)px/;
Ext.override(Ext.Element, {
getViewSize : function(contentBox){
var doc = document,
me = this,
d = me.dom,
extdom = Ext.lib.Dom,
isDoc = (d == doc || d == doc.body),
isBB, w, h, tbBorder = 0, lrBorder = 0,
tbPadding = 0, lrPadding = 0;
if (isDoc) {
return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
}
isBB = me.isBorderBox();
tbBorder = me.getBorderWidth('tb');
lrBorder = me.getBorderWidth('lr');
tbPadding = me.getPadding('tb');
lrPadding = me.getPadding('lr');

// Width calcs
// Try the style first, then clientWidth, then offsetWidth
if (w = me.getStyle('width').match(pxMatch)){
if ((w = Math.round(w[1])) && isBB){
// Style includes the padding and border if isBB
w -= (lrBorder + lrPadding);
}
if (!contentBox){
w += lrPadding;
}
// Minimize with clientWidth if present
d.clientWidth && (d.clientWidth < w) && (w = d.clientWidth);
} else {
if (!(w = d.clientWidth) && (w = d.offsetWidth)){
w -= lrBorder;
}
if (w && contentBox){
w -= lrPadding;
}
}

// Height calcs
// Try the style first, then clientHeight, then offsetHeight
if (h = me.getStyle('height').match(pxMatch)){
if ((h = Math.round(h[1])) && isBB){
// Style includes the padding and border if isBB
h -= (tbBorder + tbPadding);
}
if (!contentBox){
h += tbPadding;
}
// Minimize with clientHeight if present
d.clientHeight && (d.clientHeight < h) && (h = d.clientHeight);
} else {
if (!(h = d.clientHeight) && (h = d.offsetHeight)){
h -= tbBorder;
}
if (h && contentBox){
h -= tbPadding;
}
}

return {
width : w,
height : h
};
}
});

rblon
21 Dec 2009, 2:49 AM
great, your override works!
However, if on load, a vertical scrollbar is required, a horizontal scrollbar is still created. Only when you (slightly) resize the browser window it goes away. Adding the following statement in portal.js solves that



viewport.doLayout();


I assume this should be considered a bug in Ext 3.1?

Animal
21 Dec 2009, 3:24 AM
I suppose so.

It's only doing one layout of the page in 3.1. Obviously this is more efficient. There was a performance problem in 3.0.3 and below because multiple doLayout calls were plastered over the layout which ran over it sizing it several times.

Now I think there's a problem because if the layout resulted in appearance of scrollbars, then in some cases (like a fitting layout like column), then if the available space has changed, it needs to do it once more.

Try



Ext.override(Ext.layout.columnLayout, {
onLayout : function(ct, target, targetSize){
var cs = ct.items.items, len = cs.length, c, i;

if(!this.innerCt){
// the innerCt prevents wrapping and shuffling while
// the container is resizing
this.innerCt = target.createChild({cls:'x-column-inner'});
this.innerCt.createChild({cls:'x-clear'});
}
this.renderAll(ct, this.innerCt);

var size = targetSize || target.getViewSize(true);

if(size.width < 1 && size.height < 1){ // display none?
return;
}

var w = size.width - this.scrollOffset,
h = size.height,
pw = w;

this.innerCt.setWidth(w);

// some columns can be percentages while others are fixed
// so we need to make 2 passes

for(i = 0; i < len; i++){
c = cs[i];
if(!c.columnWidth){
pw -= (c.getSize().width + c.getPositionEl().getMargins('lr'));
}
}

pw = pw < 0 ? 0 : pw;

for(i = 0; i < len; i++){
c = cs[i];
if(c.columnWidth){
c.setSize(Math.floor(c.columnWidth * pw) - c.getPositionEl().getMargins('lr'));
}
}
// Do a second pass if the layout resulted in a vertical scrollbar (changing the available width)
if (!targetSize && ((size = target.getViewSize(true)).width != w)) {
this.onLayout(ct, target, size);
}
}
});

rblon
21 Dec 2009, 4:09 AM
not sure if I get this. The second override is to avoid the doLayout() call, right? And hence, should be used in combination with the first override?

However, it is not working for me. I have corrected the first line


Ext.override(Ext.layout.ColumnLayout, {

but I still observe the issue that initially there is a horizontal scrollbar (without view.doLayout() call). Both with your initial code (with secondPass parameter) as with the code after edit (with targetSize parameter)

Animal
21 Dec 2009, 5:14 AM
That's not it.

I am refactoring locally right now to clear all this up, and I have that example working, and accommodating scrollbars with no double layouting.

I plan to post my refactored Container classes (Container, Toolbar, Panel, TabPanel and Menu), and my refactored layout managers soon.

PranKe01
7 Feb 2010, 4:30 AM
Will this bug be fixed in the 3.1.1 release? Or is there a workaround available?

Thanks!

PranKe01
3 Mar 2010, 12:36 AM
@Animal: Did you already posted the code somewhere?

Animal
3 Mar 2010, 12:44 AM
Didn't 3.1.1 fix all these issues?

PranKe01
3 Mar 2010, 1:00 AM
I add three grids to a tab using div-containers and the grid.render function. When I resize the window, there appear unneeded scrollbars. I think I should use a layout for that...

Animal
3 Mar 2010, 1:39 AM
I add three grids to a tab using div-containers and the grid.render function.

There's your problem then. You haven't read the manual, documentation, constant reminders on the forums. You just wrote random code.