salix/front/core/components/dialog/dialog.js

131 lines
3.5 KiB
JavaScript
Raw Normal View History

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