salix/client/core/src/popover/popover.js

109 lines
3.4 KiB
JavaScript
Raw Normal View History

import {module} from '../module';
2017-02-07 13:34:26 +00:00
import './style.css';
directive.$inject = ['vnPopover'];
2017-06-03 11:01:47 +00:00
export function directive(vnPopover) {
return {
restrict: 'A',
2017-05-16 10:37:48 +00:00
link: function($scope, $element, $attrs) {
$element.on('click', function(event) {
2017-06-03 11:01:47 +00:00
vnPopover.showComponent($attrs.vnDialog, $scope, $element);
event.preventDefault();
});
}
2017-05-16 10:37:48 +00:00
};
}
module.directive('vnPopover', directive);
2017-02-01 09:05:15 +00:00
export class Popover {
constructor($document, $compile) {
this.document = $document[0];
this.$compile = $compile;
}
show(childElement, parent) {
let popover = this.document.createElement('div');
popover.className = 'vn-popover';
popover.addEventListener('mousedown',
2017-06-03 11:01:47 +00:00
e => this.onPopoverMouseDown(e));
2017-02-01 09:05:15 +00:00
popover.appendChild(childElement);
this.popover = popover;
2017-02-01 09:05:15 +00:00
let style = popover.style;
2017-02-01 09:05:15 +00:00
let spacing = 0;
let screenMargin = 20;
let dblMargin = screenMargin * 2;
2017-02-01 09:05:15 +00:00
let width = popover.offsetWidth;
let height = popover.offsetHeight;
let innerWidth = window.innerWidth;
let innerHeight = window.innerHeight;
2017-05-16 10:37:48 +00:00
if (width + dblMargin > innerWidth) {
2017-02-01 09:05:15 +00:00
width = innerWidth - dblMargin;
2017-05-16 10:37:48 +00:00
style.width = width + 'px';
2017-02-01 09:05:15 +00:00
}
2017-05-16 10:37:48 +00:00
if (height + dblMargin > innerHeight) {
2017-02-01 09:05:15 +00:00
height = innerHeight - dblMargin;
2017-05-16 10:37:48 +00:00
style.height = height + 'px';
2017-02-01 09:05:15 +00:00
}
2017-05-16 10:37:48 +00:00
if (parent) {
2017-02-01 09:05:15 +00:00
let parentNode = parent;
let rect = parentNode.getBoundingClientRect();
let left = rect.left;
let top = rect.top + spacing + parentNode.offsetHeight;
2017-05-16 10:37:48 +00:00
if (left + width > innerWidth)
2017-02-01 09:05:15 +00:00
left -= (left + width) - innerWidth + margin;
2017-05-16 10:37:48 +00:00
if (top + height > innerHeight)
2017-02-01 09:05:15 +00:00
top -= height + parentNode.offsetHeight + spacing * 2;
2017-05-16 10:37:48 +00:00
if (left < 0)
2017-02-01 09:05:15 +00:00
left = screenMargin;
2017-05-16 10:37:48 +00:00
if (top < 0)
2017-02-01 09:05:15 +00:00
top = screenMargin;
2017-05-16 10:37:48 +00:00
style.top = (top) + 'px';
style.left = (left) + 'px';
style.minWidth = (rect.width) + 'px';
}
2017-02-01 09:05:15 +00:00
this.document.body.appendChild(popover);
2017-06-03 11:01:47 +00:00
this.docMouseDownHandler = e => this.onDocMouseDown(e);
2017-02-01 09:05:15 +00:00
this.document.addEventListener('mousedown', this.docMouseDownHandler);
2017-06-03 11:01:47 +00:00
this.docKeyDownHandler = e => this.onDocKeyDown(e);
this.document.addEventListener('keydown', this.docKeyDownHandler);
2017-02-01 09:05:15 +00:00
}
showComponent(childComponent, $scope, parent) {
let childElement = this.document.createElement(childComponent);
this.$compile(childElement)($scope);
this.show(childElement, parent);
}
hide() {
2017-05-16 10:37:48 +00:00
if (!this.popover) return;
2017-02-01 09:05:15 +00:00
this.document.removeEventListener('mousedown', this.docMouseDownHandler);
2017-06-03 11:01:47 +00:00
this.document.removeEventListener('keydown', this.docKeyDownHandler);
2017-02-01 09:05:15 +00:00
this.document.body.removeChild(this.popover);
this.popover = null;
this.lastEvent = null;
this.docMouseDownHandler = null;
2017-06-03 11:01:47 +00:00
this.docKeyDownHandler = null;
2017-02-01 09:05:15 +00:00
}
onDocMouseDown(event) {
if (event != this.lastEvent)
this.hide();
}
2017-06-03 11:01:47 +00:00
onDocKeyDown(event) {
if (event.keyCode === 27)
this.hide();
}
2017-02-01 09:05:15 +00:00
onPopoverMouseDown(event) {
this.lastEvent = event;
}
}
2017-02-01 09:05:15 +00:00
Popover.$inject = ['$document', '$compile'];
module.service('vnPopover', Popover);