The problem only occurs in IE 7, 8 and 9. When a button with a menu has been pressed and the menu is visible, if the user then clicks on a text input field while the menu is still open, the process of closing the menu via Menu.hide(), which is called by the event handler for the mousedown event in menu manager, seems to consume the following focus event and it does not get propagated to the text input field.

The problem occurs for manually created <input type="text"> tags and Extjs TextField as well.

Test Case:

This code below contains an example for both 3.x and 4.x, the 3.x is commented out currently

Click on the button, while the menu is visible click on the plain text field, press the delete key

Click on the button, while the menu is visible click on the Extjs text field

Enter some text into the Extjs text field, click on the button, while the menu is visible click on the Extjs text field

The result that was expected:

Delete key should delete text

Blue high light should be visible and the empty text should disappear

Text should be selected

The result that occurs instead:

Delete key does not delete text

Blue high light is not visible and the empty text does not disappear

Text is not selected

Debugging already done:

The solution was to delay the function Menu.hide() by 1ms thus allowing the text input to receive the focus event.

Possible fix:

For my fix I overrode Menu.hide() function so as not to modify the original

The code below overrides that method, but it actually waits 1ms then calls the original, so no code from the original function was copied. This allows us to port the fix to 4.x in the future, should we need to

Code:

// The anonymous function wrapped in a closure executes right away which allows us to keep the reference to the original
// function before it is overridden.
(function() {
// Get a reference to the original function.
var origHide = Ext.menu.Menu.prototype.hide;
// Override the original function.
Ext.override(Ext.menu.Menu, {
hide: function(){
// Used another anonymous function here because you can't do: origHide.apply.defer(...)
var executeOrigHide = function() {
origHide.apply(this, arguments);
};
// defer the execution by 1ms.
executeOrigHide.defer(1, this);
}
});
})();

but your fix breaks the menus for columns in a grid? how is that a viable solution if it causes more issues elsewhere. go to a grid. hide a column through the column header menu and then try to reopen that column menu. it doesnt work.