Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 76bb9b6

Browse files
committed
fix(panel): Allow clickOutsideToClose to work with propagateContainerEvents
If both the `clickOutsideToClose` and `propagateContainerEvents` parameters are set to true within the panel configuration, then the panel will be closed when a click happens outside of the panel. Fixes #9388
1 parent c810d5e commit 76bb9b6

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

src/components/panel/panel.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,23 +1825,33 @@ MdPanelRef.prototype._configureEscapeToClose = function() {
18251825
*/
18261826
MdPanelRef.prototype._configureClickOutsideToClose = function() {
18271827
if (this.config['clickOutsideToClose']) {
1828-
var target = this.panelContainer;
1829-
var sourceElem;
1828+
var target = this.config['propagateContainerEvents'] ?
1829+
angular.element(document.body) :
1830+
this.panelContainer;
1831+
var sourceEl;
18301832

18311833
// Keep track of the element on which the mouse originally went down
18321834
// so that we can only close the backdrop when the 'click' started on it.
1833-
// A simple 'click' handler does not work,
1834-
// it sets the target object as the element the mouse went down on.
1835+
// A simple 'click' handler does not work, it sets the target object as the
1836+
// element the mouse went down on.
18351837
var mousedownHandler = function(ev) {
1836-
sourceElem = ev.target;
1838+
sourceEl = ev.target;
18371839
};
18381840

18391841
// We check if our original element and the target is the backdrop
18401842
// because if the original was the backdrop and the target was inside the
18411843
// panel we don't want to panel to close.
18421844
var self = this;
18431845
var mouseupHandler = function(ev) {
1844-
if (sourceElem === target[0] && ev.target === target[0]) {
1846+
if (self.config['propagateContainerEvents']) {
1847+
1848+
// We check if the sourceEl of the event is the panel element or one
1849+
// of it's children. If it is not, then close the panel.
1850+
if (sourceEl !== self.panelEl[0] && !self.panelEl[0].contains(sourceEl)) {
1851+
self.close();
1852+
}
1853+
1854+
} else if (sourceEl === target[0] && ev.target === target[0]) {
18451855
ev.stopPropagation();
18461856
ev.preventDefault();
18471857

@@ -2713,6 +2723,7 @@ MdPanelPosition.prototype._constrainToViewport = function(panelEl) {
27132723
}
27142724
};
27152725

2726+
27162727
/**
27172728
* Switches between 'start' and 'end'.
27182729
* @param {string} position Horizontal position of the panel
@@ -2902,6 +2913,7 @@ MdPanelAnimation.prototype.closeTo = function(closeTo) {
29022913
return this;
29032914
};
29042915

2916+
29052917
/**
29062918
* Specifies the duration of the animation in milliseconds.
29072919
* @param {number|{open: number, close: number}} duration
@@ -2927,6 +2939,7 @@ MdPanelAnimation.prototype.duration = function(duration) {
29272939
}
29282940
};
29292941

2942+
29302943
/**
29312944
* Returns the element and bounds for the animation target.
29322945
* @param {string|!Element|{top: number, left: number}} location

src/components/panel/panel.spec.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,20 @@ describe('$mdPanel', function() {
544544
expect(PANEL_EL).not.toExist();
545545
});
546546

547+
it('should close when clickOutsideToClose set to true and ' +
548+
'propagateContainerEvents is also set to true', function() {
549+
var config = {
550+
propagateContainerEvents: true,
551+
clickOutsideToClose: true
552+
};
553+
554+
openPanel(config);
555+
556+
clickPanelContainer(getElement('body'));
557+
558+
expect(PANEL_EL).not.toExist();
559+
});
560+
547561
it('should not close when escapeToClose set to false', function() {
548562
openPanel();
549563

@@ -3025,12 +3039,22 @@ describe('$mdPanel', function() {
30253039
attachedElements.push(element);
30263040
}
30273041

3028-
function clickPanelContainer() {
3042+
/**
3043+
* Returns the angular element associated with a CSS selector or element.
3044+
* @param el {string|!angular.JQLite|!Element}
3045+
* @returns {!angular.JQLite}
3046+
*/
3047+
function getElement(el) {
3048+
var queryResult = angular.isString(el) ? document.querySelector(el) : el;
3049+
return angular.element(queryResult);
3050+
}
3051+
3052+
function clickPanelContainer(container) {
30293053
if (!panelRef) {
30303054
return;
30313055
}
30323056

3033-
var container = panelRef.panelContainer;
3057+
container = container || panelRef.panelContainer;
30343058

30353059
container.triggerHandler({
30363060
type: 'mousedown',

0 commit comments

Comments
 (0)