/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
/* global EventEmitter */
/* @depend QfqEvents.js */
/**
* Qfq Namespace
*
* @namespace QfqNS
*/
var QfqNS = QfqNS || {};
(function (n) {
'use strict';
/**
*
* @param formId
* @constructor
* @name QfqNS.Form
*/
n.Form = function (formId) {
this.formId = formId;
this.eventEmitter = new EventEmitter();
if (!document.forms[this.formId]) {
throw new Error("Form '" + formId + "' does not exist.");
}
this.formChanged = false;
this.$form = $(document.forms[this.formId]);
this.$form.on("change", this.changeHandler.bind(this));
// On <input> elements, we specifically bind this events, in order to update the formChanged property
// immediately, not only after loosing focus. Same goes for <textarea>
this.$form.find("input, textarea").on("input paste", this.changeHandler.bind(this));
this.$form.on('submit', function (event) {
event.preventDefault();
});
};
n.Form.prototype.on = n.EventEmitter.onMixin;
/**
*
* @param event
*
* @private
*/
n.Form.prototype.changeHandler = function (event) {
this.formChanged = true;
this.eventEmitter.emitEvent('form.changed', n.EventEmitter.makePayload(this, null));
};
n.Form.prototype.getFormChanged = function () {
return this.formChanged;
};
n.Form.prototype.markChanged = function () {
this.changeHandler(null);
};
n.Form.prototype.resetFormChanged = function () {
this.formChanged = false;
this.eventEmitter.emitEvent('form.reset', n.EventEmitter.makePayload(this, null));
};
n.Form.prototype.submitTo = function (to) {
$.post(to, this.$form.serialize())
.done(this.ajaxSuccessHandler.bind(this))
.fail(this.submitFailureHandler.bind(this));
};
n.Form.prototype.serialize = function () {
return this.$form.serialize();
};
/**
*
* @param data
* @param textStatus
* @param jqXHR
*
* @private
*/
n.Form.prototype.ajaxSuccessHandler = function (data, textStatus, jqXHR) {
this.eventEmitter.emitEvent('form.submit.successful',
n.EventEmitter.makePayload(this, data, {
textStatus: textStatus,
jqXHR: jqXHR
}));
};
/**
*
*
* @private
*/
n.Form.prototype.submitFailureHandler = function (jqXHR, textStatus, errorThrown) {
this.eventEmitter.emitEvent('form.submit.failed', n.EventEmitter.makePayload(this, null, {
textStatus: textStatus,
errorThrown: errorThrown,
jqXHR: jqXHR
}));
// REMOVE: this.userSubmitFailureHandlers.call(this, textStatus, jqXHR, errorThrown);
};
/**
* @public
* @returns {*}
*/
n.Form.prototype.validate = function () {
// uncommented because bootstrap-validator sets novalidate="true" on form.
//if (this.$form.attr('novalidate')) {
// return true;
//}
return document.forms[this.formId].checkValidity();
};
/**
* @public
*/
n.Form.prototype.getFirstNonValidElement = function () {
var index;
var elementNumber = document.forms[this.formId].length;
for (index = 0; index < elementNumber; index++) {
var element = document.forms[this.formId][index];
if (!element.willValidate) {
continue;
}
if (!element.checkValidity()) {
return element;
}
}
return null;
};
})(QfqNS);