diff --git a/javascript/src/Alert.js b/javascript/src/Alert.js
index 215c6bed2f07af05e5cabce7272e1e56f32df95e..5958d9c6a5ae8d693cc21ab1c881522ca0848c17 100644
--- a/javascript/src/Alert.js
+++ b/javascript/src/Alert.js
@@ -3,6 +3,8 @@
  */
 
 /* global $ */
+/* global EventEmitter */
+/* @depend QfqEvents.js */
 
 var QfqNS = QfqNS || {};
 
@@ -62,11 +64,15 @@ var QfqNS = QfqNS || {};
         this.fadeOutDuration = 400;
         this.timerId = null;
 
+        this.eventEmitter = new EventEmitter();
+
         this.userOkButtonHandlers = new n.Helper.FunctionList();
         this.userCancelButtonHandlers = new n.Helper.FunctionList();
         this.userSaveButtonHandlers = new n.Helper.FunctionList();
     };
 
+    n.Alert.prototype.on = n.EventEmitter.onMixin;
+
     /**
      *
      * @private
@@ -253,19 +259,6 @@ var QfqNS = QfqNS || {};
 
     };
 
-    n.Alert.prototype.addOkButtonHandler = function (handler) {
-        this.userOkButtonHandlers.addFunction(handler);
-    };
-
-    n.Alert.prototype.addCancelButtonHandler = function (handler) {
-        this.userCancelButtonHandlers.addFunction(handler);
-    };
-
-    n.Alert.prototype.addSaveButtonHandler = function (handler) {
-        this.userSaveButtonHandlers.addFunction(handler);
-    };
-
-
     /**
      *
      * @param handler
@@ -274,7 +267,7 @@ var QfqNS = QfqNS || {};
      */
     n.Alert.prototype.okButtonHandler = function (handler) {
         this.removeAlert();
-        this.userOkButtonHandlers.call(this);
+        this.eventEmitter.emitEvent('alert.ok', n.EventEmitter.makePayload(this, null));
     };
 
     /**
@@ -285,7 +278,7 @@ var QfqNS = QfqNS || {};
      */
     n.Alert.prototype.saveButtonHandler = function (handler) {
         this.removeAlert();
-        this.userSaveButtonHandlers.call(this);
+        this.eventEmitter.emitEvent('alert.save', n.EventEmitter.makePayload(this, null));
     };
 
     /**
@@ -296,7 +289,7 @@ var QfqNS = QfqNS || {};
      */
     n.Alert.prototype.cancelButtonHandler = function (handler) {
         this.removeAlert();
-        this.userCancelButtonHandlers.call(this);
+        this.eventEmitter.emitEvent('alert.cancel', n.EventEmitter.makePayload(this, null));
     };
 
     n.Alert.prototype.isShown = function () {
diff --git a/javascript/src/BSTabs.js b/javascript/src/BSTabs.js
index 9188b0c55d39f8091987b5e15c4ccb003a42d97c..88a6b71b90dc9c7dc13b649549b292b048cd8b2f 100644
--- a/javascript/src/BSTabs.js
+++ b/javascript/src/BSTabs.js
@@ -4,6 +4,8 @@
 
 /* global $ */
 /* global console */
+/* global EventEmitter */
+
 /* @depend QfqEvents.js */
 
 var QfqNS = QfqNS || {};
@@ -25,6 +27,7 @@ var QfqNS = QfqNS || {};
         this._tabActiveSelector = '#' + this.tabId + ' .active a[data-toggle="tab"]';
         this.tabs = {};
         this.currentTab = this.getActiveTabFromDOM();
+        this.eventEmitter = new EventEmitter();
 
         // Fill this.tabs
         this.fillTabInformation();
@@ -33,6 +36,8 @@ var QfqNS = QfqNS || {};
         this.installTabHandlers();
     };
 
