PDA

View Full Version : [SOLVED] Menu Not Hiding



krider2010
7 Sep 2007, 1:54 AM
Hi,

I've been through the forums with a variety of searches but am unable to find a solution to my problem. I wondered if anyone had any insight about where I should look next...?

I've got a context menu on a grid row which displays fine. The event handling on the (currently single) item on the menu also works fine and things happen, debug goes into the console etc. However nothing causes that menu to be hidden. Even explicitly calling the hide function on the menu does nothing visually (though it does cause isVisible() to then return false instead of true).

In the same layout I've got a tree with a context menu which does exactly as it should. It appears, clicking on an item causes things to happen based on my event handler, and then it disappears.

I've debugged both in FF2/Firebug and it appears that the handleClick() in BaseItem makes the following call:
this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);

Which for the menu on the tree then some time later causes the hide() method the menu to fire. This doesn't seem to be happening on the grid context menu. The parameters of hideDelay, parentMenu etc. are all valid according to firebug.

Right clicking on the again grid causes another instance of the menu to appear with the old one still visible.

If I replace the contents of the region in which the grid resides with a new content panel as part of the menu item click handler this works, but my menu is still sat on top of that too!

Has anyone experienced a menu that won't hide (aside from when it's config is to stay open ;) ) or issues with this sort of defer call? Would it be related to where the dom element the menu is using is declared?

Thanks for any advice/pointers.

PS I've even explicitly set hideOnClick: true in the item even though that should be the default behaviour and the menu still won't go away.

fay
7 Sep 2007, 2:01 AM
I set up my context menus on grids as follows and they work fine:



var gridRangesContextMenu = new Ext.menu.Menu({
id: 'gridRangesContextMenu',
items: [
{text: 'Select All', handler: onRangesSelectAllClick},
{text: 'Clear All', handler: onRangesClearAllClick}
]
});

// ...

gridRanges.addListener('rowcontextmenu', onGridRangesContextMenu);

// ...

function onGridRangesContextMenu(grid, rowIndex, e) {
e.stopEvent();
var coords = e.getXY();
gridRangesContextMenu.showAt([coords[0], coords[1]]);
}

Are you calling stopEvent()? (Note, I'm still using 1.0.1a so I don't know if it's different in the later version.)

krider2010
7 Sep 2007, 2:15 AM
Thanks for the response. I seem to be doing all the right things :(

I'm using version 1.1.1 of Ext.

My code is setup as follows (the this. references are just because I have all the code/widgets in a class):

//...

this.gridContextMenu = new Ext.menu.Menu(this.getGridContextMenuElement());
var viewSummary = new Ext.menu.Item({
text: 'View Summary',
hideOnClick: true,
handler: this.onViewSummary,
scope: this
});
this.gridContextMenu.add(
viewSummary
);

this.grid.addListener('rowcontextmenu', this.onRowContextMenu, this);

//...

onRowContextMenu : function(grid, rowIndex, e) {
e.stopEvent();
var coords = e.getXY();
this.gridContextMenu.showAt([coords[0], coords[1]]);
this.gridContextMenu.rowRecord = grid.getDataSource().getAt(rowIndex);
},

//...

onViewSummary : function(item, event) {
// do something here
console.log(item);
},

//...

getGridElement : function() {
if (typeof this.gridEl == "undefined") {
this.gridEl = Ext.DomHelper.append(document.body, {id: 'fl-grid'}, true);
}
return this.gridEl;
},

getGridContextMenuElement : function() {
if (typeof this.cmEl == "undefined") {
this.cmEl = Ext.DomHelper.append(this.getGridElement(), {id: 'fl-grid-cm'}, true);
}
return this.cmEl;
},

//...

Also the grid is displayed inside a GridPanel in the layout if that helps at all.

krider2010
7 Sep 2007, 5:10 AM
An update - and I've finally solved it :)

Using the following two pieces of code I can see that the timeout and function calls are happening as I would expect:


window.setTimeout = window.setTimeout.createInterceptor(function() {
console.log(arguments);
return true;
});


Function.prototype.defer = Function.prototype.defer.createInterceptor(function() {
console.log(arguments);
return true;
});

The output from the defer helped me to shed light on the problem:

...
[200, Object id=ext-gen91 events=Object items=[1] el=Object, [true]]
...
[200, Object dom=div#fl-grid-cm id=fl-grid-cm visibilityMode=1, [true]]
...

And after my fix (more in a minute):

...
[200, Object id=ext-gen91 events=Object items=[1] el=Object, [true]]
...
[200, Object id=ext-gen233 events=Object items=[1] el=Object, [true]]
...


Note the generated ids instead of the one I was passing in via an Element!

Basically I had to change this line

this.gridContextMenu = new Ext.menu.Menu(this.getGridContextMenuElement());
to this one

this.gridContextMenu = new Ext.menu.Menu();

I can now see (reading the source of Menu) that I should have been creating my Menus differently. I shouldn't have been passing in the element like I was. Or I could take the approach of {id: ...} as the config element but I'm happy with the auto-generated assuming there is no code-style problem with doing it this way.

Doh! Sorry for being a numpty!

Hopefully this might help anyone else with a similar problem - or even just debugging defer/timout things.