Code:
handleHdCtx : function(g, index, e){
e.stopEvent();
var hd = this.getHeaderCell(index);
this.hdCtxIndex = index;
var ms = this.hmenu.items, cm = this.cm;
ms.get("asc").setDisabled(!cm.isSortable(index));
ms.get("desc").setDisabled(!cm.isSortable(index));
if(this.grid.enableColLock !== false){
ms.get("lock").setDisabled(cm.isLocked(index));
ms.get("unlock").setDisabled(!cm.isLocked(index));
}
this.hmenu.show(hd, "tl-bl?"); //<---- add the '?', same as ExtJS 2.0
},
here is the corrected code in source/core/Element.js, (add 2 functions, rewrite 1)
GetAbsWindowBottom: function()
{
// Compute the bottom of the popup window and the bottom of
// the browser window, in absolute co-ordinates - different
// on all browsers but the below should be accurate usually!
var abswindowbottom = 0;
if (typeof(window.innerHeight) == 'number')
abswindowbottom = window.innerHeight;
else if (document.documentElement && document.documentElement.clientHeight)
abswindowbottom = document.documentElement.clientHeight;
else if (document.body && document.body.clientHeight)
abswindowbottom = document.body.clientHeight;
if (typeof(window.pageYOffset) == 'number')
abswindowbottom = abswindowbottom + window.pageYOffset;
else if (document.body && document.body.scrollTop)
abswindowbottom = abswindowbottom + document.body.scrollTop;
else if (document.documentElement && document.documentElement.scrollTop)
abswindowbottom = abswindowbottom + document.documentElement.scrollTop;
return abswindowbottom;
},
GetAbsWindowRight: function()
{
// Compute the bottom of the popup window and the bottom of
// the browser window, in absolute co-ordinates - different
// on all browsers but the below should be accurate usually!
var abswindowright = 0;
if (typeof(window.innerWidth) == 'number')
abswindowright = window.innerWidth;
else if (document.documentElement && document.documentElement.clientWidth)
abswindowright = document.documentElement.clientWidth;
else if (document.body && document.body.clientWidth)
abswindowright = document.body.clientWidth;
if (typeof(window.pageXOffset) == 'number')
abswindowright = abswindowright + window.pageXOffset;
else if (document.body && document.body.scrollLeft)
abswindowright = abswindowright + document.body.scrollLeft;
else if (document.documentElement && document.documentElement.scrollLeft)
abswindowright = abswindowright + document.documentElement.scrollLeft;
return abswindowright;
},
/**
* Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the
* supported position values.
* @param {String/HTMLElement/Ext.Element} element The element to align to.
* @param {String} position The position to align to.
* @param {Array} offsets (optional) Offset the positioning by [x, y]
* @return {Array} [x, y]
*/
getAlignToXY : function(alignTo_element, position_rules, explicit_offset){
alignTo_element = Ext.get(alignTo_element), d = this.dom;
if(!alignTo_element.dom){
throw "Element.alignTo with an element that doesn't exist";
}
var keep_within_viewport = false; //constrain to viewport
var offset_delta = 5;
var our_corner_rules = "", align_to_rules = "";
var border_width=d.offsetWidth ? 18 : 0;
explicit_offset = explicit_offset || [0,0];
// if no rules specified, use (our) TopLeft to (their)BottomLeft
// assumes our menu is UNDER the other one
if(!position_rules){
position_rules = "tl-bl";
// if only "keep within the viewport"
}else if(position_rules == "?"){
// assume our menu is UNDER the other one and constrained in viewport
position_rules = "tl-bl?";
// if only one rule specified,
// assume it is the target element alignment point,
}else if(position_rules.indexOf("-") == -1){
// ours will be top left (under or right)
position_rules = "tl-" + p;
}
// all lower case for the rest of the code
position_rules = position_rules.toLowerCase();
// parse the position options string
var m = position_rules.match(/^([a-z]+)-([a-z]+)(\?)?$/);
// if nothing found, then we have a big problem
if(!m){
throw "Element.alignTo with an invalid alignment " + p;
}
// get the rules segments
our_corner_rules = m[1], align_to_rules = m[2], keep_within_viewport = m[3] ? true : false;
//Subtract the aligned el"s internal xy from the target"s offset xy
//plus custom offset to get the aligned el's new offset xy
// get our alignment point
var a1 = this.getAnchorXY(our_corner_rules, true);
// get the target element alignment point
var a2 = alignTo_element.getAnchorXY(align_to_rules, false);
// calculate the position deltas, left/right (x), top/bottom (y)
var x = a2[0] - a1[0] + explicit_offset[0];
var y = a2[1] - a1[1] + explicit_offset[1];
if(keep_within_viewport==true){
// our absolute bottom edge
var abspopupbottom = y + this.getHeight() + offset_delta;
// our absolute right edge
var abspopupright = x + this.getWidth() + offset_delta;
// bottom of window absolute position
var abswindowbottom = this.GetAbsWindowBottom()-border_width;
// right edge of window absolute position
var windowWidth = this.GetAbsWindowRight()-border_width;
// If menu goes outside the viewport, down or right, move it
if (abspopupbottom > abswindowbottom || abspopupright>windowWidth ){
//
// If we exceed a viewport boundary and
// the to be aligned el is anchored on the target el border that is perpendicular to the viewport border,
// allow the aligned el to slide on that border,
// otherwise
// swap the to be aligned el to the opposite border of the target el
// watch out for both viewport boundaries
//
var our_corner_rulesY = our_corner_rules.charAt(0), our_corner_rulesX = our_corner_rules.charAt(our_corner_rules.length-1);
var align_to_rulesY = align_to_rules.charAt(0), align_to_rulesX = align_to_rules.charAt(align_to_rules.length-1);
// if one is top and the other is bottom, we could swap
var swapY = ((our_corner_rulesY=="t" && align_to_rulesY=="b") || (our_corner_rulesY=="b" && align_to_rulesY=="t"));
// if one is left and one is right, we could sawp
var swapX = ((our_corner_rulesX=="r" && align_to_rulesX=="l") || (our_corner_rulesX=="l" && align_to_rulesX=="r"));
// work variable
var xy = "";
// if the menu will be off screen to the right
if (abspopupright>windowWidth) {
// and we support swapping it completely on the other side
if(swapX){
// then swap the alignment rules, and re-calculate
xy = this.getAlignToXY(alignTo_element,align_to_rules+"-"+our_corner_rules+keep_within_viewport, explicit_offset);
x=xy[0]; y=xy[1];
// watch out for the other dimension adjust, right AND bottom
if(abspopupbottom > abswindowbottom){
y = y - (abspopupbottom - abswindowbottom);
}
return [x,y];
}
// othewise we need to slide adjust the difference.
else
x = x - (abspopupright - windowWidth);
}
// if the menu would be off screen to the bottom
if(abspopupbottom > abswindowbottom){
// and we support swapping it completely on the other side
if(swapY){
// then swap the alignment rules, and re-calculate
xy = this.getAlignToXY(alignTo_element,align_to_rules+"-"+our_corner_rules+keep_within_viewport, explicit_offset);
x=xy[0]; y=xy[1];
// watch out for the other dimension adjust, bottom AND right
if (abspopupright>windowWidth){
x = x - (abspopupright - windowWidth);
}
return [x,y];
}
// otherwise we need to slide adjust the difference
else
y = y - (abspopupbottom - abswindowbottom);
}
}
}
return [x,y];
},
This has been tested in IE6 , 7, Firefox 2, Safari. In Opera 9.23 I am unable to get mouse clicks thru.