diff --git a/README.md b/README.md index 83fd3a7..e9079f1 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ var winMtds = L.control.window(map) | close() | undefined | Hide and remove window. | | enableBtn() | undefined | Enables the OK button of the window (default). | | disableBtn() | undefined | Disables the OK button of the window. | +| isHidden() | boolean | If the window is currently hidden | ### Other options | Property | Description | Default Value | Possible values | @@ -86,6 +87,7 @@ var winMtds = L.control.window(map) | prompt.buttonOK | Text for ```OK``` button. | 'OK' | String | | prompt.buttonCancel | Text for ```Cancel``` button | button hidden by default | String | | visible | Render window immediately. | false | Boolean | +| closeOnClickOutside | Closes the window on a click outside of its bounds | false | Boolean | ### Other Methods | Method | Returns | Description | diff --git a/src/L.Control.Window.js b/src/L.Control.Window.js index cc66b4a..41d6bee 100644 --- a/src/L.Control.Window.js +++ b/src/L.Control.Window.js @@ -12,8 +12,10 @@ L.Control.Window = L.Control.extend({ prompt: undefined, maxWidth: 600, modal: false, - position: 'center' + position: 'center', + closeOnClickOutside: false }, + initialize: function (container, options) { var self = this; @@ -29,18 +31,18 @@ L.Control.Window = L.Control.extend({ } // Create popup window container - this._wrapper = L.DomUtil.create('div',modality+' leaflet-control-window-wrapper', L.DomUtil.get(this.options.element)); + this._wrapper = L.DomUtil.create('div', modality+' leaflet-control-window-wrapper', L.DomUtil.get(this.options.element)); - this._container = L.DomUtil.create('div', 'leaflet-control leaflet-control-window '+this.options.className,this._wrapper); + this._container = L.DomUtil.create('div', 'leaflet-control leaflet-control-window '+this.options.className, this._wrapper); this._container.setAttribute('style','max-width:'+this.options.maxWidth+'px'); - this._containerTitleBar = L.DomUtil.create('div', 'titlebar',this._container); - this.titleContent = L.DomUtil.create('h2', 'title',this._containerTitleBar); - this._containerContent = L.DomUtil.create('div', 'content' ,this._container); - this._containerPromptButtons = L.DomUtil.create('div', 'promptButtons' ,this._container); + this._containerTitleBar = L.DomUtil.create('div', 'titlebar', this._container); + this.titleContent = L.DomUtil.create('h2', 'title', this._containerTitleBar); + this._containerContent = L.DomUtil.create('div', 'content', this._container); + this._containerPromptButtons = L.DomUtil.create('div', 'promptButtons', this._container); if (this.options.closeButton) { - this._closeButton = L.DomUtil.create('a', 'close',this._containerTitleBar); + this._closeButton = L.DomUtil.create('a', 'close', this._containerTitleBar); this._closeButton.innerHTML = '×'; } @@ -54,6 +56,7 @@ L.Control.Window = L.Control.extend({ .on(this._wrapper, 'dblclick', stop) .on(this._wrapper, 'mousewheel', stop) .on(this._wrapper, 'MozMousePixelScroll', stop) + .on(this._wrapper, 'wheel', stop); // Attach event to close button if (this.options.closeButton) { @@ -75,6 +78,21 @@ L.Control.Window = L.Control.extend({ //map.on('resize',function(){self.mapResized()}); }, + _setupOutsideClickHandler: function() { + var self = this; + var mapContainer = L.DomUtil.get(this.options.element); + + // Small delay to prevent the handler from catching the opening click propegation + setTimeout(function() { + self._outsideClickHandler = function(e) { + if (!self._container.contains(e.target) && !self.isHidden()) { + self.hide(); + } + }; + + L.DomEvent.on(mapContainer, 'click', self._outsideClickHandler); + }, 100); + }, disableBtn: function(){ this._btnOK.disabled=true; this._btnOK.className='disabled'; @@ -94,6 +112,10 @@ L.Control.Window = L.Control.extend({ return this; }, remove: function () { + if (this._outsideClickHandler) { + var mapContainer = L.DomUtil.get(this.options.element); + L.DomEvent.off(mapContainer, 'click', this._outsideClickHandler); + } L.DomUtil.get(this.options.element).removeChild(this._wrapper); @@ -106,9 +128,8 @@ L.Control.Window = L.Control.extend({ .off(this._wrapper, 'touchstart', stop) .off(this._wrapper, 'dblclick', stop) .off(this._wrapper, 'mousewheel', stop) - .off(this._wrapper, 'MozMousePixelScroll', stop); - - // map.off('resize',self.mapResized); + .off(this._wrapper, 'MozMousePixelScroll', stop) + .off(this._wrapper, 'wheel', stop); if (this._closeButton && this._close) { var close = this._closeButton; @@ -163,6 +184,11 @@ L.Control.Window = L.Control.extend({ this.showOn([left+width/2-thisWidth/2-margin, top+top+height/2-thisHeight/2-margin+offset]) } + // Setup outside click handler if enabled + if (this.options.closeOnClickOutside) { + this._setupOutsideClickHandler(); + } + return this; }, showOn: function(point){ @@ -181,9 +207,17 @@ L.Control.Window = L.Control.extend({ L.DomUtil.removeClass(this._wrapper, 'visible'); this.fire('hide'); + + if (this._outsideClickHandler) { + var mapContainer = L.DomUtil.get(this.options.element); + L.DomEvent.off(mapContainer, 'click', this._outsideClickHandler); + } + return this; }, - + isHidden: function() { + return !L.DomUtil.hasClass(this._wrapper, 'visible'); + }, getContainer: function () { return this._containerContent; },