+    n.BSTabs.prototype.on = n.EventEmitter.onMixin;
+
     /**
      * Get active tab from DOM.
      *
@@ -101,8 +106,7 @@ var QfqNS = QfqNS || {};
         this.currentTab = event.target.hash.slice(1);
 
         n.Log.debug("BSTabs.tabShowHandler(): invoke user handler(s)");
-        n.EventEmitter.emitEvent('bootstrap.tab.shown', n.EventEmitter.makePayload(this, null));
-        // REMOVE: this.userTabShowHandlers.call(that);
+        this.eventEmitter.emitEvent('bootstrap.tab.shown', n.EventEmitter.makePayload(this, null));
         n.Log.debug('Exit: BSTabs.tabShowHandler()');
     };
 
diff --git a/javascript/src/FileUpload.js b/javascript/src/FileUpload.js
index a9b23b5e2eb42717f5a66e8a2be356fc06fa63fa..3a54530db2790494862fd6ce21683ee340c66251 100644
--- a/javascript/src/FileUpload.js
+++ b/javascript/src/FileUpload.js
@@ -3,9 +3,11 @@
  */
 
 /* global $ */
+/* global EventEmitter */
 
 /* @depend QfqEvents.js */
 
+
 var QfqNS = QfqNS || {};
 
 (function (n) {
@@ -15,10 +17,13 @@ var QfqNS = QfqNS || {};
         this.formSelector = formSelector;
         this.targetUrl = targetUrl;
         this.sip = sip;
+        this.eventEmitter = new EventEmitter();
 
         this.setupOnChangeHandler();
     };
 
+    n.FileUpload.prototype.on = n.EventEmitter.onMixin;
+
     /**
      *
      * @private
@@ -32,7 +37,7 @@ var QfqNS = QfqNS || {};
      * @param event
      */
     n.FileUpload.prototype.performFileUpload = function (event) {
-        n.EventEmitter.emitEvent('fileupload.started', n.EventEmitter.makePayload(event.target, null));
+        this.eventEmitter.emitEvent('fileupload.started', n.EventEmitter.makePayload(event.target, null));
 
         var data = this.prepareData(event.target);
 
@@ -77,8 +82,8 @@ var QfqNS = QfqNS || {};
             textStatus: textStatus,
             jqXHR: jqXHR
         });
-        n.EventEmitter.emitEvent('fileupload.upload.successful', eventData);
-        n.EventEmitter.emitEvent('fileupload.ended', eventData);
+        this.eventEmitter.emitEvent('fileupload.upload.successful', eventData);
+        this.eventEmitter.emitEvent('fileupload.ended', eventData);
     };
 
     /**
@@ -93,8 +98,8 @@ var QfqNS = QfqNS || {};
             errorThrown: errorThrown,
             jqXHR: jqXHR
         });
-        n.EventEmitter.emitEvent('fileupload.upload.failed', eventData);
-        n.EventEmitter.emitEvent('fileupload.ended', eventData);
+        this.eventEmitter.emitEvent('fileupload.upload.failed', eventData);
+        this.eventEmitter.emitEvent('fileupload.ended', eventData);
     };
 
 
diff --git a/javascript/src/Form.js b/javascript/src/Form.js
index 3f6309532201839a820364c2ea7ddeb6e4b7565c..81245710ca93f3458b81cb8eea84ea5dbadfa31c 100644
--- a/javascript/src/Form.js
+++ b/javascript/src/Form.js
@@ -3,6 +3,7 @@
  */
 
 /* global $ */
+/* global EventEmitter */
 /* @depend QfqEvents.js */
 
 var QfqNS = QfqNS || {};
