diff options
author | Frederic Guillot <fred@kanboard.net> | 2017-01-02 17:01:27 -0500 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2017-01-02 17:01:27 -0500 |
commit | 3833c12ccce59bcc49c4cfa892401973558f604d (patch) | |
tree | b67b0e10cdc3d42e5626f728206138a444a40ed0 /assets/js/core | |
parent | d49ce63e51f596ad3bf0d02b689aea673cf544f8 (diff) |
Refactoring/rewrite of modal boxes handling
Diffstat (limited to 'assets/js/core')
-rw-r--r-- | assets/js/core/base.js | 4 | ||||
-rw-r--r-- | assets/js/core/dom.js | 12 | ||||
-rw-r--r-- | assets/js/core/http.js | 35 | ||||
-rw-r--r-- | assets/js/core/modal.js | 172 | ||||
-rw-r--r-- | assets/js/core/utils.js | 7 |
5 files changed, 223 insertions, 7 deletions
diff --git a/assets/js/core/base.js b/assets/js/core/base.js index a4fd00ac..033be0a7 100644 --- a/assets/js/core/base.js +++ b/assets/js/core/base.js @@ -22,9 +22,7 @@ KB.on = function (eventType, callback) { KB.trigger = function (eventType, eventData) { if (this.listeners.internals.hasOwnProperty(eventType)) { for (var i = 0; i < this.listeners.internals[eventType].length; i++) { - if (! this.listeners.internals[eventType][i](eventData)) { - break; - } + this.listeners.internals[eventType][i](eventData); } } }; diff --git a/assets/js/core/dom.js b/assets/js/core/dom.js index 84bdade2..250a1f78 100644 --- a/assets/js/core/dom.js +++ b/assets/js/core/dom.js @@ -88,6 +88,11 @@ KB.dom = function (tag) { return this; }; + this.replaceText = function (text) { + element.textContent = text; + return this; + }; + this.addClass = function (className) { element.classList.add(className); return this; @@ -122,6 +127,13 @@ KB.dom = function (tag) { return this; }; + this.empty = function () { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + return this; + }; + this.parent = function (selector) { for (; element && element !== document; element = element.parentNode) { if (element.matches(selector)) { diff --git a/assets/js/core/http.js b/assets/js/core/http.js index b965ad23..21200a0f 100644 --- a/assets/js/core/http.js +++ b/assets/js/core/http.js @@ -3,11 +3,21 @@ KB.http.request = function (method, url, headers, body) { var errorCallback = function() {}; function parseResponse(request) { - try { - return JSON.parse(request.responseText); - } catch (e) { - return request.responseText; + var redirect = request.getResponseHeader('X-Ajax-Redirect'); + + if (redirect === 'self') { + window.location.reload(); + } else if (redirect && redirect.indexOf('#') > -1) { + window.location = redirect.split('#')[0]; + } else if (redirect) { + window.location = redirect; + } else if (request.getResponseHeader('Content-Type') === 'application/json') { + try { + return JSON.parse(request.responseText); + } catch (e) {} } + + return request.responseText; } this.execute = function () { @@ -64,3 +74,20 @@ KB.http.postJson = function (url, body) { return (new KB.http.request('POST', url, headers, JSON.stringify(body))).execute(); }; + +KB.http.postForm = function (url, formElement) { + var formData = new FormData(formElement); + return (new KB.http.request('POST', url, {}, formData)).execute(); +}; + +KB.http.uploadFile = function (url, file, onProgress, onComplete, onError) { + var fd = new FormData(); + fd.append('files[]', file); + + var xhr = new XMLHttpRequest(); + xhr.upload.addEventListener('progress', onProgress); + xhr.upload.addEventListener('load', onComplete); + xhr.upload.addEventListener('error', onError); + xhr.open('POST', url, true); + xhr.send(fd); +}; diff --git a/assets/js/core/modal.js b/assets/js/core/modal.js new file mode 100644 index 00000000..b41dfbac --- /dev/null +++ b/assets/js/core/modal.js @@ -0,0 +1,172 @@ +(function () { + var isOpen = false; + + function onOverlayClick(e) { + if (e.target.matches('#modal-overlay')) { + e.stopPropagation(); + e.preventDefault(); + destroy(); + } + } + + function onCloseButtonClick() { + destroy(); + } + + function onFormSubmit() { + KB.trigger('modal.loading'); + submitForm(); + } + + function getForm() { + return document.querySelector('#modal-content form'); + } + + function submitForm() { + var form = getForm(); + + if (form) { + var url = form.getAttribute('action'); + + if (url) { + KB.http.postForm(url, form).success(function (response) { + KB.trigger('modal.stop'); + + if (response) { + replace(response); + } else { + destroy(); + } + }); + } + } + } + + function afterRendering() { + var formElement = KB.find('#modal-content form'); + if (formElement) { + formElement.on('submit', onFormSubmit, false); + } + + var autoFocusElement = document.querySelector('#modal-content input[autofocus]'); + if (autoFocusElement) { + autoFocusElement.focus(); + } + + KB.render(); + _KB.datePicker(); + _KB.autoComplete(); + _KB.tagAutoComplete(); + _KB.get('Task').onPopoverOpened(); + } + + function replace(html) { + var contentElement = KB.find('#modal-content'); + + if (contentElement) { + contentElement.replace(KB.dom('div') + .attr('id', 'modal-content') + .html(html) + .build() + ); + + afterRendering(); + } + } + + function create(html, width, overlayClickDestroy) { + var closeButtonElement = KB.dom('a') + .attr('href', '#') + .attr('id', 'modal-close-button') + .html('<i class="fa fa-times"></i>') + .click(onCloseButtonClick) + .build(); + + var headerElement = KB.dom('div') + .attr('id', 'modal-header') + .add(closeButtonElement) + .build(); + + var contentElement = KB.dom('div') + .attr('id', 'modal-content') + .html(html) + .build(); + + var boxElement = KB.dom('div') + .attr('id', 'modal-box') + .style('width', width) + .add(headerElement) + .add(contentElement) + .build(); + + var overlayElement = KB.dom('div') + .attr('id', 'modal-overlay') + .add(boxElement) + .build(); + + if (overlayClickDestroy) { + overlayElement.addEventListener('click', onOverlayClick, false); + } + + document.body.appendChild(overlayElement); + afterRendering(); + } + + function destroy() { + var overlayElement = KB.find('#modal-overlay'); + + if (overlayElement) { + overlayElement.remove(); + } + } + + function getWidth(size) { + var viewport = KB.utils.getViewportSize(); + + switch (size) { + case 'large': + return viewport.width < 1300 ? '95%' : '1300px'; + case 'medium': + return viewport.width < 1024 ? '70%' : '1024px'; + } + + return viewport.width < 800 ? '75%' : '800px'; + } + + KB.on('modal.close', function () { + destroy(); + }); + + KB.on('modal.submit', function () { + submitForm(); + }); + + KB.modal = { + open: function (url, size, overlayClickDestroy) { + _KB.get('Dropdown').close(); + destroy(); + + if (typeof overlayClickDestroy === 'undefined') { + overlayClickDestroy = true; + } + + KB.http.get(url).success(function (response) { + isOpen = true; + create(response, getWidth(size), overlayClickDestroy); + }); + }, + close: function () { + isOpen = false; + destroy(); + }, + isOpen: function () { + return isOpen; + }, + replace: function (url) { + KB.http.get(url).success(function (response) { + replace(response); + }); + }, + getForm: getForm + }; +}()); diff --git a/assets/js/core/utils.js b/assets/js/core/utils.js index 4d0f8847..a3683122 100644 --- a/assets/js/core/utils.js +++ b/assets/js/core/utils.js @@ -87,3 +87,10 @@ KB.utils.getKey = function (e) { return e.key; }; + +KB.utils.getViewportSize = function () { + return { + width: Math.max(document.documentElement.clientWidth, window.innerWidth || 0), + height: Math.max(document.documentElement.clientHeight, window.innerHeight || 0) + }; +}; |