Commit 18279f25 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge remote-tracking branch 'origin/raos_work' into crose_work

parents 3ee37bec 60406bfa
......@@ -8,6 +8,7 @@ module.exports = function (grunt) {
var js_sources = [
'javascript/src/Helper/*.js',
'javascript/src/Element/*.js',
'javascript/src/Validation/*.js',
'javascript/src/*.js'
];
......
......@@ -154,8 +154,40 @@ QfqNS.Element = QfqNS.Element || {};
}
};
/**
* @public
* @param required
*/
n.FormGroup.prototype.setRequired = function (required) {
this.$element.prop('required', required);
};
/**
* @public
* @param isError
*/
n.FormGroup.prototype.setError = function (isError) {
if (isError) {
this.$formGroup.addClass("has-error has-danger");
} else {
this.$formGroup.removeClass("has-error has-danger");
}
};
n.FormGroup.prototype.setHelp = function (help) {
if (!this.hasHelpBlock()) {
return;
}
this.$helpBlock.text(help);
};
n.FormGroup.prototype.clearHelp = function () {
if (!this.hasHelpBlock()) {
return;
}
this.$helpBlock.empty();
};
})(QfqNS.Element);
\ No newline at end of file
......@@ -33,6 +33,8 @@ var QfqNS = QfqNS || {};
this.formChanged = false;
this.$form = $(document.forms[this.formId]);
this.$form.on("change", this.changeHandler.bind(this));
this.$form.on("invalid.bs.validator", this.validationError.bind(this));
this.$form.on("valid.bs.validator", this.validationSuccess.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>
......@@ -108,7 +110,6 @@ var QfqNS = QfqNS || {};
errorThrown: errorThrown,
jqXHR: jqXHR
}));
// REMOVE: this.userSubmitFailureHandlers.call(this, textStatus, jqXHR, errorThrown);
};
/**
......@@ -117,10 +118,6 @@ var QfqNS = QfqNS || {};
*/
n.Form.prototype.validate = function () {
this.eventEmitter.emitEvent('form.validation.before', n.EventEmitter.makePayload(this, null));
// uncommented because bootstrap-validator sets novalidate="true" on form.
//if (this.$form.attr('novalidate')) {
// return true;
//}
var result = document.forms[this.formId].checkValidity();
......@@ -129,6 +126,20 @@ var QfqNS = QfqNS || {};
return result;
};
/**
* @private
*/
n.Form.prototype.validationError = function (data) {
this.eventEmitter.emitEvent('form.validation.failed', n.EventEmitter.makePayload(this, {element: data.relatedTarget}));
};
/**
* @private
*/
n.Form.prototype.validationSuccess = function (data) {
this.eventEmitter.emitEvent('form.validation.success', n.EventEmitter.makePayload(this, {element: data.relatedTarget}));
};
/**
* @public
*/
......
......@@ -16,7 +16,7 @@ var QfqNS = QfqNS || {};
(function (n) {
'use strict';
// TODO: This object is getting too big. Start refactoring.
// TODO: This object is getting its own gravitational field. Start refactoring.
/**
* Represents a QFQ Form.
*
......@@ -38,6 +38,7 @@ var QfqNS = QfqNS || {};
this.fileDeleteUrl = fileDeleteUrl;
this.form = new n.Form(this.formId);
this.inputMatcher = new n.Validation.InputMatcher(this.formId);
// This is required when displaying validation messages, in to activate the tab, which has validation issues
this.bsTabs = null;
this.lastButtonPress = null;
......@@ -91,10 +92,29 @@ var QfqNS = QfqNS || {};
n.Helper.tinyMce();
this.form.on('form.submit.before', n.Helper.tinyMce.prepareSave);
this.form.on('form.validation.before', n.Helper.tinyMce.prepareSave);
this.form.on('form.validation.failed', this.validationError);
this.form.on('form.validation.success', this.validationSuccess);
};
n.QfqForm.prototype.on = n.EventEmitter.onMixin;
n.QfqForm.prototype.validationError = function (info) {
var $formControl = $(info.data.element);
var $messageContainer = $formControl.siblings('.hidden.with-errors');
$messageContainer.data('qfq.hidden.message', true);
$messageContainer.removeClass('hidden');
};
n.QfqForm.prototype.validationSuccess = function (info) {
var $formControl = $(info.data.element);
var $messageContainer = $formControl.siblings('.with-errors');
if ($messageContainer.data('qfq.hidden.message') === true) {
$messageContainer.addClass('hidden');
}
};
/**
* @private
*/
......@@ -334,6 +354,12 @@ var QfqNS = QfqNS || {};
};
n.QfqForm.prototype.submit = function () {
var alert;
if (this.inputMatcher.validate() !== true) {
alert = new n.Alert("Form is incomplete.", "warning");
alert.show();
return;
}
if (this.form.validate() !== true) {
var element = this.form.getFirstNonValidElement();
......@@ -348,7 +374,7 @@ var QfqNS = QfqNS || {};
this.form.$form.validator('update');
this.form.$form.validator('validate');
var alert = new n.Alert("Form is incomplete.", "warning");
alert = new n.Alert("Form is incomplete.", "warning");
alert.show();
return;
}
......
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
/* @depend ../Element/FormGroup.js */
/**
* Qfq Namespace
*
* @namespace QfqNS
*/
var QfqNS = QfqNS || {};
/**
* Qfq.Element Namespace
*
* @namespace QfqNS.Element
*/
QfqNS.Validation = QfqNS.Validation || {};
(function (n) {
'use strict';
function InputMatcher(formId) {
this.formId = formId;
this.list = [];
this.addAllElementsToList();
}
/**
* @private
*/
InputMatcher.prototype.addAllElementsToList = function () {
var $requireMatching = this.findElementsRequireMatchingOnForm();
var that = this;
$requireMatching.each(function (index, element) {
var $element = $(element);
var $slave = that.resolveCompareElements($element);
if (!$slave) {
return;
}
var masterFormGroup = that.convertElementToFormGroup($element);
var slaveFormGroup = that.convertElementToFormGroup($slave);
that.list.push({
master: masterFormGroup,
slave: slaveFormGroup
});
});
};
/**
* @private
*/
InputMatcher.prototype.findElementsRequireMatchingOnForm = function () {
return this.findOnForm('[data-compare-element]');
};
/**
* @private
*/
InputMatcher.prototype.findOnForm = function (selector) {
return $('#' + this.formId).find(selector);
};
/**
* @private
*/
InputMatcher.prototype.resolveCompareElements = function ($element) {
var $slave;
var slaveName = $element.data('compare-element');
if (!slaveName) {
return null;
}
$slave = this.findOnForm('[name=' + slaveName + ']');
if ($slave.length === 0) {
return null;
}
return $($slave[0]);
};
/**
* @private
*/
InputMatcher.prototype.convertElementToFormGroup = function ($element) {
//return new QfqNS.Element.FormGroup($element);
return QfqNS.Element.getElement($element.attr('name'));
};
InputMatcher.prototype.validate = function () {
var length = this.list.length;
var valid = true;
for (var i = 0; i < length; i++) {
var matcher = this.list[i];
if (matcher.master.getValue() !== matcher.slave.getValue()) {
matcher.slave.setError(true);
matcher.slave.setHelp("Does not match");
valid = false;
} else {
matcher.slave.setError(false);
matcher.slave.clearHelp();
}
}
return valid;
};
n.InputMatcher = InputMatcher;
})(QfqNS.Validation);
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/bootstrap-theme.min.css">
<link rel="stylesheet" href="../css/jqx.base.css">
<link rel="stylesheet" href="../css/jqx.bootstrap.css">
<link rel="stylesheet" href="../css/qfq-bs.css">
<title>Input Confirm Mock</title>
</head>
<body>
<button id="validateMatchers">Validate</button>
<label>Submit to
<select name="submitTo" id="submitTo">
<option>404 error</option>
<option>save_error_matno.json</option>
<option>save_error_geburtstag.json</option>
<option>save_no_redirect.json</option>
<option>save_server_redirect.json</option>
<option>save_client_redirect.json</option>
</select>
</label>
<label>Delete URL
<select name="deleteUrl" id="deleteUrl">
<option>404 error</option>
<option>delete_client_redirect.json</option>
<option>delete_error.json</option>
<option>delete_no_redirect.json</option>
<option>delete_server_redirect.json</option>
</select>
</label>
<label>Upload to
<select name="uploadTo" id="uploadTo">
<option>404 error</option>
<option>uploadhandler.php</option>
<option>uploadhandler_error.php</option>
</select>
</label>
<label>File Delete Url
<select name="fileDeleteUrl" id="fileDeleteUrl">
<option>404 error</option>
<option>delete_file_ok.json</option>
<option>delete_file_error.json</option>
</select>
</label>
<div class="container-fluid">
<div class="row">
<div class="col-md-10 ">
<div class="btn-toolbar pull-right" role="toolbar">
<div class="btn-group" role="group">
<button id="save-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-ok"></span></button>
<button id="close-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="btn-group" role="group">
<button id="delete-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-trash"></span></button>
</div>
<div class="btn-group" role="group">
<a id="form-new-button" href="personmock.html?s=badcaffe1" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-plus"></span></a>
</div>
</div>
</div>
</div>
<form id='myForm' method='post'
accept-charset='UTF-8' autocomplete='on' enctype='application/x-www-form-urlencoded'
class='form-horizontal' data-toggle='validator'>
<div class="form-group">
<div class='col-md-3 qfq-label'><label for="personEmail" class="control-label">Email</label></div>
<div class='col-md-6'><input type="email" class="form-control" id="personEmail" name="personEmail"
placeholder="Email"
title="Tooltip"
data-toggle="tooltip" data-placement="right"
data-compare-element="personEmailRETYPE"></div>
<div class="help-block">Email of the person.</div>
</div>
<div class="form-group">
<div
class='col-md-3 qfq-label'><label for="personEmailRETYPE" class="control-label">please
retype</label></div>
<div class='col-md-6'>
<input type="email" class="form-control" id="personEmailRETYPE"
name="personEmailRETYPE"
placeholder="Email" title="Tooltip"
data-toggle="tooltip" data-placement="right"></div>
<div class="help-block"></div>
</div>
<div class="form-group">
<div class='col-md-3 qfq-label'><label for="personEmail2" class="control-label">Email2</label></div>
<div class='col-md-6'><input type="email" class="form-control" id="personEmail2" name="personEmail2"
placeholder="Email"
title="Tooltip"
data-toggle="tooltip" data-placement="right"
data-compare-element="personEmail2RETYPE"></div>
<div class="help-block">Email of the person.</div>
</div>
<div class="form-group">
<div
class='col-md-3 qfq-label'><label for="personEmail2RETYPE" class="control-label">please
retype</label></div>
<div class='col-md-6'>
<input type="email" class="form-control" id="personEmail2RETYPE"
name="personEmail2RETYPE"
placeholder="Email" title="Tooltip"
data-toggle="tooltip" data-placement="right"></div>
<div class="help-block"></div>
</div>
</form>
</div>
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/validator.min.js"></script>
<script src="../js/jqx-all.js"></script>
<script src="../js/EventEmitter.min.js"></script>
<script src="../js/qfq.debug.js"></script>
<script type="text/javascript">
$(function () {
var qfqPage = new QfqNS.QfqPage({
tabsId: 'myTabs',
formId: 'myForm',
submitTo: 'api/' + $("#submitTo").val(),
deleteUrl: 'api/' + $("#deleteUrl").val(),
fileUploadTo: 'api/' + $("#uploadTo").val(),
fileDeleteUrl: 'api/' + $("#fileDeleteUrl").val(),
});
$("#submitTo").on("change", function (evt) {
qfqPage.settings.submitTo = 'api/' + $(evt.target).val();
qfqPage.qfqForm.submitTo = 'api/' + $(evt.target).val();
});
$("#deleteUrl").on("change", function (evt) {
qfqPage.settings.deleteUrl = 'api/' + $(evt.target).val();
qfqPage.qfqForm.deleteUrl = 'api/' + $(evt.target).val();
});
$("#uploadTo").on("change", function (evt) {
qfqPage.settings.fileUploadTo = 'api/' + $(evt.target).val();
qfqPage.qfqForm.fileUploader.targetUrl = 'api/' + $(evt.target).val();
});
$("#fileDeleteUrl").on("change", function (evt) {
qfqPage.settings.fileDeleteUrl = 'api/' + $(evt.target).val();
qfqPage.qfqForm.fileDeleter.targetUrl = 'api/' + $(evt.target).val();
});
$('#myForm').on('invalid', function () {
console.log("Invalid event catched");
});
$('#validateMatchers').on("click", function () {
var inputMatcher = new QfqNS.Validation.InputMatcher("myForm");
if (!inputMatcher.validate()) {
console.log("Invalid");
} else {
console.log("Valid");
}
});
QfqNS.Log.level = 0;
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -147,7 +147,7 @@
<div class="col-md-6">
<input id="firstname" name="firstname" type="text" class="form-control" required>
<div class="help-block with-errors"></div>
<div class="help-block with-errors hidden"></div>
</div>
</div>
......
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