Commit 6da9e5f1 authored by Rafael Ostertag's avatar Rafael Ostertag
Browse files

Refactored JS to use EventEmitter.

parent 8e8d4fb7
......@@ -4,6 +4,7 @@
/* global $ */
/* global console */
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
......@@ -24,8 +25,6 @@ var QfqNS = QfqNS || {};
this._tabActiveSelector = '#' + this.tabId + ' .active a[data-toggle="tab"]';
this.tabs = {};
this.currentTab = this.getActiveTabFromDOM();
this.userTabShowHandlers = new n.Helper.FunctionList();
// Fill this.tabs
this.fillTabInformation();
......@@ -101,9 +100,9 @@ var QfqNS = QfqNS || {};
n.Log.debug('Enter: BSTabs.tabShowHandler()');
this.currentTab = event.target.hash.slice(1);
var that = this;
n.Log.debug("BSTabs.tabShowHandler(): invoke user handler(s)");
this.userTabShowHandlers.call(that);
n.EventEmitter.emitEvent('bootstrap.tab.shown', n.EventEmitter.makePayload(this, null));
// REMOVE: this.userTabShowHandlers.call(that);
n.Log.debug('Exit: BSTabs.tabShowHandler()');
};
......@@ -161,15 +160,6 @@ var QfqNS = QfqNS || {};
return this.currentTab;
};
/**
* Add tab show handler.
*
* @param {function} handler handler function. `this` will be passed as first and only argument to the handler.
*/
n.BSTabs.prototype.addTabShowHandler = function (handler) {
this.userTabShowHandlers.addFunction(handler);
};
n.BSTabs.prototype.getTabName = function (tabId) {
if (!this.tabs[tabId]) {
console.error("Unable to find tab with id: " + tabId);
......
......@@ -4,6 +4,8 @@
/* global $ */
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
(function (n) {
......@@ -14,47 +16,9 @@ var QfqNS = QfqNS || {};
this.targetUrl = targetUrl;
this.sip = sip;
// TODO: Seriously, I'd like to have an event system.
this.fileUploadStartCallbacks = new n.Helper.FunctionList();
this.fileUploadEndCallbacks = new n.Helper.FunctionList();
this.fileUploadSuccessCallbacks = new n.Helper.FunctionList();
this.fileUploadErrorCallbacks = new n.Helper.FunctionList();
this.setupOnChangeHandler();
};
/**
* @public
* @param handler
*/
n.FileUpload.prototype.addFileUploadStartHandler = function (handler) {
this.fileUploadStartCallbacks.addFunction(handler);
};
/**
* @public
* @param handler
*/
n.FileUpload.prototype.addFileUploadEndHandler = function (handler) {
this.fileUploadEndCallbacks.addFunction(handler);
};
/**
* @public
* @param handler
*/
n.FileUpload.prototype.addFileUploadSuccessHandler = function (handler) {
this.fileUploadSuccessCallbacks.addFunction(handler);
};
/**
* @public
* @param handler
*/
n.FileUpload.prototype.addFileUploadErrorHandler = function (handler) {
this.fileUploadErrorCallbacks.addFunction(handler);
};
/**
*
* @private
......@@ -68,7 +32,7 @@ var QfqNS = QfqNS || {};
* @param event
*/
n.FileUpload.prototype.performFileUpload = function (event) {
this.fileUploadStartCallbacks.call(event.target);
n.EventEmitter.emitEvent('fileupload.started', n.EventEmitter.makePayload(event.target, null));
var data = this.prepareData(event.target);
......@@ -109,8 +73,12 @@ var QfqNS = QfqNS || {};
*/
n.FileUpload.prototype.ajaxSuccessHandler = function (uploadTriggeredBy, data, textStatus, jqXHR) {
this.fileUploadSuccessCallbacks.call(uploadTriggeredBy, data, textStatus);
this.fileUploadEndCallbacks.call(uploadTriggeredBy);
var eventData = n.EventEmitter.makePayload(uploadTriggeredBy, data, {
textStatus: textStatus,
jqXHR: jqXHR
});
n.EventEmitter.emitEvent('fileupload.upload.successful', eventData);
n.EventEmitter.emitEvent('fileupload.ended', eventData);
};
/**
......@@ -120,8 +88,13 @@ var QfqNS = QfqNS || {};
* @param errorThrown
*/
n.FileUpload.prototype.ajaxErrorHandler = function (uploadTriggeredBy, jqXHR, textStatus, errorThrown) {
this.fileUploadErrorCallbacks.call(uploadTriggeredBy, textStatus, errorThrown);
this.fileUploadEndCallbacks.call(uploadTriggeredBy);
var eventData = n.EventEmitter.makePayload(uploadTriggeredBy, null, {
textStatus: textStatus,
errorThrown: errorThrown,
jqXHR: jqXHR
});
n.EventEmitter.emitEvent('fileupload.upload.failed', eventData);
n.EventEmitter.emitEvent('fileupload.ended', eventData);
};
......
......@@ -3,6 +3,7 @@
*/
/* global $ */
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
......@@ -17,11 +18,6 @@ var QfqNS = QfqNS || {};
}
this.formChanged = false;
this.userFormChangeHandlers = new QfqNS.Helper.FunctionList();
this.userResetHandlers = new QfqNS.Helper.FunctionList();
this.userSubmitSuccessHandlers = new QfqNS.Helper.FunctionList();
this.userSubmitFailureHandlers = new QfqNS.Helper.FunctionList();
this.$form = $(document.forms[this.formId]);
this.$form.on("change", this.changeHandler.bind(this));
......@@ -38,23 +34,8 @@ var QfqNS = QfqNS || {};
*/
n.Form.prototype.changeHandler = function (event) {
this.formChanged = true;
this.userFormChangeHandlers.call(this);
};
n.Form.prototype.addChangeHandler = function (callback) {
this.userFormChangeHandlers.addFunction(callback);
};
n.Form.prototype.addResetHandler = function (callback) {
this.userResetHandlers.addFunction(callback);
};
n.Form.prototype.addSubmitSuccessHandler = function (callback) {
this.userSubmitSuccessHandlers.addFunction(callback);
};
n.Form.prototype.addSubmitFailureHandler = function (callback) {
this.userSubmitFailureHandlers.addFunction(callback);
n.EventEmitter.emitEvent('form.changed', n.EventEmitter.makePayload(this, null));
// REMOVE: this.userFormChangeHandlers.call(this);
};
n.Form.prototype.getFormChanged = function () {
......@@ -63,7 +44,8 @@ var QfqNS = QfqNS || {};
n.Form.prototype.resetFormChanged = function () {
this.formChanged = false;
this.userResetHandlers.call(this);
n.EventEmitter.emitEvent('form.reset', n.EventEmitter.makePayload(this, null));
// REMOVE: this.userResetHandlers.call(this);
};
n.Form.prototype.submitTo = function (to) {
......@@ -85,7 +67,11 @@ var QfqNS = QfqNS || {};
* @private
*/
n.Form.prototype.ajaxSuccessHandler = function (data, textStatus, jqXHR) {
this.userSubmitSuccessHandlers.call(this, data, textStatus);
n.EventEmitter.emitEvent('form.submit.successful',
n.EventEmitter.makePayload(this, data, {
textStatus: textStatus,
jqXHR: jqXHR
}));
};
/**
......@@ -94,7 +80,12 @@ var QfqNS = QfqNS || {};
* @private
*/
n.Form.prototype.submitFailureHandler = function (jqXHR, textStatus, errorThrown) {
this.userSubmitFailureHandlers.call(this, textStatus, jqXHR, errorThrown);
n.EventEmitter.emitEvent('form.submit.failed', n.EventEmitter.makePayload(this, null, {
textStatus: textStatus,
errorThrown: errorThrown,
jqXHR: jqXHR
}));
// REMOVE: this.userSubmitFailureHandlers.call(this, textStatus, jqXHR, errorThrown);
};
})(QfqNS);
......@@ -2,6 +2,8 @@
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
(function (n) {
......@@ -12,7 +14,6 @@ var QfqNS = QfqNS || {};
this.pageState = location.hash.slice(1);
this.data = null;
this.inPoppingHandler = false;
this.userPopStateHandlers = new n.Helper.FunctionList();
window.addEventListener("popstate", this.popStateHandler.bind(this));
};
......@@ -32,7 +33,7 @@ var QfqNS = QfqNS || {};
n.Log.debug("PageState.popStateHandler(): invoke user pop state handler(s)");
this.userPopStateHandlers.call(this);
n.EventEmitter.emitEvent('pagestate.state.popped', n.EventEmitter.makePayload(this, null));
this.inPoppingHandler = false;
n.Log.debug("Exit: PageState.popStateHandler()");
......@@ -70,9 +71,4 @@ var QfqNS = QfqNS || {};
this.data = data;
};
n.PageState.prototype.addStateActivationHandler = function (handler) {
this.userPopStateHandlers.addFunction(handler);
};
})(QfqNS);
\ No newline at end of file
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global EventEmitter */
/* global $ */
var QfqNS = QfqNS || {};
(function (n) {
'use strict';
n.EventEmitter = new EventEmitter();
n.EventEmitter.makePayload = function (target, data, additionalArgs) {
return [$.extend({},
typeof additionalArgs === "object" ? additionalArgs : null,
{
target: target,
data: data
}
)];
};
})(QfqNS);
\ No newline at end of file
......@@ -3,6 +3,7 @@
*/
/* global $ */
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
......@@ -20,17 +21,15 @@ var QfqNS = QfqNS || {};
// This is required when displaying validation messages, in to activate the tab, which has validation issues
this.bsTabs = null;
this.lastButtonPress = null;
this.destroyFormUserCallbacks = new n.Helper.FunctionList();
this.getSaveButton().addClass("disabled").attr("disabled", "disabled");
this.form.addChangeHandler(this.changeHandler.bind(this));
this.form.addResetHandler(this.resetHandler.bind(this));
this.form.addSubmitSuccessHandler(this.submitSuccessDispatcher.bind(this));
this.form.addSubmitFailureHandler(
function (form, textStatus, jqXHR, errorThrown) {
n.Helper.showAjaxError(jqXHR, textStatus, errorThrown);
});
n.EventEmitter.addListener('form.changed', this.changeHandler.bind(this));
n.EventEmitter.addListener('form.reset', this.resetHandler.bind(this));
n.EventEmitter.addListener('form.submit.successful', this.submitSuccessDispatcher.bind(this));
n.EventEmitter.addListener('form.submit.failed', function (obj) {
n.Helper.showAjaxError(null, obj.textStatus, obj.errorThrown);
});
this.getSaveButton().click(this.handleSaveClick.bind(this));
this.getCloseButton().click(this.handleCloseClick.bind(this));
......@@ -40,13 +39,14 @@ var QfqNS = QfqNS || {};
this.setupFormUpdateHandler();
this.fileUploader = new n.FileUpload('#' + this.formId, this.fileUploadTo, this.getSip());
this.fileUploader.addFileUploadStartHandler(this.startUploadHandler);
this.fileUploader.addFileUploadSuccessHandler(this.fileUploadSuccessHandler);
this.fileUploader.addFileUploadErrorHandler(
function (uploadTriggeredBy, textStatus, errorThrown) {
n.Helper.showAjaxError(null, textStatus, errorThrown);
n.EventEmitter.addListener('fileupload.started', this.startUploadHandler);
n.EventEmitter.addListener('fileupload.upload.success', this.fileUploadSuccessHandler);
n.EventEmitter.addListener('fileupload.upload.failed',
function (obj) {
n.Helper.showAjaxError(null, obj.textStatus, obj.errorThrown);
});
this.fileUploader.addFileUploadEndHandler(this.endUploadHandler);
n.EventEmitter.addListener('fileupload.ended', this.endUploadHandler);
};
/**
......@@ -60,13 +60,13 @@ var QfqNS = QfqNS || {};
/**
* @private
*/
n.QfqForm.prototype.fileUploadSuccessHandler = function (uploadTriggeredBy, data, textStatus) {
if (!data.status) {
n.QfqForm.prototype.fileUploadSuccessHandler = function (obj) {
if (!obj.data.status) {
throw Error("Response on file upload missing status");
}
if (data.status === "error") {
var alert = new n.Alert(data.message, "error");
if (obj.data.status === "error") {
var alert = new n.Alert(obj.data.message, "error");
alert.show();
}
};
......@@ -137,7 +137,7 @@ var QfqNS = QfqNS || {};
n.QfqForm.prototype.destroyFormAndSetText = function (text) {
this.form = null;
$('#' + this.formId).replaceWith($("<p>").append(text));
this.destroyFormUserCallbacks.call();
n.EventEmitter.emitEvent('qfqform.destroyed', n.EventEmitter.makePayload(this, null));
};
/**
......@@ -271,7 +271,7 @@ var QfqNS = QfqNS || {};
*
* @private
*/
n.QfqForm.prototype.changeHandler = function (form) {
n.QfqForm.prototype.changeHandler = function (obj) {
this.getSaveButton().removeClass("disabled");
this.getSaveButton().addClass("alert-warning");
this.getSaveButton().removeAttr("disabled");
......@@ -283,7 +283,7 @@ var QfqNS = QfqNS || {};
*
* @private
*/
n.QfqForm.prototype.resetHandler = function (form) {
n.QfqForm.prototype.resetHandler = function (obj) {
this.getSaveButton().removeClass("alert-warning");
this.getSaveButton().addClass("disabled");
this.getSaveButton().attr("disabled", "disabled");
......@@ -333,20 +333,20 @@ var QfqNS = QfqNS || {};
/**
* @private
*/
n.QfqForm.prototype.submitSuccessDispatcher = function (form, data, textStatus) {
if (!data.status) {
n.QfqForm.prototype.submitSuccessDispatcher = function (obj) {
if (!obj.data.status) {
throw new Error("No 'status' property in 'data'");
}
switch (data.status) {
switch (obj.data.status) {
case "error":
this.handleLogicSubmitError(form, data);
this.handleLogicSubmitError(obj.target, obj.data);
break;
case "success":
this.handleSubmitSuccess(form, data);
this.handleSubmitSuccess(obj.target, obj.data);
break;
default:
throw new Error("Status '" + data.status + "' unknown.");
throw new Error("Status '" + obj.data.status + "' unknown.");
}
};
......@@ -525,8 +525,8 @@ var QfqNS = QfqNS || {};
* @private
* @param triggeredBy
*/
n.QfqForm.prototype.startUploadHandler = function (triggeredBy) {
$(triggeredBy).after(
n.QfqForm.prototype.startUploadHandler = function (obj) {
$(obj.target).after(
$('<i>').addClass('spinner')
);
};
......@@ -535,15 +535,11 @@ var QfqNS = QfqNS || {};
* @private
* @param triggeredBy
*/
n.QfqForm.prototype.endUploadHandler = function (triggeredBy) {
var $siblings = $(triggeredBy).siblings();
n.QfqForm.prototype.endUploadHandler = function (obj) {
var $siblings = $(obj.target).siblings();
$siblings.filter("i").remove();
};
n.QfqForm.prototype.ajaxFileUploadErrorHandler = function (triggeredBy, jqHXR, textStatus, errorThrown) {
n.Helper.showAjaxError(jqHXR, textStatus, errorThrown);
};
/**
* Retrieve SIP as stored in hidden input field.
*
......
......@@ -4,6 +4,7 @@
/* global $ */
/* global console */
/* @depend QfqEvents.js */
var QfqNS = QfqNS || {};
......@@ -34,9 +35,8 @@ var QfqNS = QfqNS || {};
this.settings.pageState.setPageState(this.bsTabs.getCurrentTab(), n.PageTitle.get());
}
this.bsTabs.addTabShowHandler(this.tabShowHandler.bind(this));
this.settings.pageState.addStateActivationHandler(this.popStateHandler.bind(this));
n.EventEmitter.addListener('bootstrap.tab.shown', this.tabShowHandler.bind(this));
n.EventEmitter.addListener('pagestate.state.popped', this.popStateHandler.bind(this));
} catch (e) {
n.Log.message(e.message);
this.bsTabs = null;
......@@ -50,7 +50,7 @@ var QfqNS = QfqNS || {};
this.settings.refreshUrl,
this.settings.fileUploadTo);
this.qfqForm.setBsTabs(this.bsTabs);
this.qfqForm.destroyFormUserCallbacks.addFunction(this.destroyFormHandler.bind(this));
n.EventEmitter.addListener('qfqform.destroyed', this.destroyFormHandler.bind(this));
} catch (e) {
n.Log.error(e.message);
this.qfqForm = null;
......@@ -60,12 +60,12 @@ var QfqNS = QfqNS || {};
/**
* @private
*/
n.QfqPage.prototype.destroyFormHandler = function () {
n.QfqPage.prototype.destroyFormHandler = function (obj) {
this.settings.qfqForm = null;
$('#' + this.settings.tabsId).remove();
};
n.QfqPage.prototype.tabShowHandler = function (bsTabs) {
n.QfqPage.prototype.tabShowHandler = function (obj) {
// tabShowHandler will be called every time the tab will be shown, regardless of whether or not this happens
// because of BSTabs.activateTab() or user interaction.
//
......@@ -76,16 +76,15 @@ var QfqNS = QfqNS || {};
" restoration.");
return;
}
var currentTabId = bsTabs.getCurrentTab();
var currentTabId = obj.target.getCurrentTab();
n.Log.debug('Saving state: ' + currentTabId);
n.PageTitle.setSubTitle(bsTabs.getTabName(currentTabId));
n.PageTitle.setSubTitle(obj.target.getTabName(currentTabId));
this.settings.pageState.setPageState(currentTabId, n.PageTitle.get());
};
n.QfqPage.prototype.popStateHandler = function (pageState) {
this.bsTabs.activateTab(pageState.getPageState());
n.PageTitle.set(pageState.getPageData());
n.QfqPage.prototype.popStateHandler = function (obj) {
this.bsTabs.activateTab(obj.target.getPageState());
n.PageTitle.set(obj.target.getPageData());
};
})(QfqNS);
\ No newline at end of file
......@@ -23,20 +23,20 @@
<script>
var fileUpload = new QfqNS.FileUpload('#myForm', 'api/uploadhandler.php', 'the_sip');
fileUpload.addFileUploadStartHandler(function () {
QfqNS.EventEmitter.addListener('fileupload.started', function () {
$('#progress').empty().append('<p>Upload started</p>');
});
fileUpload.addFileUploadEndHandler(function () {
QfqNS.EventEmitter.addListener('fileupload.ended', function () {
$('#progress').append('<p>Upload finished</p>');
});
fileUpload.addFileUploadSuccessHandler(function (data) {
QfqNS.EventEmitter.addListener('fileupload.upload.successful', function (obj) {
$('#progress').append('<p>Upload success</p>');
$('#display').empty().append(data);
$('#display').empty().append(obj.data.file_content);
});
fileUpload.addFileUploadErrorHandler(function () {
QfqNS.EventEmitter.addListener('fileupload.upload.failed', function () {
$('#progress').append('<p>Upload made a booboo</p>');
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment