PDA

View Full Version : [FIXED-20][2.x,3.0] Ext.MsgBox needs to explicitly blur the clicked button.



Animal
18 Jul 2008, 1:11 AM
This is an obscure one that only manifests on Firefox that was driving me mad trying to implement an MsgBox.confirm of a drop gesture.

What happens is that after clicking an MsgBox Button, the Msgbox is hidden using visibility and offsets, but that does not blur the clicked Button. It retains focus.

So the next mousedown, instead of firing "mousedown", fires "blur". The DragDrop listener only handles the mousedown, so the drag does not happen when you expect it when you start the next drag gesture.

The fix is twofold.

First, implement a blur method in Ext.Button:



Ext.override(Ext.Button, {
/**
* Blur the button
*/
blur : function(){
this.el.child(this.buttonSelector).blur();
}
});


In fact for efficiency, it may be best to capture this.el.child(this.buttonSelector) into this.btnEl on render.

Then in Ext.MessageBox:



var handleButton = function(button){
buttons[button].blur();
if(dlg.isVisible()){
dlg.hide();
Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
}
};

brian.moeskau
21 Jul 2008, 2:08 PM
Maybe I'm not following the use case, or it's specific to DD, but I'm not sure why the button blurring would interfere with mousedown on another el? Can you tell me what's different about your use case from this example?



Ext.onReady(function(){
var p = new Ext.Panel({
renderTo: Ext.getBody(),
title: 'Foo',
height: 200,
width: 300,
html: 'Click me...',
buttons: [{
text:'Show MessageBox',
handler: function(){
Ext.Msg.alert('Foo', 'Bar');
}
}]
});
p.body.on('mousedown', function(){
p.body.update('mousedown '+new Date().format('H:i:s:u')).highlight();
});
});

Animal
4 Aug 2008, 11:00 PM
The live test at http://extjs.com/deploy/dev/examples/dd/dnd_grid_to_formpanel.html exhibits this behaviour.

Drag a Record to the Form, click the "Reset Example" Button and the next mousedown does not initiate a drag!

Of course it's not in the Ext.MsgBox context, so it just needs a manual workaround to explicitly blur the Button in the handler, but it demonstrates the principle of blurring "stealing" the mousedown event.

brian.moeskau
5 Aug 2008, 7:47 AM
Thanks -- I didn't have time to look at this earlier, but I'll check into it.

Animal
26 Mar 2009, 4:37 AM
This issue is related to hiding Components which contain the focussed element and is biting people.

http://extjs.com/forum/showthread.php?t=60387

The problem is that if a focussable element (such as a Button) is used as the trigger to cause hiding of a Component, then that focussable element remains focussed even if hidden.

So the properties of the next mouse event are overriden by the blur event which inevitable happens.

The triggering focussable element needs programatically blurring somehow.

I'm not sure how this can be fixed on a general basis.

Ideas anyone?

mystix
26 Mar 2009, 4:51 AM
Ext.getBody().focus() the moment the triggering element is clicked?
scratch that. doesn't work.

probably need to insert a 1x1 pixel anchor element <a> somewhere after the opening <body> tag, and attempt to focus that.

nescha
10 Sep 2009, 3:28 AM
This issue impose another conflict mentioned in http://www.extjs.com/forum/showthread.php?p=385062#post385062 (combining of CheckBoxSelectionModel and Drag & Drop - on initial grid load, you can't start dragging immediately but you need to click anywhere in the browser to blur some component, even moving focus to FF console will work)

Animal
10 Sep 2009, 3:37 AM
Looks like the same issue.

The Grid's focusEl is focussed after a checkbox click (or is the checkbox focussed?)

Whichever, the next mousedown is transformed into a blur event.

nescha
10 Sep 2009, 4:29 AM
I managed to exclude this behavior for current project. Since we have some advanced automatic logic that always focuses first field in shown form, I just added parameter not to do this on form that coexist with the grid.

Animal
10 Sep 2009, 5:34 AM
How about a mouseenter listener on the GridView's mainBody which calls



this.focusEl.focus();
this.focusEl.blur();


To ensure that nothing is focussed on mouseover?

nescha
10 Sep 2009, 6:29 AM
Works!

Just add listener to grid's render event:



listeners: {
render: function() {
var gridView = this.getView();
gridView.mainBody.addListener('mouseover', function() {
gridView.focusEl.focus();
gridView.focusEl.blur();
});
}
}