I'm having problems with dismissing a control that is being popped up by the PopupControlExtender.
The control in question is a panel with a listbox in it. When the panel first pops up, if I click outside the panel the popup is dimissed, just like it should be. But if I click on an item in the listbox while the panel is popped up (giving it focus), I have to click twice outside of the panel to dismiss the popup.
I found this code in the PopupControlExtender:
this._onClick = function() {
// Handle clicks in the popup We use a simple flag because
// cancelling the event bubbling doesn't always seem to work
// in IE as we expect. We then check in _onBodyClick whether
// it was set to ignore the event.
_wasClicked = true;
event.cancelBubble = true;
}
My understanding of this is that the _wasClicked flag is set because this is a click in our control, and we don't want the onBodyClick() handler to think it's a click outside the control; the flag is set so that onBodyClick() eats the click. You do this because cancelling the event bubbling doesn't work predictably, that is, you try to cancel the bubbling in onClick(), but sometimes onBodyClick() gets called anyway. Therefore, if onBodyClick(), sees _wasClicked = true, it eats the event and resets _wasClicked:
this._onBodyClick = function() {
// Handle clicks for the whole window
if (_wasClicked) {
// If we received a click that we expected, do nothing
_wasClicked = false;
} else if (_popupVisible) {
// If the click was outside our control, hide the popup
this.hidePopup();
}
}
Now, the problem I'm having with the extender is that two clicks outside the panel are required to dismiss the popup if the popup is given focus with a click. My suspicion was that the first click was being eaten through the _wasClicked path, and the second was dismissing the popup.
So somehow _wasClicked was being set in a control event handler, but not being reset by onBodyClick(). I figured that this could happen if "event.cancelBubble = true" was actually doing what it was supposed to. That is, if _wasClicked is set to true on the assumption that onBodyClick() will be called, yet event.cancelBubble = true works and never triggers onBodyClick(), then _wasClicked will not be reset, and will be "true" even if I click outside the control, thus eating that click and not dismissing the popup.
When I commented out the line "event.cancelBubble = true", I seem to have fixed the problem: the popup always disappears after a single click outside of the control.
My question is whether I really "fixed" this, as there may be some behavior that I'm not aware of or some good reason why event.cancelBubble must be set to true.