154 lines
4.3 KiB
JavaScript
154 lines
4.3 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
window.utils = window.utils || {};
|
|
|
|
var JS_INITIALIZED_CLASS = 'js-modal-initialized';
|
|
var MODAL_OPEN_CLASS = 'modal--open';
|
|
var MODAL_TRIGGER_CLASS = 'modal__trigger';
|
|
var MODAL_CONTENT_CLASS = 'modal__content';
|
|
var MAIN_CONTENT_CLASS = 'main__content-body'
|
|
var MODAL_CLOSABLE_FLAG = 'closeable';
|
|
var MODAL_DYNAMIC_FLAG = 'dynamic';
|
|
var MODAL_HEADERS = {
|
|
'Is-Modal': 'True',
|
|
};
|
|
var OVERLAY_CLASS = 'modal__overlay';
|
|
var OVERLAY_OPEN_CLASS = 'modal__overlay--open';
|
|
var CLOSER_CLASS = 'modal__closer';
|
|
|
|
window.utils.modal = function(modalElement, options) {
|
|
|
|
if (!modalElement || modalElement.classList.contains(JS_INITIALIZED_CLASS)) {
|
|
return;
|
|
}
|
|
|
|
var utilInstances = [];
|
|
|
|
var overlayElement = document.createElement('div');
|
|
var closerElement = document.createElement('div');
|
|
var triggerElement = document.querySelector('#' + modalElement.dataset.trigger);
|
|
|
|
function setup() {
|
|
document.body.insertBefore(modalElement, null);
|
|
|
|
setupForm();
|
|
setupCloser();
|
|
|
|
triggerElement.classList.add(MODAL_TRIGGER_CLASS);
|
|
triggerElement.addEventListener('click', openHandler, false);
|
|
|
|
modalElement.classList.add(JS_INITIALIZED_CLASS);
|
|
}
|
|
|
|
function openHandler(event) {
|
|
event.preventDefault();
|
|
open();
|
|
}
|
|
|
|
function open() {
|
|
modalElement.classList.add(MODAL_OPEN_CLASS);
|
|
overlayElement.classList.add(OVERLAY_CLASS);
|
|
document.body.insertBefore(overlayElement, modalElement);
|
|
overlayElement.classList.add(OVERLAY_OPEN_CLASS);
|
|
|
|
var modalUrl = triggerElement.getAttribute('href');
|
|
if (modalUrl && MODAL_DYNAMIC_FLAG in modalElement.dataset) {
|
|
fillModal(modalUrl);
|
|
}
|
|
|
|
document.addEventListener('keyup', keyupHandler);
|
|
}
|
|
|
|
function closeHandler(event) {
|
|
event.preventDefault();
|
|
close();
|
|
}
|
|
|
|
function close() {
|
|
overlayElement.classList.remove(OVERLAY_OPEN_CLASS);
|
|
modalElement.classList.remove(MODAL_OPEN_CLASS);
|
|
|
|
document.removeEventListener('keyup', keyupHandler);
|
|
};
|
|
|
|
function setupForm() {
|
|
var form = modalElement.querySelector('form');
|
|
if (form) {
|
|
utilInstances.push(window.utils.setup('form', form, { headers: MODAL_HEADERS }));
|
|
}
|
|
}
|
|
|
|
function setupCloser() {
|
|
if (MODAL_CLOSABLE_FLAG in modalElement.dataset) {
|
|
modalElement.insertBefore(closerElement, null);
|
|
closerElement.classList.add(CLOSER_CLASS);
|
|
closerElement.addEventListener('click', closeHandler, false);
|
|
overlayElement.addEventListener('click', closeHandler, false);
|
|
}
|
|
}
|
|
|
|
function fillModal(url) {
|
|
if (!window.utils.httpClient) {
|
|
throw new Error('httpClient not found! Can\' fetch modal content from ' + url);
|
|
}
|
|
|
|
window.utils.httpClient.get(url, MODAL_HEADERS)
|
|
.then(function(response) {
|
|
response.text().then(processResponse);
|
|
});
|
|
}
|
|
|
|
function processResponse(reponseBody) {
|
|
var modalContent = document.createElement('div');
|
|
modalContent.classList.add(MODAL_CONTENT_CLASS);
|
|
modalContent.innerHTML = reponseBody;
|
|
|
|
var contentBody = modalContent.querySelector('.' + MAIN_CONTENT_CLASS);
|
|
|
|
if (contentBody) {
|
|
modalContent.innerHTML = contentBody.innerHTML;
|
|
}
|
|
|
|
var previousModalContent = modalElement.querySelector('.' + MODAL_CONTENT_CLASS);
|
|
if (previousModalContent) {
|
|
previousModalContent.remove();
|
|
}
|
|
|
|
modalContent = withPrefixedInputIDs(modalContent);
|
|
modalElement.insertBefore(modalContent, null);
|
|
setupForm();
|
|
}
|
|
|
|
function withPrefixedInputIDs(modalContent) {
|
|
var idAttrs = ['id', 'for', 'data-conditional-id'];
|
|
idAttrs.forEach(function(attr) {
|
|
modalContent.querySelectorAll('[' + attr + ']').forEach(function(input) {
|
|
var value = modalElement.id + '__' + input.getAttribute(attr);
|
|
input.setAttribute(attr, value);
|
|
});
|
|
});
|
|
return modalContent;
|
|
}
|
|
|
|
function keyupHandler(event) {
|
|
if (event.key === 'Escape') {
|
|
close();
|
|
}
|
|
}
|
|
|
|
setup();
|
|
|
|
function destroyUtils() {
|
|
utilInstances.forEach(function(utilInstance) {
|
|
utilInstance.destroy();
|
|
});
|
|
}
|
|
|
|
return {
|
|
scope: modalElement,
|
|
destroy: destroyUtils,
|
|
};
|
|
};
|
|
})();
|