@@ -12,6 +13,7 @@ var QfqNS = QfqNS || {};
 
     n.Form = function (formId) {
         this.formId = formId;
+        this.eventEmitter = new EventEmitter();
 
         if (!document.forms[this.formId]) {
             throw new Error("Form '" + formId + "' does not exist.");
@@ -26,6 +28,8 @@ var QfqNS = QfqNS || {};
         this.$form.find("input[type=text]").on("input paste", this.changeHandler.bind(this));
     };
 
+    n.Form.prototype.on = n.EventEmitter.onMixin;
+
     /**
      *
      * @param event
@@ -34,7 +38,7 @@ var QfqNS = QfqNS || {};
      */
     n.Form.prototype.changeHandler = function (event) {
         this.formChanged = true;
-        n.EventEmitter.emitEvent('form.changed', n.EventEmitter.makePayload(this, null));
+        this.eventEmitter.emitEvent('form.changed', n.EventEmitter.makePayload(this, null));
         // REMOVE: this.userFormChangeHandlers.call(this);
     };
 
@@ -44,7 +48,7 @@ var QfqNS = QfqNS || {};
 
     n.Form.prototype.resetFormChanged = function () {
         this.formChanged = false;
-        n.EventEmitter.emitEvent('form.reset', n.EventEmitter.makePayload(this, null));
+        this.eventEmitter.emitEvent('form.reset', n.EventEmitter.makePayload(this, null));
         // REMOVE: this.userResetHandlers.call(this);
     };
 
@@ -67,7 +71,7 @@ var QfqNS = QfqNS || {};
      * @private
      */
     n.Form.prototype.ajaxSuccessHandler = function (data, textStatus, jqXHR) {
-        n.EventEmitter.emitEvent('form.submit.successful',
+        this.eventEmitter.emitEvent('form.submit.successful',
             n.EventEmitter.makePayload(this, data, {
                 textStatus: textStatus,
                 jqXHR: jqXHR
@@ -80,7 +84,7 @@ var QfqNS = QfqNS || {};
      * @private
      */
     n.Form.prototype.submitFailureHandler = function (jqXHR, textStatus, errorThrown) {
-        n.EventEmitter.emitEvent('form.submit.failed', n.EventEmitter.makePayload(this, null, {
+        this.eventEmitter.emitEvent('form.submit.failed', n.EventEmitter.makePayload(this, null, {
             textStatus: textStatus,
             errorThrown: errorThrown,
             jqXHR: jqXHR
diff --git a/javascript/src/Helper/FunctionList.js b/javascript/src/Helper/FunctionList.js
index fb9d0dfd641f2d8bea5867ab8f55582235306818..f0ccd20cb3907766636b03d0f5fee5123f8cb188 100644
--- a/javascript/src/Helper/FunctionList.js
+++ b/javascript/src/Helper/FunctionList.js
@@ -10,6 +10,10 @@ QfqNS.Helper = QfqNS.Helper || {};
 (function (n) {
     'use strict';
 
+    /**
+     * @deprecated
+     * @constructor
+     */
     n.FunctionList = function () {
         this.functions = [];
     };
diff --git a/javascript/src/PageState.js b/javascript/src/PageState.js
index 554b06fb13a0c658775a856f7fc939a0c34b8fa4..52f371a38e09fafd4c4c8a955c41ea087f8d43de 100644
--- a/javascript/src/PageState.js
+++ b/javascript/src/PageState.js
@@ -3,6 +3,7 @@
  */
 
 /* @depend QfqEvents.js */
+/* global EventEmitter */
 
 var QfqNS = QfqNS || {};
 
@@ -14,9 +15,12 @@ var QfqNS = QfqNS || {};
         this.pageState = location.hash.slice(1);
         this.data = null;
         this.inPoppingHandler = false;
+        this.eventEmitter = new EventEmitter();
 
         window.addEventListener("popstate", this.popStateHandler.bind(this));
     };
+
+    n.PageState.prototype.on = n.EventEmitter.onMixin;
     /**
      *
      * @param event
@@ -33,7 +37,7 @@ var QfqNS = QfqNS || {};
 
         n.Log.debug("PageState.popStateHandler(): invoke user pop state handler(s)");
 
-        n.EventEmitter.emitEvent('pagestate.state.popped', n.EventEmitter.makePayload(this, null));
+        this.eventEmitter.emitEvent('pagestate.state.popped', n.EventEmitter.makePayload(this, null));
 
         this.inPoppingHandler = false;
         n.Log.debug("Exit: PageState.popStateHandler()");
diff --git a/javascript/src/QfqEvents.js b/javascript/src/QfqEvents.js
index e0a2835c335fc2531569e616b4df9c6e76ca9b53..26be83cc0395ee412c55c7f7b2a4ae27542f7cd3 100644
--- a/javascript/src/QfqEvents.js
+++ b/javascript/src/QfqEvents.js
@@ -10,15 +10,19 @@ 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
-            }
-        )];
+    n.EventEmitter = {
+        makePayload: function (target, data, additionalArgs) {
+            return [$.extend({},
+                typeof additionalArgs === "object" ? additionalArgs : null,
+                {
+                    target: target,
+                    data: data
+                }
+            )];
+        },
+        onMixin: function (event, func) {
+            this.eventEmitter.addListener(event, func);
+        }
     };
 
 })(QfqNS);
\ No newline at end of file
diff --git a/javascript/src/QfqForm.js b/javascript/src/QfqForm.js
index ace44071f10bcd710fcaa7a120b20a5c1ab21677..5898b57d5f96ae543977cec87db6263f91df5342 100644
--- a/javascript/src/QfqForm.js
+++ b/javascript/src/QfqForm.js
@@ -3,6 +3,7 @@
  */
 
 /* global $ */
+/* global EventEmitter */
 /* @depend QfqEvents.js */
 
 var QfqNS = QfqNS || {};
@@ -21,13 +22,14 @@ 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.eventEmitter = new EventEmitter();
 
         this.getSaveButton().addClass("disabled").attr("disabled", "disabled");
 
-        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) {
+        this.form.on('form.changed', this.changeHandler.bind(this));
+        this.form.on('form.reset', this.resetHandler.bind(this));
+        this.form.on('form.submit.successful', this.submitSuccessDispatcher.bind(this));
+        this.form.on('form.submit.failed', function (obj) {
             n.Helper.showAjaxError(null, obj.textStatus, obj.errorThrown);
         });
 
@@ -39,16 +41,18 @@ var QfqNS = QfqNS || {};
         this.setupFormUpdateHandler();
 
         this.fileUploader = new n.FileUpload('#' + this.formId, this.fileUploadTo, this.getSip());
-        n.EventEmitter.addListener('fileupload.started', this.startUploadHandler);
-        n.EventEmitter.addListener('fileupload.upload.success', this.fileUploadSuccessHandler);
+        this.fileUploader.on('fileupload.started', this.startUploadHandler);
+        this.fileUploader.on('fileupload.upload.success', this.fileUploadSuccessHandler);
 
-        n.EventEmitter.addListener('fileupload.upload.failed',
+        this.fileUploader.on('fileupload.upload.failed',
             function (obj) {
                 n.Helper.showAjaxError(null, obj.textStatus, obj.errorThrown);
             });
-        n.EventEmitter.addListener('fileupload.ended', this.endUploadHandler);
+        this.fileUploader.on('fileupload.ended', this.endUploadHandler);
     };
 
+    n.QfqForm.prototype.on = n.EventEmitter.onMixin;
+
     /**
      * @public
      * @param bsTabs
@@ -137,7 +141,7 @@ var QfqNS = QfqNS || {};
     n.QfqForm.prototype.destroyFormAndSetText = function (text) {
         this.form = null;
         $('#' + this.formId).replaceWith($("<p>").append(text));
-        n.EventEmitter.emitEvent('qfqform.destroyed', n.EventEmitter.makePayload(this, null));
+        this.eventEmitter.emitEvent('qfqform.destroyed', n.EventEmitter.makePayload(this, null));
     };
 
     /**
@@ -160,10 +164,10 @@ var QfqNS = QfqNS || {};
         if (this.form.getFormChanged()) {
             var alert = new n.Alert("You have unsaved changes. Do you want to close?", "warning", "yesnosave");
             var that = this;
-            alert.addSaveButtonHandler(function () {
+            alert.on('alert.save', function () {
                 that.form.submitTo(that.submitTo);
             });
-            alert.addOkButtonHandler(function () {
+            alert.on('alert.ok', function () {
                 window.history.back();
             });
             alert.show();
@@ -188,7 +192,7 @@ var QfqNS = QfqNS || {};
         n.Log.debug("delete click");
         var alert = new n.Alert("Do you really want to delete the record?", "warning", "yesno");
         var that = this;
-        alert.addOkButtonHandler(function () {
+        alert.on('alert.ok', function () {
             $.post(that.deleteUrl)
                 .done(that.ajaxDeleteSuccessDispatcher.bind(that))
                 .fail(n.Helper.showAjaxError);
diff --git a/javascript/src/QfqPage.js b/javascript/src/QfqPage.js
index 24447f7f70e9904ed9ef93030917af5b3ec29cae..e07a10d40abbd3da9a7d53ce8351f926632129d7 100644
--- a/javascript/src/QfqPage.js
+++ b/javascript/src/QfqPage.js
@@ -35,8 +35,8 @@ var QfqNS = QfqNS || {};
                 this.settings.pageState.setPageState(this.bsTabs.getCurrentTab(), n.PageTitle.get());
             }
 
-            n.EventEmitter.addListener('bootstrap.tab.shown', this.tabShowHandler.bind(this));
-            n.EventEmitter.addListener('pagestate.state.popped', this.popStateHandler.bind(this));
+            this.bsTabs.on('bootstrap.tab.shown', this.tabShowHandler.bind(this));
+            this.settings.pageState.on('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);
-            n.EventEmitter.addListener('qfqform.destroyed', this.destroyFormHandler.bind(this));
+            this.qfqForm.on('qfqform.destroyed', this.destroyFormHandler.bind(this));
         } catch (e) {
             n.Log.error(e.message);
             this.qfqForm = null;
diff --git a/javascript/src/QfqRecordList.js b/javascript/src/QfqRecordList.js
index 82b2024ce587db9f93f0fde1f03d745faa67f551..18ea78a6f8a20ee521b5c269c7488829cf6cbe03 100644
--- a/javascript/src/QfqRecordList.js
+++ b/javascript/src/QfqRecordList.js
@@ -42,7 +42,7 @@ var QfqNS = QfqNS || {};
 
         var alert = new n.Alert("Do you really want to delete the record?", "warning", "yesno");
         var that = this;
-        alert.addOkButtonHandler(function () {
+        alert.on('alert.ok', function () {
             $.post(that.deleteUrl + "?s=" + sip)
                 .done(that.ajaxDeleteSuccessDispatcher.bind(that, $recordElement))
                 .fail(n.Helper.showAjaxError);
diff --git a/mockup/upload.html b/mockup/upload.html
index 395080612c34bd6692d71fbe40a4bdf9d4670124..88d991b858fcb8d4b2a115d4a1f209665b84e7a5 100644
--- a/mockup/upload.html
+++ b/mockup/upload.html
@@ -23,20 +23,20 @@
 
 <script>
     var fileUpload = new QfqNS.FileUpload('#myForm', 'api/uploadhandler.php', 'the_sip');
-    QfqNS.EventEmitter.addListener('fileupload.started', function () {
+    fileUpload.on('fileupload.started', function () {
         $('#progress').empty().append('<p>Upload started</p>');
     });
 
-    QfqNS.EventEmitter.addListener('fileupload.ended', function () {
+    fileUpload.on('fileupload.ended', function () {
         $('#progress').append('<p>Upload finished</p>');
     });
 
-    QfqNS.EventEmitter.addListener('fileupload.upload.successful', function (obj) {
+    fileUpload.on('fileupload.upload.successful', function (obj) {
         $('#progress').append('<p>Upload success</p>');
         $('#display').empty().append(obj.data.file_content);
     });
 
-    QfqNS.EventEmitter.addListener('fileupload.upload.failed', function () {
+    fileUpload.on('fileupload.upload.failed', function () {
         $('#progress').append('<p>Upload made a booboo</p>');
     });