reimplement dynamic modals

This commit is contained in:
Felix Hamann 2019-02-24 22:27:45 +01:00
parent 77ecd5c59f
commit 99949cc4db
2 changed files with 76 additions and 31 deletions

View File

@ -13,6 +13,7 @@
color: var(--color-font); color: var(--color-font);
padding: 0 65px 0 20px; padding: 0 65px 0 20px;
overflow: auto; overflow: auto;
overscroll-behavior: contain;
transition: transition:
opacity .2s .1s ease-in-out, opacity .2s .1s ease-in-out,
transform .3s ease-in-out; transform .3s ease-in-out;

View File

@ -6,11 +6,28 @@
var JS_INITIALIZED_CLASS = 'js-modal-initialized'; var JS_INITIALIZED_CLASS = 'js-modal-initialized';
var MODAL_OPEN_CLASS = 'modal--open'; var MODAL_OPEN_CLASS = 'modal--open';
var MODAL_TRIGGER_CLASS = 'modal__trigger'; 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_CLOSABLE_FLAG = 'closeable';
var MODAL_DYNAMIC_FLAG = 'dynamic';
var OVERLAY_CLASS = 'modal__overlay'; var OVERLAY_CLASS = 'modal__overlay';
var OVERLAY_OPEN_CLASS = 'modal__overlay--open'; var OVERLAY_OPEN_CLASS = 'modal__overlay--open';
var CLOSER_CLASS = 'modal__closer'; var CLOSER_CLASS = 'modal__closer';
var AJAX_SUBMIT_FLAG = 'ajaxSubmit' var AJAX_SUBMIT_FLAG = 'ajaxSubmit';
// helper function for convenient http requests with appropriate headers
function httpRequest(url, method, body) {
var requestOptions = {
method: method,
credentials: 'same-origin',
headers: {
'Is-Modal': 'True',
},
body: body,
};
return fetch(url, requestOptions);
}
window.utils.modal = function(modalElement, options) { window.utils.modal = function(modalElement, options) {
@ -22,6 +39,18 @@
var closerElement = document.createElement('div'); var closerElement = document.createElement('div');
var triggerElement = document.querySelector('#' + modalElement.dataset.trigger); 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', open, false);
modalElement.classList.add(JS_INITIALIZED_CLASS);
}
function open(event) { function open(event) {
event.preventDefault(); event.preventDefault();
@ -29,6 +58,11 @@
overlayElement.classList.add(OVERLAY_CLASS); overlayElement.classList.add(OVERLAY_CLASS);
document.body.insertBefore(overlayElement, modalElement); document.body.insertBefore(overlayElement, modalElement);
overlayElement.classList.add(OVERLAY_OPEN_CLASS); overlayElement.classList.add(OVERLAY_OPEN_CLASS);
var modalUrl = triggerElement.getAttribute('href');
if (modalUrl && MODAL_DYNAMIC_FLAG in modalElement.dataset) {
fillModal(modalUrl);
}
} }
function close(event) { function close(event) {
@ -37,50 +71,60 @@
modalElement.classList.remove(MODAL_OPEN_CLASS); modalElement.classList.remove(MODAL_OPEN_CLASS);
}; };
function setup() { function setupForm() {
document.body.insertBefore(modalElement, null);
var form = modalElement.querySelector('form'); var form = modalElement.querySelector('form');
if (form && AJAX_SUBMIT_FLAG in form.dataset) { if (form && AJAX_SUBMIT_FLAG in form.dataset) {
setupForm(form); form.addEventListener('submit', function(event) {
} event.preventDefault();
var url = form.getAttribute('action');
var body = new FormData(form);
return httpRequest(url, form.method, body).then(function(response) {
return response.json();
}).then(function(response) {
// TODO: process json response once backend returns json
}).catch(function(error) {
console.error('could not fetch or process response from ' + url, { error });
});
});
}
}
function setupCloser() {
if (MODAL_CLOSABLE_FLAG in modalElement.dataset) { if (MODAL_CLOSABLE_FLAG in modalElement.dataset) {
modalElement.insertBefore(closerElement, null); modalElement.insertBefore(closerElement, null);
closerElement.classList.add(CLOSER_CLASS); closerElement.classList.add(CLOSER_CLASS);
closerElement.addEventListener('click', close, false); closerElement.addEventListener('click', close, false);
overlayElement.addEventListener('click', close, false); overlayElement.addEventListener('click', close, false);
} }
triggerElement.classList.add(MODAL_TRIGGER_CLASS);
triggerElement.addEventListener('click', open, false);
modalElement.classList.add(JS_INITIALIZED_CLASS);
} }
function setupForm(form) { function fillModal(url) {
form.addEventListener('submit', function(event) { httpRequest(url, 'GET').then(function(response) {
event.preventDefault(); response.text().then(processResponse);
var url = form.getAttribute('action');
var httpRequestOptions = {
method: form.method,
credentials: 'same-origin',
headers: {
'Is-Modal': 'True'
},
body: new FormData(form),
};
return fetch(url, httpRequestOptions).then(function(response) {
return response.json();
}).then(function(response) {
// TODO: process json response once backend returns json
}).catch(function(error) {
console.error('could not fetch or process response from ' + url, { error });
});
}); });
} }
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();
}
modalElement.insertBefore(modalContent, null);
setupForm();
}
setup(); setup();
}; };
})(); })();