/**
*
* Validator module.<br>
* The {@link validate} method calls all specific validations in turn and returns <b>global</b> validation status.
*
* @author Fabio Pavesi (fabio@adamassoft.it)
* @namespace
*/
var validator = (function() {
var validations = [
validateRequiredFields,
validateIntFields,
validateFloatFields,
validateURI,
validateURN,
validateDate,
validateDateRange,
validateBoundingBox,
validateAlternativeFields
];
var warnings = 0;
var errors = 0;
function error(control, message) {
errors++;
control.addClass("invalid");
control.after("<div class='error-message'>" + localise(message) + " - " + control.val() + "</div>");
}
function warning(control, message) {
warnings++;
control.addClass("warning");
control.after("<div class='warning-message'>" + localise(message) + " - " + control.val() + "</div>");
}
function validateRequiredFields() {
var result = true;
$("*:not(.fixed)[required='required']").each(function() {
if ( $(this).val() == null || $(this).val().trim() == "" ) {
var item = ediml.findItemById($(this).attr("id"));
var alternativeElement = item.getAlternativeElement();
if ( alternativeElement ) {
var self = $(this);
$("*[required='required']", $("#" + alternativeElement.id)).each(function() {
if ( $(this).val() == null || $(this).val().trim() == "" ) {
error(self, "ALTERNATIVE_REQUIRED_FIELD");
error($(this), "ALTERNATIVE_REQUIRED_FIELD");
result = false;
}
});
} else {
error($(this), "REQUIRED_FIELD");
result = false;
}
}
});
return result;
}
function validateAlternativeFields() {
var result = true;
console.log("validateAlternativeFields");
$(".alternativeGroup").each(function() {
console.log("alternative group " + $(this).attr("id"));
var group = "#" + $(this).attr("id");
$(".element", $("#" + $(this).attr("id"))).first().each(function() {
var thisOne = "#" + $(this).attr("id");
var theOtherOne = "#" + $(this).attr("alternativeto");
var countThese = 0;
var countTheOtherOnes = 0;
$(".form-control", thisOne).each(function() {
if ( !$(this).hasClass("fixed") && $(this).val() != "" ) {
countThese++;
}
})
$(".form-control", theOtherOne).each(function() {
if ( !$(this).hasClass("fixed") && $(this).val() != "" ) {
countTheOtherOnes++;
}
})
if ( countThese > 0 && countTheOtherOnes > 0 ) {
warning($(group), "DOUBLE_VALUE_ON_ALTERNATIVE");
}
console.log("found " + countThese + " local and " + countTheOtherOnes + " alternative items with value");
});
});
return result;
}
function isInt(value) {
return value == "" || (!isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value)))
}
function isFloat(value) {
if ( value == "" ) {
return true;
}
value = parseFloat(value);
if(isNaN(value)) {
return false;
}
return true;
}
function isValidDate(input) {
if ( input == "" ) {
return true;
}
var bits = input.split('-');
var d = new Date(bits[0], bits[1] - 1, bits[2]);
return d.getFullYear() == bits[0] && (d.getMonth() + 1) == bits[1] && d.getDate() == Number(bits[2]);
}
function validateIntFields() {
var result = true;
$("*:not(.fixed)[datatype='int'], *:not(.fixed)[datatype='integer']").each(function() {
var value = $(this).val();
if ( !isInt(value) ) {
error($(this), "NOT_AN_INT");
// console.log("it is not");
result = false;
}
});
return result;
}
function validateFloatFields() {
var result = true;
$("*:not(.fixed)[datatype='real'], *:not(.fixed)[datatype='float'], *:not(.fixed)[datatype='double']").each(function() {
var value = $(this).val();
if ( !isFloat(value) ) {
error($(this), "NOT_A_FLOAT");
// console.log("it is not");
result = false;
}
});
return result;
}
function validateURI() {
var result = true;
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
$("*:not(.fixed)[datatype='URI'], *:not(.fixed)[datatype='URL']").each(function() {
var value = $(this).val().toString();
if ( value != "" && !pattern.test(value) ) {
error($(this), "NOT_A_URI");
result = false;
}
});
return result;
}
function validateURN() {
var result = true;
var pattern = new RegExp('^urn:[a-z0-9]{0,31}:[a-z0-9()+,\-.:=@;$_!*\'%/?#]+$','i'); // fragment locator
$("*:not(.fixed)[datatype='URN']").each(function() {
var value = $(this).val().toString();
if ( value != "" && !pattern.test(value) ) {
error($(this), "NOT_A_URN");
result = false;
}
});
return result;
}
function validateDateRange() {
var result = true;
$("*:not(.fixed)[datatype='dateRange'][id$='_start']").each(function () {
var baseId = $(this).attr("id").replace("_start", "");
console.log("dateRange " + baseId);
// either both with value or both without and syntax check
if ( $(this).val() == "" && $("#" + baseId + "_end").val() == "" ) {
}
if ( $(this).val() > $("#" + baseId + "_end").val() ) {
error($(this), "START_AFTER_END");
result = false;
}
});
return result;
}
function validateBoundingBox() {
var result = true;
$("*:not(.fixed)[datatype='boundingBox'][id$='_northLatitude']").each(function () {
var baseId = $(this).attr("id").replace("_northLatitude", "");
console.log("boundingBox " + baseId);
if ( parseFloat($(this).val()) < parseFloat($("#" + baseId + "_southLatitude").val()) ) {
error($(this), "NORTH_BELOW_SOUTH");
result = false;
}
});
$("*:not(.fixed)[datatype='boundingBox'][id$='_eastLongitude']").each(function () {
var baseId = $(this).attr("id").replace("_eastLongitude", "");
console.log("boundingBox " + baseId);
if ( parseFloat($(this).val()) < parseFloat($("#" + baseId + "_westLongitude").val()) ) {
error($(this), "EAST_WEST_OF_WEST");
result = false;
}
});
return result;
}
function validateDate() {
var result = true;
$("*:not(.fixed)[datatype='date'], *:not(.fixed)[datatype='dateRange']").find("input[type='text']").each(function() {
var value = $(this).val().toString();
if ( value != "" && !isValidDate(value) ) {
error($(this), "NOT_A_DATE");
result = false;
}
});
return result;
}
/**
* Validate method<br>
* It calls specific validation methods in turns and returns true or false<br>
* A return value of true can happen in the presence of warnings, so make sure to check {@link getWarningCount} as well<br>
* @method
* @memberOf validator
* @returns {boolean}
*
* No errors and possible warnings -> true<br>
* At least one error -> false<br>
*
*/
function validate() {
var result = true;
errors = 0;
warnings = 0;
$(".invalid").removeClass("invalid");
$(".error-message").remove();
for ( var i = 0; i < validations.length; i++ ) {
console.log("validator #" + i);
result &= validations[i]();
}
return result;
}
return {
validate: validate,
/**
*
* @method
* @memberOf validator
* @returns {number}
*/
getWarningCount: function() {
return warnings;
},
/**
*
* @method
* @memberOf validator
* @returns {number}
*/
getErrorCount: function() {
return errors;
}
}
})();