summaryrefslogtreecommitdiff
path: root/assets/js/core
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2017-01-02 17:01:27 -0500
committerFrederic Guillot <fred@kanboard.net>2017-01-02 17:01:27 -0500
commit3833c12ccce59bcc49c4cfa892401973558f604d (patch)
treeb67b0e10cdc3d42e5626f728206138a444a40ed0 /assets/js/core
parentd49ce63e51f596ad3bf0d02b689aea673cf544f8 (diff)
Refactoring/rewrite of modal boxes handling
Diffstat (limited to 'assets/js/core')
-rw-r--r--assets/js/core/base.js4
-rw-r--r--assets/js/core/dom.js12
-rw-r--r--assets/js/core/http.js35
-rw-r--r--assets/js/core/modal.js172
-rw-r--r--assets/js/core/utils.js7
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)
+ };
+};