2018-02-10 15:18:01 +00:00
|
|
|
import ngModule from '../../module';
|
|
|
|
import Component from '../../lib/component';
|
2017-02-06 17:01:04 +00:00
|
|
|
import './style.scss';
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
/**
|
|
|
|
* Dialog component.
|
2018-02-20 09:00:19 +00:00
|
|
|
*
|
|
|
|
* @property {HTMLElement} body The dialog HTML body
|
|
|
|
* @property {HTMLElement} buttons The dialog HTML buttons
|
2017-02-06 17:01:04 +00:00
|
|
|
*/
|
|
|
|
export default class Dialog extends Component {
|
2018-05-30 06:45:02 +00:00
|
|
|
constructor($element, $scope, $transclude) {
|
|
|
|
super($element, $scope);
|
2018-02-20 09:00:19 +00:00
|
|
|
this.shown = false;
|
|
|
|
this.$element.addClass('vn-dialog');
|
|
|
|
this.element.addEventListener('mousedown',
|
|
|
|
e => this.onBackgroundMouseDown(e));
|
|
|
|
|
|
|
|
if ($transclude) {
|
2018-05-30 06:45:02 +00:00
|
|
|
$transclude($scope.$parent, tClone => {
|
2018-02-20 09:00:19 +00:00
|
|
|
this.body = tClone[0];
|
|
|
|
}, null, 'body');
|
2018-05-30 06:45:02 +00:00
|
|
|
$transclude($scope.$parent, tClone => {
|
2018-02-20 09:00:19 +00:00
|
|
|
this.buttons = tClone[0];
|
|
|
|
}, null, 'buttons');
|
|
|
|
}
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2018-02-20 09:00:19 +00:00
|
|
|
set body(value) {
|
|
|
|
this.element.querySelector('.body').appendChild(value);
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2018-02-20 09:00:19 +00:00
|
|
|
set buttons(value) {
|
|
|
|
this.element.querySelector('.buttons').appendChild(value);
|
2017-01-31 13:13:06 +00:00
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
/**
|
|
|
|
* Displays the dialog to the user.
|
|
|
|
*/
|
|
|
|
show() {
|
2018-02-20 09:00:19 +00:00
|
|
|
if (this.shown) return;
|
|
|
|
this.shown = true;
|
2018-03-07 14:05:09 +00:00
|
|
|
this.keyDownHandler = e => this.onkeyDown(e);
|
|
|
|
this.document.addEventListener('keydown', this.keyDownHandler);
|
2018-02-20 09:00:19 +00:00
|
|
|
this.element.style.display = 'flex';
|
2018-03-07 14:05:09 +00:00
|
|
|
this.transitionTimeout = setTimeout(() => this.$element.addClass('shown'), 30);
|
2017-01-31 13:13:06 +00:00
|
|
|
|
2017-05-25 10:52:38 +00:00
|
|
|
if (this.onOpen)
|
2017-02-06 17:01:04 +00:00
|
|
|
this.onOpen();
|
2018-03-07 14:05:09 +00:00
|
|
|
|
|
|
|
let firstFocusable = this.element.querySelector('input, textarea');
|
|
|
|
if (firstFocusable) firstFocusable.focus();
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
/**
|
|
|
|
* Hides the dialog calling the response handler.
|
|
|
|
*/
|
|
|
|
hide() {
|
|
|
|
this.fireResponse();
|
|
|
|
this.realHide();
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
/**
|
|
|
|
* Calls the response handler.
|
2017-06-03 11:01:47 +00:00
|
|
|
*
|
|
|
|
* @param {String} response The response code
|
|
|
|
* @return {Boolean} %true if response was canceled, %false otherwise
|
2017-02-06 17:01:04 +00:00
|
|
|
*/
|
|
|
|
fireResponse(response) {
|
|
|
|
let cancel = false;
|
2017-05-25 10:52:38 +00:00
|
|
|
if (this.onResponse)
|
2017-02-06 17:01:04 +00:00
|
|
|
cancel = this.onResponse({response: response});
|
|
|
|
return cancel;
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
realHide() {
|
2018-02-20 09:00:19 +00:00
|
|
|
if (!this.shown) return;
|
2017-02-06 17:01:04 +00:00
|
|
|
this.element.style.display = 'none';
|
2018-03-07 14:05:09 +00:00
|
|
|
this.document.removeEventListener('keydown', this.keyDownHandler);
|
2017-02-06 17:01:04 +00:00
|
|
|
this.lastEvent = null;
|
2018-02-20 09:00:19 +00:00
|
|
|
this.shown = false;
|
2018-08-30 06:16:50 +00:00
|
|
|
this.transitionTimeout = setTimeout(() => this.$element.removeClass('shown'), 30);
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
onButtonClick(event) {
|
2018-02-20 09:00:19 +00:00
|
|
|
let buttons = this.element.querySelector('.buttons');
|
|
|
|
let tplButtons = buttons.querySelector('tpl-buttons');
|
2017-02-06 17:01:04 +00:00
|
|
|
let node = event.target;
|
2018-02-20 09:00:19 +00:00
|
|
|
while (node.parentNode != tplButtons) {
|
|
|
|
if (node == buttons) return;
|
2017-02-06 17:01:04 +00:00
|
|
|
node = node.parentNode;
|
2017-01-31 13:13:06 +00:00
|
|
|
}
|
2017-02-06 17:01:04 +00:00
|
|
|
|
|
|
|
let response = node.getAttribute('response');
|
|
|
|
let cancel = this.fireResponse(response);
|
2017-05-25 10:52:38 +00:00
|
|
|
if (cancel !== false) this.realHide();
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
onDialogMouseDown(event) {
|
|
|
|
this.lastEvent = event;
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
onBackgroundMouseDown(event) {
|
|
|
|
if (event != this.lastEvent)
|
|
|
|
this.hide();
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2018-03-07 14:05:09 +00:00
|
|
|
onkeyDown(event) {
|
2017-05-25 10:52:38 +00:00
|
|
|
if (event.keyCode == 27) // Esc
|
2017-02-06 17:01:04 +00:00
|
|
|
this.hide();
|
|
|
|
}
|
2018-08-30 06:16:50 +00:00
|
|
|
|
2018-02-20 09:00:19 +00:00
|
|
|
$onDestroy() {
|
|
|
|
clearTimeout(this.transitionTimeout);
|
|
|
|
}
|
2017-01-31 13:13:06 +00:00
|
|
|
}
|
2018-05-30 06:45:02 +00:00
|
|
|
Dialog.$inject = ['$element', '$scope', '$transclude'];
|
2017-02-06 17:01:04 +00:00
|
|
|
|
2018-02-10 15:18:01 +00:00
|
|
|
ngModule.component('vnDialog', {
|
2017-05-31 07:46:05 +00:00
|
|
|
template: require('./dialog.html'),
|
2017-02-06 17:01:04 +00:00
|
|
|
transclude: {
|
2018-02-20 09:00:19 +00:00
|
|
|
body: 'tplBody',
|
2018-02-22 07:18:57 +00:00
|
|
|
buttons: '?tplButtons'
|
2017-02-06 17:01:04 +00:00
|
|
|
},
|
|
|
|
bindings: {
|
2017-10-05 12:28:57 +00:00
|
|
|
onOpen: '&?',
|
|
|
|
onResponse: '&?'
|
2017-02-06 17:01:04 +00:00
|
|
|
},
|
|
|
|
controller: Dialog
|
|
|
|
});
|