97 lines
3.3 KiB
JavaScript
97 lines
3.3 KiB
JavaScript
|
import {module} from '../module';
|
||
|
require('./style.css');
|
||
|
|
||
|
directive.$inject = ['vnPopover'];
|
||
|
export function directive(popover) {
|
||
|
return {
|
||
|
restrict: 'A',
|
||
|
link: function($scope, $element, $attrs, $ctrl) {
|
||
|
$element.on('click', function(event) {
|
||
|
popover.showComponent($attrs.vnDialog, $scope, $element);
|
||
|
event.preventDefault();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
module.directive('vnPopover', directive);
|
||
|
|
||
|
factory.$inject = ['$document', '$compile'];
|
||
|
function factory($document, $compile) {
|
||
|
return {
|
||
|
show: function(childElement, parent) {
|
||
|
let popover = $document[0].createElement('div');
|
||
|
popover.className = 'vn-popover';
|
||
|
popover.addEventListener('mousedown',
|
||
|
this.onPopoverMouseDown.bind(this));
|
||
|
popover.appendChild (childElement);
|
||
|
this.popover = popover;
|
||
|
|
||
|
let style = popover.style;
|
||
|
|
||
|
let spacing = 0;
|
||
|
let screenMargin = 20;
|
||
|
let dblMargin = screenMargin * 2;
|
||
|
|
||
|
let width = popover.offsetWidth;
|
||
|
let height = popover.offsetHeight;
|
||
|
let innerWidth = window.innerWidth;
|
||
|
let innerHeight = window.innerHeight;
|
||
|
|
||
|
if(width + dblMargin > innerWidth) {
|
||
|
width = innerWidth - dblMargin;
|
||
|
style.width = width +'px';
|
||
|
}
|
||
|
if(height + dblMargin > innerHeight) {
|
||
|
height = innerHeight - dblMargin;
|
||
|
style.height = height +'px';
|
||
|
}
|
||
|
|
||
|
if(parent) {
|
||
|
let parentNode = parent;
|
||
|
let rect = parentNode.getBoundingClientRect();
|
||
|
let left = rect.left;
|
||
|
let top = rect.top + spacing + parentNode.offsetHeight;
|
||
|
|
||
|
if(left + width > innerWidth)
|
||
|
left -= (left + width) - innerWidth + margin;
|
||
|
if(top + height > innerHeight)
|
||
|
top -= height + parentNode.offsetHeight + spacing * 2;
|
||
|
|
||
|
if(left < 0)
|
||
|
left = screenMargin;
|
||
|
if(top < 0)
|
||
|
top = screenMargin;
|
||
|
|
||
|
style.top = (top) +'px';
|
||
|
style.left = (left) +'px';
|
||
|
style.minWidth = (rect.width) +'px';
|
||
|
}
|
||
|
|
||
|
$document[0].body.appendChild (popover);
|
||
|
this.docMouseDownHandler = this.onDocMouseDown.bind(this);
|
||
|
$document.on('mousedown', this.docMouseDownHandler);
|
||
|
},
|
||
|
showComponent: function(childComponent, $scope, parent) {
|
||
|
let childElement = $document[0].createElement(childComponent);
|
||
|
$compile(childElement)($scope);
|
||
|
this.show(childElement, parent);
|
||
|
},
|
||
|
hide: function() {
|
||
|
if(!this.popover) return;
|
||
|
$document.off('mousedown', this.docMouseDownHandler);
|
||
|
$document[0].body.removeChild (this.popover);
|
||
|
this.popover = null;
|
||
|
this.lastEvent = null;
|
||
|
this.docMouseDownHandler = null;
|
||
|
},
|
||
|
onDocMouseDown: function(event) {
|
||
|
if (event != this.lastEvent)
|
||
|
this.hide();
|
||
|
},
|
||
|
onPopoverMouseDown: function(event) {
|
||
|
this.lastEvent = event;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
module.factory('vnPopover', factory);
|