1142 lines
44 KiB
JavaScript
1142 lines
44 KiB
JavaScript
"use strict";
|
|
|
|
var Validator;
|
|
|
|
if(!String.prototype.trim){
|
|
String.prototype.trim = function(){
|
|
return this.replace(/^\s+|\s+$/g, "");
|
|
};
|
|
}
|
|
(function() {
|
|
|
|
Validator = (function() {
|
|
|
|
/**
|
|
* Validator class with methods
|
|
*
|
|
* @category CMS / PUB
|
|
* @dependencies PHP Validator class
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @since CMS Version 2.2
|
|
*
|
|
* @constructor
|
|
* @this {Validator}
|
|
* @param {object} config - config object
|
|
* @param {string} selector - sub area selector
|
|
* @param {object} transl - translation object
|
|
* @param {object} jqObj - jquery container object
|
|
**/
|
|
function Validator(config, selector, transl, jqObj){
|
|
var _this = this;
|
|
|
|
_this.gM = defaultVal(transl, {});
|
|
_this.fields = defaultVal(config, {});
|
|
_this.sel = defaultVal(selector, "body");
|
|
_this.jqObj = defaultVal(jqObj, $(_this.sel));
|
|
|
|
if(_this.fields && _this.fields["cfg"])
|
|
_this.sBindOnAttr = (_this.fields["cfg"]["sBindAttrTitle"] ? _this.fields["cfg"]["sBindAttrTitle"] : "name");
|
|
|
|
// Prep id2fn array
|
|
for(var i in _this.fn)
|
|
if(_this.fn.hasOwnProperty(i))
|
|
_this.id2fn[_this.fn[i]] = i;
|
|
|
|
if(typeof StickyMsg !== "undefined") {
|
|
_this.oErrorMsg = new StickyMsg(_this.jqObj);
|
|
_this.oErrorMsg.bShowMsgOnErrorAppend = true;
|
|
}
|
|
|
|
// Set default values
|
|
_this.oForm.vDefValues = {};
|
|
_this.oForm.bHasChanges = false;
|
|
_this.oForm.bManualChanges = false;
|
|
_this.oForm.vFieldsChanged = [];
|
|
|
|
_this.init();
|
|
}
|
|
|
|
/**
|
|
* @property {string} sel
|
|
* @property {jQuery} jqObj
|
|
*
|
|
* @property {object} fields
|
|
* @property {object} currField
|
|
* @property {boolean} log
|
|
* @property {string} sBindOnAttr
|
|
* @property {StickyMsg|boolean} oErrorMsg
|
|
*
|
|
* @property {object} gM
|
|
* @enum {string} vTransl
|
|
* @enum {string} fn
|
|
* @property {object} id2fn
|
|
* @enum {T_} fn
|
|
* @enum {P_} fn
|
|
*
|
|
* @property {object} oForm
|
|
* @property {object} oForm.vDefValues
|
|
* @property {boolean} oForm.bHasChanges
|
|
* @property {boolean} oForm.bManualChanges
|
|
* @property {object} oForm.vFieldsChanged
|
|
**/
|
|
Validator.prototype = {
|
|
// Class declarations
|
|
sel : "", // Subarea selector
|
|
jqObj : {}, // Subarea jquery object
|
|
|
|
fields : {}, // Config data
|
|
currField : {}, // Currently processed cfg field
|
|
log : false, // Log validator events
|
|
|
|
sBindOnAttr : "name", // Bind events based on data attr name
|
|
oErrorMsg : false,
|
|
|
|
gM : {},
|
|
vTransl : {
|
|
chkComp : "Please fill in the field!",
|
|
chkEmail : "Not a valid email address specified!",
|
|
chkDigit : "Only digits allowed!",
|
|
chkNum : "Not a valid number specified!",
|
|
chkInt : "Not a valid integer specified!",
|
|
chkIp : "Not a valid ip address specified!",
|
|
chkDate : "Invalid date specified!",
|
|
chkMmYyyy : "Invalid date specified!",
|
|
chkPhone : "Invalid telephone specified!",
|
|
chkUrlSegm : "Invalid url segment specified!",
|
|
chkAbsUrl : "Invalid url specified!",
|
|
chkIsSize : "Invalid size specified!",
|
|
chkEqual : "Fields do not match!",
|
|
chkContNoUrl : "Field cannot contain any link!",
|
|
|
|
chkLenEqual : "Value length must be %s",
|
|
chkLenBetween : "Value length must be between %s and %d",
|
|
chkLenMin : "Min value length is %s",
|
|
chkLenMax : "Max value length is %s"
|
|
},
|
|
fn : {
|
|
chkDate : "t1", chkMmYyyy : "t2", chkTime : "t3", chkNum : "t4", chkInt : "t5",
|
|
chkDigit : "t6", chkEmail : "t7", chkIp : "t8", chkLen : "t9", chkPhone : "t10",
|
|
chkUrlSegm : "t11", chkAbsUrl : "t12", chkIsSize : "t13", chkString : "t14", chkEqual : "t15",
|
|
chkContNoUrl : "t16", chkComp : "t17"
|
|
},
|
|
|
|
id2fn : {},
|
|
T_ : {STR:"s", INT:"i", FLOAT:"f", DEC:"d", DATE:"d", ARRAY:"a", TIME:"t"},
|
|
P_ : {COMP:"c", TYPE:"ty", TEST:"t", EVENT:"e", ADDS:"a", LINK:"l", TITLE:"ft"},
|
|
|
|
oForm : {
|
|
vDefValues : {},
|
|
bHasChanges : false,
|
|
bManualChanges : false,
|
|
vFieldsChanged : []
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function to initialize validator class
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @return {object} this - returns validator object
|
|
*/
|
|
Validator.prototype.init = function(){
|
|
var _this = this, jqObj;
|
|
if(_this.fields){
|
|
for(var i in _this.fields){
|
|
if(_this.fields.hasOwnProperty(i)){
|
|
if(i !== "cfg" && _this.fields[i][_this.P_.TEST]){
|
|
if(!_this.fields[i][_this.P_.EVENT]) _this.fields[i][_this.P_.EVENT] = "blur";
|
|
_this.jqObj.find("[" + _this.sBindOnAttr + "=" + i + "]").bind(_this.fields[i][_this.P_.EVENT], function(){
|
|
// Call passed linked object method
|
|
_this.checkThis(this);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
_this.loadDefaultFormValues();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function to bind additional checkup fields
|
|
*
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {jQuery|string} jqSelectorObj - passed caller object
|
|
* @param {{find:function}} jqSelectorObj
|
|
* @category Validator
|
|
*/
|
|
Validator.prototype.bindSubs = function(jqSelectorObj){
|
|
var _this = this;
|
|
|
|
if(_this.fields){
|
|
if(typeof jqSelectorObj === "string")
|
|
jqSelectorObj = _this.jqObj.find(jqSelectorObj);
|
|
|
|
if(jqSelectorObj.length){
|
|
for(var i in _this.fields){
|
|
if(_this.fields.hasOwnProperty(i)){
|
|
if(i !== "cfg" && _this.fields[i][_this.P_.TEST]){
|
|
jqSelectorObj.find("[" + _this.sBindOnAttr + "=" + i + "]").bind(_this.fields[i][_this.P_.EVENT], function(){
|
|
// Call passed linked object method
|
|
_this.checkThis(this);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function to validate field by passed event caller object based on config
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} caller - passed caller object
|
|
* @return {boolean} true / false if unsuccessful
|
|
*/
|
|
Validator.prototype.checkThis = function(caller){
|
|
|
|
var _this = this;
|
|
var result = true;
|
|
var key, val, val2;
|
|
|
|
var jqCaller = $(caller);
|
|
var sId = jqCaller.attr("id");
|
|
|
|
val2 = val = defaultVal(jqCaller.val(), "");
|
|
key = defaultVal(jqCaller.attr(_this.sBindOnAttr), "");
|
|
|
|
// Check if field exists in config
|
|
if(_this.fields[key] && _this.fields[key][_this.P_.TEST]){
|
|
|
|
_this.currField = _this.fields[key];
|
|
|
|
// Remove spaces
|
|
if(/^ | $/g.test(val)) val2 = val.trim();
|
|
|
|
// Check is float
|
|
if(val.indexOf(",") !== -1 && (_this.fields[key][_this.P_.TYPE] === _this.T_.FLOAT || _this.fields[key][_this.P_.TYPE] === _this.T_.DEC)){
|
|
val2 = val2.replace(",", ".");
|
|
}
|
|
// Check is time
|
|
if((val.indexOf(",") !== -1 || val.indexOf(".") !== -1) && _this.fields[key][_this.P_.TYPE] === _this.T_.TIME){
|
|
val2 = val2.replace(",", ":").replace(".", ":");
|
|
}
|
|
|
|
// If value changed while trimming or replacing , -> . - call
|
|
if(val !== val2){
|
|
jqCaller.val(val2).trigger(_this.currField.e);
|
|
return false;
|
|
}
|
|
|
|
// Set flag if one form value changed
|
|
if(_this.oForm.vDefValues.hasOwnProperty(sId)){
|
|
if(_this.oForm.vDefValues[sId] != val){
|
|
_this.oForm.bHasChanges = true;
|
|
_this.oForm.vFieldsChanged.push(sId);
|
|
}
|
|
}else{
|
|
_this.oForm.bHasChanges = true;
|
|
_this.oForm.vFieldsChanged.push(sId);
|
|
}
|
|
|
|
// Start field value testing
|
|
if(result = _this.chkComp(key, val, jqCaller, _this.currField)){
|
|
|
|
var fn;
|
|
// Run tests on field until error detected
|
|
if(val.length){
|
|
for(var i in _this.currField[_this.P_.TEST]){
|
|
if(_this.currField[_this.P_.TEST].hasOwnProperty(i)){
|
|
fn = (isNaN(parseInt(i)) ? i : _this.currField[_this.P_.TEST][i]);
|
|
if(_this.id2fn[fn]){
|
|
fn = _this.id2fn[fn];
|
|
// Check if test available
|
|
if (fn in _this){
|
|
if(!_this[fn](key, val, jqCaller, _this.currField)){
|
|
result = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(result)
|
|
_this.hideError(jqCaller);
|
|
jqCaller.removeClass("lf");
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Function to clear unused changed fields
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
*/
|
|
Validator.prototype.rmNonExistingChangedFields = function(){
|
|
var _this = this;
|
|
if(_this.oForm.vFieldsChanged.length){
|
|
var jqActiveFormFields = _this.jqObj.find("#" + _this.oForm.vFieldsChanged.join(", #"));
|
|
_this.oForm.vFieldsChanged = jqActiveFormFields.map(function() { return this.id; }).toArray();
|
|
_this.oForm.bHasChanges = _this.oForm.vFieldsChanged.length > 0;
|
|
}
|
|
};
|
|
/**
|
|
* Function to clear unused changed fields
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
*/
|
|
Validator.prototype.loadDefaultFormValues = function(){
|
|
var str = "", jqFields, _this = this;
|
|
_this.oForm.vDefValues = [];
|
|
|
|
if(_this.fields){
|
|
for(var i in _this.fields){
|
|
str += ",[" + _this.sBindOnAttr + "=" + i + "]";
|
|
}
|
|
if(str.length){
|
|
jqFields = _this.jqObj.find(str.substring(1));
|
|
jqFields.each(function(){
|
|
var jqX = $(this);
|
|
// Save initial values
|
|
_this.oForm.vDefValues[jqX.attr("id")] = jqX.val();
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Function to clear current field error
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} caller - field object for which to hide error
|
|
*/
|
|
Validator.prototype.hideError = function(caller){
|
|
if(caller){
|
|
var jqValidate = $(caller).closest(".validate");
|
|
if(!jqValidate.length) jqValidate = $(caller).parent();
|
|
|
|
jqValidate.addClass("v-ok").removeClass("v-error").find(".errMsg").hide().html("");
|
|
if(this.oErrorMsg) this.oErrorMsg.removeErrorFromTitle($(caller));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function to prepare current field error
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} caller - field object for which to add error
|
|
* @param {string} eMsgCode - error message to show
|
|
* @param {boolean} [bAppendAndShow=true] - show or append error msg to title
|
|
* @return {string} msg - error message
|
|
*/
|
|
Validator.prototype.prepError = function(caller, eMsgCode, bAppendAndShow){
|
|
var _this = this, msg = "";
|
|
// Check if error msg passed down with validator
|
|
if(eMsgCode){
|
|
if(_this.fn[eMsgCode] && _this.currField && _this.currField[_this.P_.TEST] && _this.currField[_this.P_.TEST][_this.fn[eMsgCode]]){
|
|
msg = _this.currField[_this.P_.TEST][_this.fn[eMsgCode]];
|
|
}else{
|
|
msg = (_this.gM && _this.gM[eMsgCode] ? _this.gM[eMsgCode] : (_this.vTransl[eMsgCode] ? _this.vTransl[eMsgCode] : eMsgCode + " - Error!"));
|
|
}
|
|
}
|
|
// Show error
|
|
if(defaultVal(bAppendAndShow, true)) this.showError(caller, msg);
|
|
return msg;
|
|
};
|
|
|
|
/**
|
|
* Function to show current field error
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} caller - field object for which to add error
|
|
* @param {string} sMessage - error message to show
|
|
*/
|
|
Validator.prototype.showError = function(caller, sMessage){
|
|
|
|
if(caller){
|
|
var _this = this;
|
|
var jqCaller = $(caller);
|
|
var jqErr, jqValidate = jqCaller.closest(".validate");
|
|
|
|
if(!jqValidate.length) jqValidate = jqCaller.parent();
|
|
|
|
jqErr = jqValidate.addClass("v-error").removeClass("v-ok").find(".errMsg");
|
|
if(!jqErr.length) jqValidate.append("<div class='errMsg'>"+sMessage+"</div>");
|
|
else jqErr.show().html(sMessage);
|
|
|
|
var id = jqCaller.attr("id");
|
|
if(defaultVal(id, false)) {
|
|
_this.showErrorsInTitle([{
|
|
id: id,
|
|
lbl: _this.getLabelText4ErrorBox(jqCaller),
|
|
msg: sMessage,
|
|
fn: function () {
|
|
_this.scrollToErrorField(jqCaller, _this.oErrorMsg.jqMsgBody);
|
|
}
|
|
}]);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Function to show field errors by field object error cfg
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} errors - error cfg array
|
|
*/
|
|
Validator.prototype.vErrorFields = [];
|
|
Validator.prototype.showErrorsByObject = function (errors) {
|
|
let _this = this;
|
|
_this.hideAllErrors();
|
|
errors = defaultVal(errors, {});
|
|
_this.showErrorsByObjectRecursion(errors, _this.jqObj);
|
|
// Get all title errors & show
|
|
if (_this.vErrorFields.length) {
|
|
_this.showErrorsInTitle(_this.vErrorFields);
|
|
}
|
|
};
|
|
Validator.prototype.showErrorsByObjectRecursion = function (errors, jqObj) {
|
|
let i, jqField, _this = this;
|
|
if (errors && jqObj.length) {
|
|
// Set errors
|
|
for (i in errors) {
|
|
if (errors.hasOwnProperty(i)) {
|
|
if (typeof errors[i] === "object")
|
|
_this.showErrorsByObjectRecursion(errors[i], jqObj.find("#" + i));
|
|
else {
|
|
jqField = jqObj.find("[" + _this.sBindOnAttr + "=" + i + "]");
|
|
(function (errMsg, jqObj) {
|
|
_this.vErrorFields.push({
|
|
id: jqField.attr("id"),
|
|
lbl: _this.getLabelText4ErrorBox(jqField),
|
|
msg: errMsg,
|
|
fn: function () {
|
|
_this.scrollToErrorField(jqObj, _this.oErrorMsg.jqMsgBody);
|
|
}
|
|
});
|
|
|
|
_this.showError(jqField, errors[i]);
|
|
})(errors[i], jqField);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Function : get error field message to display
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} jqField - jquery error field object
|
|
*/
|
|
Validator.prototype.getLabelText4ErrorBox = function(jqField){
|
|
var sLabel = "", jqLabel, _this = this;
|
|
if(jqField.length){
|
|
jqLabel = jqField.closest("li").find("label");
|
|
if(jqLabel.length > 1) jqLabel = jqField.closest("li").find("label:visible:first");
|
|
|
|
var vCfg = _this.fields[jqField.attr(_this.sBindOnAttr)];
|
|
if(vCfg){
|
|
sLabel = defaultValNotFalse((vCfg.hasOwnProperty(_this.P_.TITLE) ? vCfg[_this.P_.TITLE] : false), (jqLabel.length ? jqLabel.text() : ""));
|
|
|
|
// Check if label ends with ":"
|
|
if(sLabel[sLabel.length - 1] !== ":") sLabel += ":";
|
|
}
|
|
}
|
|
return sLabel;
|
|
};
|
|
/**
|
|
* Function : scroll to first found v-error class
|
|
*
|
|
* @this {Validator}
|
|
* @author Aivars Žukovskis <info@brsystems.lv>
|
|
* @param {object} jqObj - jquery object
|
|
*/
|
|
Validator.prototype.scrollToFirstError = function(jqObj){
|
|
var jqErrorObj = jqObj.find(".v-error:first");
|
|
if(jqErrorObj.length){
|
|
if(!jqErrorObj.is(":visible")) jqErrorObj.closest("div.settings").find("> h3").trigger("click");
|
|
var jqCustomStatusObj = $(".custom-status > .validator-custom-msg");
|
|
|
|
if(jqCustomStatusObj.length) {
|
|
$('html, body').animate({
|
|
scrollTop: jqCustomStatusObj.offset().top - 25
|
|
}, 500);
|
|
}
|
|
this.scrollToFirstErrorAdditional(jqErrorObj);
|
|
}
|
|
};
|
|
/** Additional Function to call when scrolled to object (do additional magic) */
|
|
Validator.prototype.scrollToFirstErrorAdditional = function(jqCaller){};
|
|
/**
|
|
* Function to scroll to given field and if not visible try to open settings
|
|
*
|
|
* @this {Validator}
|
|
* @author Aivars Žukovskis <info@brsystems.lv>
|
|
* @param {object} jqScrollToObj - field to scroll
|
|
* @param {jQuery} jsOffsetElem - jquery offset element to exclude as well
|
|
*/
|
|
Validator.prototype.scrollToErrorField = function(jqScrollToObj, jsOffsetElem){
|
|
if(jqScrollToObj.length){
|
|
|
|
jsOffsetElem = defaultVal(jsOffsetElem, $());
|
|
var jqErrorObj = jqScrollToObj.closest("div.validate");
|
|
if(!jqErrorObj.length) jqErrorObj = jqScrollToObj.parent();
|
|
if(!jqErrorObj.is(":visible")) jqErrorObj.closest("div.settings").find("> h3").trigger("click");
|
|
var c = jqErrorObj.offset().top - 25;
|
|
|
|
if(jsOffsetElem.length) c -= jsOffsetElem.outerHeight();
|
|
|
|
// Check scroll container exists
|
|
var jqContainer = jqScrollToObj.closest(".scroll-cnt");
|
|
if(!jqContainer.length) jqContainer = $('html, body');
|
|
else c += -jqContainer.offset().top + jqContainer.scrollTop(); // Scroll correction within container
|
|
|
|
jqContainer.stop(true, true).animate({
|
|
scrollTop: c
|
|
}, 500);
|
|
|
|
}
|
|
};
|
|
/** Additional Function to call on show errors (do additional magic) */
|
|
Validator.prototype.showErrorsInTitle = function(vFields){
|
|
var _this = this;
|
|
var i = 0, jqObj, jqField, x;
|
|
var vFieldsNotFound = [];
|
|
|
|
vFields = defaultVal(vFields, []);
|
|
if(!vFields.length){
|
|
// Gather default v-errors
|
|
_this.jqObj.find(".v-error").each(function(){
|
|
jqObj = $(this);
|
|
jqField = jqObj.find("[" + _this.sBindOnAttr + "]").first();
|
|
x = _this.fields[jqField.attr(_this.sBindOnAttr)];
|
|
|
|
if(x){
|
|
vFields[i++] = {
|
|
id : jqObj.find("input,select,textarea").attr("id"),
|
|
lbl : _this.getLabelText4ErrorBox(jqField),
|
|
msg : $(this).find(".errMsg").text(),
|
|
fn : function(jqObj){
|
|
_this.scrollToErrorField($(".form-data #" + jqObj.attr("data-id")), _this.oErrorMsg.jqMsgBody);
|
|
}
|
|
}
|
|
}else{
|
|
vFieldsNotFound.push(jqObj);
|
|
}
|
|
});
|
|
}
|
|
|
|
if(vFields.length && _this.oErrorMsg) _this.oErrorMsg.appendErrorsInTitle(vFields);
|
|
if(vFieldsNotFound.length) _this.showErrorsInTitleCustom(_this.oErrorMsg, vFieldsNotFound);
|
|
};
|
|
|
|
/** Additional Function to call on show errors (do additional magic) */
|
|
Validator.prototype.showErrorsInTitleCustom = function(oErrorMsg, vErrorObjects){ };
|
|
|
|
/**
|
|
* Function to remove empty errors from title - with no linked element
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @prop jQuery jqContainer - jquery container where to search errors
|
|
* @return {boolean} true / false
|
|
*/
|
|
Validator.prototype.removeExistingErrorsFromTitleByContainer = function(jqContainer){
|
|
var vFields = [], _this = this;
|
|
|
|
jqContainer = defaultVal(jqContainer, $());
|
|
jqContainer = (jqContainer.length ? _this.jqObj.find(jqContainer): _this.jqObj);
|
|
|
|
jqContainer.find(".v-error").each(function () {
|
|
vFields.push($(this).find("input,select,textarea").attr("id"));
|
|
});
|
|
|
|
if(vFields.length)
|
|
_this.oErrorMsg.removeErrorFromTitleByKeyAndAttribute(vFields);
|
|
};
|
|
|
|
/**
|
|
* Function to validate selector fields within passed cfg
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @param {string|object|boolean|jQuery} [field = false] - field to validate
|
|
* @param {{not:function}} field
|
|
* @return {boolean} true / false if form not valid
|
|
*/
|
|
Validator.prototype.isFormValid = function(field){
|
|
var _this = this;
|
|
var str = "", oError = false;
|
|
|
|
field = defaultVal(field, false);
|
|
if(field){
|
|
if(!$.isObject(field)){
|
|
field = _this.jqObj.find("[" + _this.sBindOnAttr + "="+ field +"]");
|
|
}
|
|
}
|
|
|
|
if(!field){
|
|
if(_this.fields){
|
|
for(var i in _this.fields){
|
|
str += ",[" + _this.sBindOnAttr + "=" + i + "]";
|
|
}
|
|
}
|
|
if(str.length > 1)
|
|
field = _this.jqObj.find(str.substring(1));
|
|
else
|
|
field = $("");
|
|
}
|
|
|
|
if(field){
|
|
field.not(".skip").each(function(){
|
|
if(!_this.checkThis(this))
|
|
oError = true;
|
|
});
|
|
}
|
|
|
|
if(oError) {
|
|
//_this.showErrorsInTitle();
|
|
//_this.scrollToFirstError(_this.jqObj);
|
|
} else _this.hideAllErrors();
|
|
|
|
return !oError;
|
|
|
|
};
|
|
|
|
/**
|
|
* Function to clear all field errors
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.hideAllErrors = function(){
|
|
var _this = this;
|
|
_this.vErrorFields = [];
|
|
if(_this.oErrorMsg) _this.oErrorMsg.removeErrorFromTitle($(), true);
|
|
_this.jqObj.find(".v-error").removeClass("v-ok v-error");
|
|
};
|
|
|
|
/**
|
|
* Function to get linked field by current field config
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {object} fCfg - passed field config object
|
|
* @return {object} linked field object
|
|
*/
|
|
Validator.prototype.getLinkedField = function(fCfg){
|
|
var _this = this;
|
|
if(fCfg[_this.P_.LINK]){
|
|
var linkedField = _this.jqObj.find("[" + _this.sBindOnAttr + "=" + fCfg[_this.P_.LINK] + "]");
|
|
if(linkedField.length)
|
|
return linkedField;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Function to log actions
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - string key to log
|
|
* @param {string} val - string value to log
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.logThis = function(key, val){
|
|
var _this = this;
|
|
if(_this.log){
|
|
if("console" in window){
|
|
if(typeof(val) !== "object"){
|
|
console.log(key + ":\t\t\t" + val);
|
|
}else{
|
|
console.dir({key : val});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is empty & compulsory
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} [key] jqCaller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} jqCaller - field configuration object
|
|
* @param {object} fCfg - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkComp = function(key, val, jqCaller, fCfg){
|
|
var st = true, msg = "", _this = this;
|
|
|
|
// Check if compulsory field filled
|
|
if(!jqCaller.hasClass("passEmpty") && (fCfg[_this.P_.COMP] === true || fCfg[_this.P_.COMP] === 1) && (val.length === 0 || fCfg[_this.P_.TYPE] === 'float' && parseInt(val) === 0)){
|
|
st = false;
|
|
msg = this.prepError(jqCaller, "chkComp");
|
|
}
|
|
|
|
_this.logThis("chkComp", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid email
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkEmail = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(!/[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]{2,4}$/.test(val)) {
|
|
msg = this.prepError(caller, "chkEmail");
|
|
st = false;
|
|
}
|
|
this.logThis("chkEmail", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid digit
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkDigit = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^[\d]*$/)){
|
|
msg = this.prepError(caller, "chkDigit");
|
|
st = false;
|
|
}
|
|
this.logThis("chkDigit", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid num
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkNum = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^[\-\+]?[\d\,]*\.?[\d]*$/)){
|
|
msg = this.prepError(caller, "chkNum");
|
|
st = false;
|
|
}
|
|
this.logThis("chkNum", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid integer
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkInt = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^[\d]*$/)){
|
|
msg = this.prepError(caller, "chkInt");
|
|
st = false;
|
|
}
|
|
this.logThis("chkInt", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid IP
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkIp = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/)){
|
|
msg = this.prepError(caller, "chkIp");
|
|
st = false;
|
|
}
|
|
this.logThis("chkIp", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid time
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkTime = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/)){
|
|
msg = this.prepError(caller, "chkTime");
|
|
st = false;
|
|
}
|
|
this.logThis("chkTime", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid phone
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkPhone = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^\+?\s?[0-9\s]+$/)){
|
|
msg = this.prepError(caller, "chkPhone");
|
|
st = false;
|
|
}
|
|
this.logThis("chkPhone", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid URL segment
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkUrlSegm = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if (val.length > 0 && !val.match(/^[a-zA-Z]+[a-zA-Z0-9-]*$/)){
|
|
msg = this.prepError(caller, "chkUrlSegm");
|
|
st = false;
|
|
}
|
|
this.logThis("chkUrlSegm", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid absolute URL
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkAbsUrl = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(!/^(news|telnet|nttp|file|http|ftp|https):\/\/[-A-Za-z0-9\\.]+\\?.*$/.test(val)) {
|
|
msg = this.prepError(caller, "chkAbsUrl");
|
|
st = false;
|
|
}
|
|
this.logThis("chkAbsUrl", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid size measurement
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkIsSize = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && !val.match(/^[0-9.]+([ ]?)(%|in|cm|mm|em|ex|pt|pc|px)?$/)){
|
|
msg = this.prepError(caller, "chkIsSize");
|
|
st = false;
|
|
}
|
|
this.logThis("chkIsSize", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check min length param
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @param {object} fCfg - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkLen = function(key, val, caller, fCfg){
|
|
var _this = this;
|
|
var st = true, msg = "", bCheck = true;
|
|
|
|
if(fCfg[_this.P_.ADDS]){
|
|
|
|
var vAdds = fCfg[_this.P_.ADDS];
|
|
|
|
// Check length param configuration
|
|
if(vAdds["min"] && vAdds["max"] && vAdds["min"] === vAdds["max"])
|
|
vAdds["len"] = vAdds["min"];
|
|
|
|
// Check length equal to
|
|
if(bCheck && vAdds["len"] && parseInt(vAdds["len"]) > 0){
|
|
if(val.length !== parseInt(vAdds["len"])){
|
|
msg = _this.prepError(caller, "chkLenEqual", false).replace("%s", vAdds["len"]);
|
|
_this.showError(caller, msg);
|
|
st = false;
|
|
}
|
|
bCheck = false;
|
|
}
|
|
|
|
// Check length between
|
|
var min = (vAdds["min"] ? parseInt(vAdds["min"]) : 0);
|
|
var max = (vAdds["max"] ? parseInt(vAdds["max"]) : 0);
|
|
if(bCheck && vAdds["between"]){
|
|
if(val.length < min || val.length > max){
|
|
msg = _this.prepError(caller, "chkLenBetween", false).replace("%s", vAdds["min"]).replace("%m", vAdds["max"]);
|
|
_this.showError(caller, msg);
|
|
st = false;
|
|
}
|
|
bCheck = false;
|
|
}
|
|
|
|
// Check min length param
|
|
if(bCheck && vAdds["min"]){
|
|
if(val.length < min){
|
|
msg = _this.prepError(caller, "chkLenMin", false).replace("%s", vAdds["min"]);
|
|
_this.showError(caller, msg);
|
|
st = false;
|
|
}
|
|
bCheck = false;
|
|
}
|
|
|
|
// Check max length param
|
|
if(bCheck && vAdds["max"]){
|
|
if(val.length > max){
|
|
msg = _this.prepError(caller, "chkLenMax", false).replace("%s", vAdds["max"]);
|
|
_this.showError(caller, msg);
|
|
st = false;
|
|
}
|
|
//bCheck = false;
|
|
}
|
|
}
|
|
|
|
_this.logThis("chkLen", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is equal to linked field
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @param {object} fCfg - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkEqual = function(key, val, caller, fCfg){
|
|
var st = false, msg = "", lf;
|
|
|
|
// Compare fields
|
|
if(lf = this.getLinkedField(fCfg)){
|
|
if(val === lf.val())
|
|
st = true;
|
|
// Trigger event on field
|
|
if(!$(caller).hasClass("lf")){
|
|
lf.addClass("lf");
|
|
lf.trigger("blur");
|
|
}else{
|
|
$(caller).removeClass("lf")
|
|
}
|
|
}
|
|
if(!st)
|
|
msg = this.prepError(caller, "chkEqual");
|
|
|
|
this.logThis("chkEqual", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
/**
|
|
* Function to check if passed field is a valid date
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkDate = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
|
|
try {
|
|
//Change the below values to determine which format of date you wish to check. It is set to dd/mm/yyyy by default.
|
|
var DayIndex = 0;
|
|
var MonthIndex = 1;
|
|
var YearIndex = 2;
|
|
|
|
var value = val.replace(/-/g, "/").replace(/\./g, "/");
|
|
|
|
var SplitValue = value.split("/");
|
|
var OK = true;
|
|
if (!(SplitValue[DayIndex].length === 1 || SplitValue[DayIndex].length === 2)) {
|
|
OK = false;
|
|
}
|
|
if (OK && !(SplitValue[MonthIndex].length === 1 || SplitValue[MonthIndex].length === 2)) {
|
|
OK = false;
|
|
}
|
|
if (OK && SplitValue[YearIndex].length !== 4) {
|
|
OK = false;
|
|
}
|
|
if (OK) {
|
|
var Day = parseInt(SplitValue[DayIndex], 10);
|
|
var Month = parseInt(SplitValue[MonthIndex], 10);
|
|
var Year = parseInt(SplitValue[YearIndex], 10);
|
|
|
|
if (OK = ((Year > 1900) && (Year < 2080))) {
|
|
if (OK = (Month <= 12 && Month > 0)) {
|
|
var LeapYear = (((Year % 4) === 0) && ((Year % 100) !== 0) || ((Year % 400) === 0));
|
|
|
|
if (Month === 2) {
|
|
OK = LeapYear ? Day <= 29 : Day <= 28;
|
|
}
|
|
else {
|
|
if ((Month === 4) || (Month === 6) || (Month === 9) || (Month === 11)) {
|
|
OK = (Day > 0 && Day <= 30);
|
|
}
|
|
else {
|
|
OK = (Day > 0 && Day <= 31);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
st = OK;
|
|
}catch(e){
|
|
st = false;
|
|
}
|
|
|
|
if(!st)
|
|
msg = this.prepError(caller, "chkDate");
|
|
|
|
this.logThis("chkDate", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
/**
|
|
* Function to check if passed field is a valid month - year date ( MM.YYYY )
|
|
*
|
|
* @this {Validator}
|
|
* @author Aivars Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkMmYyyy = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
|
|
try {
|
|
//Change the below values to determine which format of date you wish to check. It is set to mm/yyyy by default.
|
|
var MonthIndex = 0;
|
|
var YearIndex = 1;
|
|
|
|
var value = val.replace(/-/g, "/").replace(/\./g, "/");
|
|
|
|
var SplitValue = value.split("/");
|
|
var OK = true;
|
|
if (OK && !(SplitValue[MonthIndex].length === 1 || SplitValue[MonthIndex].length === 2))
|
|
OK = false;
|
|
if (OK && SplitValue[YearIndex].length !== 4)
|
|
OK = false;
|
|
|
|
if (OK) {
|
|
var Month = parseInt(SplitValue[MonthIndex], 10);
|
|
var Year = parseInt(SplitValue[YearIndex], 10);
|
|
|
|
if (OK = ((Year > 1900) && (Year < 2080))) {
|
|
OK = (Month <= 12 && Month > 0);
|
|
}
|
|
}
|
|
|
|
st = OK;
|
|
}catch(e){
|
|
st = false;
|
|
}
|
|
|
|
if(!st)
|
|
msg = this.prepError(caller, "chkMmYyyy");
|
|
|
|
this.logThis("chkMmYyyy", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
|
|
/**
|
|
* Function to check if passed field has any url within
|
|
*
|
|
* @this {Validator}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {string} key - caller object this
|
|
* @param {string} val - field configuration object
|
|
* @param {object} caller - field configuration object
|
|
* @return {boolean} true / false based on the outcome
|
|
*/
|
|
Validator.prototype.chkContNoUrl = function(key, val, caller){
|
|
var st = true, msg = "";
|
|
if(val.length > 0 && val.match(/((http|https|ftp|ftps) *\: *\/\/|www *\.)+ *[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/gi)){
|
|
msg = this.prepError(caller, "chkContNoUrl");
|
|
st = false;
|
|
}
|
|
this.logThis("chkContNoUrl", (msg?msg:"ok"));
|
|
return st;
|
|
};
|
|
|
|
return Validator;
|
|
})();
|
|
|
|
})(); |