diff --git a/.gitignore b/.gitignore index 06ab436..3ecc873 100644 --- a/.gitignore +++ b/.gitignore @@ -222,5 +222,8 @@ pip-log.txt #Mr Developer .mr.developer.cfg + +# Lock files +package-lock.json yarn-error.log yarn.lock \ No newline at end of file diff --git a/.npmignore b/.npmignore index 9a1941d..124e1e6 100644 --- a/.npmignore +++ b/.npmignore @@ -7,5 +7,6 @@ templates/ app.js gulpfile.js index.html +package-lock.json yarn-error.log yarn.lock \ No newline at end of file diff --git a/bower.json b/bower.json index c18636e..2a95ccc 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-validation-ghiscoding", - "version": "1.5.21", + "version": "1.5.28", "author": "Ghislain B.", "description": "Angular-Validation Directive and Service (ghiscoding)", "main": [ diff --git a/changelog.txt b/changelog.txt index 0a4aea3..4bc5352 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,12 @@ Angular-Validation change logs +1.5.28 (2019-06-20) Merged PR #183, #184 fixes #185 Issue while de-registering a watcher and field level validateOnEmpty +1.5.27 (2019-04-14) Merged PR #182 to fix Radio button required field validation not working, closes #181 +1.5.26 (2018-11-13) Merged PR #178 to fix revalidateAndAttachOnBlur method to handle zeroes appropriately +1.5.25 (2018-10-29) Add Chinese locale "cn.json" in the locales folder. +1.5.24 (2017-09-01) Fix #160, validate on empty not working in angular-service +1.5.23 (2017-08-17) Merged PR #162 and #163 +1.5.22 (2017-06-07) Merged PR #157 to add Simplified Chinese locale. 1.5.21 (2017-05-14) Fix #151 validation rule "different" disables rule "required". 1.5.20 (2017-04-20) Add an unminified version and Fix #153 bug in validation service. 1.5.19 (2017-04-17) Fix #150 angularValidation.revalidate problems diff --git a/dist/angular-validation.js b/dist/angular-validation.js index 124ef27..b9139bc 100644 --- a/dist/angular-validation.js +++ b/dist/angular-validation.js @@ -2,9 +2,9 @@ * Angular-Validation Directive and Service (ghiscoding) * http://github.com/ghiscoding/angular-validation * @author: Ghislain B. - * @version: 1.5.21 + * @version: 1.5.28 * @license: MIT - * @build: Sun May 14 2017 23:35:23 GMT-0400 (Eastern Daylight Time) + * @build: Thu Jun 20 2019 21:18:15 GMT-0400 (Eastern Daylight Time) */ /** * Angular-Validation Directive (ghiscoding) @@ -187,7 +187,7 @@ } // invalidate field before doing any validation - if(!!value || commonObj.isFieldRequired() || _validateOnEmpty) { + if((value !== "" && value !== null && typeof value !== "undefined") || commonObj.isFieldRequired() || _validateOnEmpty) { ctrl.$setValidity('validation', false); } @@ -411,7 +411,9 @@ /** Re-evaluate the element and revalidate it, also re-attach the onBlur event on the element */ function revalidateAndAttachOnBlur() { // Revalidate the input when enabled (without displaying the error) - var value = ctrl.$modelValue || ''; + var value = ctrl.$modelValue !== null && typeof ctrl.$modelValue !== 'undefined' + ? ctrl.$modelValue + : ''; if(!Array.isArray(value)) { ctrl.$setValidity('validation', commonObj.validate(value, false)); } @@ -505,6 +507,7 @@ angular // list of available published public functions of this object validationCommon.prototype.addToValidationSummary = addToValidationSummary; // add an element to the $validationSummary validationCommon.prototype.arrayFindObject = arrayFindObject; // search an object inside an array of objects + validationCommon.prototype.arrayRemoveObject = arrayRemoveObject; // search an object inside an array of objects and remove it from array validationCommon.prototype.defineValidation = defineValidation; // define our validation object validationCommon.prototype.getFormElementByName = getFormElementByName; // get the form element custom object by it's name validationCommon.prototype.getFormElements = getFormElements; // get the array of form elements (custom objects) @@ -617,7 +620,7 @@ angular self = analyzeElementAttributes(self); // get the rules(or validation), inside directive it's named (validation), inside service(rules) - var rules = self.validatorAttrs.rules || self.validatorAttrs.validation; + var rules = self.validatorAttrs.rules || self.validatorAttrs.validation || ''; // We first need to see if the validation holds a custom user regex, if it does then deal with it first // So why deal with it separately? Because a Regex might hold pipe '|' and so we don't want to mix it with our regular validation pipe @@ -1210,6 +1213,25 @@ angular return null; } + /** Quick function to remove an object inside an array by it's given field name and value, return and remove the object found or null + * @param Array sourceArray + * @param string searchId: search property id + * @param string searchValue: value to search + * @return object found from source array or null + */ + function arrayRemoveObject(sourceArray, searchId, searchValue) { + if (!!sourceArray) { + for (var i = 0; i < sourceArray.length; i++) { + if (sourceArray[i][searchId] === searchValue) { + var itemToRemove = sourceArray[i]; + sourceArray.splice(i,1); + return itemToRemove; + } + } + } + return null; + } + /** Quick function to find all object(s) inside an array of objects by it's given field name and value, return array of object found(s) or empty array * @param Array sourceArray * @param string searchId: search property id @@ -1255,7 +1277,7 @@ angular var formName = (!!formObj) ? formObj.getAttribute("name") : null; if (!!formObj && !!formName) { - parentForm = (!!_globalOptions && !!_globalOptions.controllerAs && formName.indexOf('.') >= 0) + var parentForm = (!!_globalOptions && !!_globalOptions.controllerAs && formName.indexOf('.') >= 0) ? objectFindById(self.scope, formName, '.') : self.scope[formName]; @@ -2842,18 +2864,14 @@ angular attrs.name = attrs.elmName; // user could pass his own scope, useful in a case of an isolate scope - if (!!self.validationAttrs.isolatedScope) { - var tempValidationOptions = scope.$validationOptions || null; // keep global validationOptions - scope = self.validationAttrs.isolatedScope; // rewrite original scope + if (!!self.validationAttrs.isolatedScope || attrs.isolatedScope) { + var tempValidationOptions = scope.$validationOptions || null; // keep global validationOptions + scope = self.validationAttrs.isolatedScope || attrs.isolatedScope; // rewrite original scope if(!!tempValidationOptions) { - scope.$validationOptions = tempValidationOptions; // reuse the validationOption from original scope + scope.$validationOptions = tempValidationOptions; // reuse the validationOption from original scope } } - // Possible element attributes - _validationCallback = (self.validationAttrs.hasOwnProperty('validationCallback')) ? self.validationAttrs.validationCallback : null; - _validateOnEmpty = (self.validationAttrs.hasOwnProperty('validateOnEmpty')) ? self.commonObj.parseBool(self.validationAttrs.validateOnEmpty) : !!_globalOptions.validateOnEmpty; - // onBlur make validation without waiting attrs.elm.bind('blur', _blurHandler = function(event) { // get the form element custom object and use it after @@ -2864,7 +2882,7 @@ angular self.commonObj.initialize(scope, attrs.elm, attrs, attrs.ctrl); // attempt to validate & run validation callback if user requested it - var validationPromise = attemptToValidate(self, event.target.value, 0); + var validationPromise = attemptToValidate(self, (attrs.ctrl.$modelValue == undefined ? '' : attrs.ctrl.$modelValue), 0); if(!!_validationCallback) { self.commonObj.runValidationCallbackOnPromise(validationPromise, _validationCallback); } @@ -2875,6 +2893,10 @@ angular // so the position inside the mergeObject call is very important attrs = self.commonObj.mergeObjects(self.validationAttrs, attrs); + // Possible element attributes + _validationCallback = (attrs.hasOwnProperty('validationCallback')) ? attrs.validationCallback : null; + _validateOnEmpty = (attrs.hasOwnProperty('validateOnEmpty')) ? self.commonObj.parseBool(attrs.validateOnEmpty) : !!_globalOptions.validateOnEmpty; + // watch the `disabled` attribute for changes // if it become disabled then skip validation else it becomes enable then we need to revalidate it watchNgDisabled(self, scope, attrs); @@ -3088,9 +3110,12 @@ angular // pre-validate without any events just to pre-fill our validationSummary with all field errors // passing false as 2nd argument for not showing any errors on screen self.commonObj.validate(value, false); - + + // check field level setting for validateOnEmpty + var isFieldValidateOnEmpty = (self.commonObj.validatorAttrs && self.commonObj.validatorAttrs.validateOnEmpty); + // if field is not required and his value is empty, cancel validation and exit out - if(!self.commonObj.isFieldRequired() && !_validateOnEmpty && (value === "" || value === null || typeof value === "undefined")) { + if(!self.commonObj.isFieldRequired() && !(_validateOnEmpty || isFieldValidateOnEmpty) && (value === "" || value === null || typeof value === "undefined")) { cancelValidation(self, formElmObj); deferred.resolve({ isFieldValid: true, formElmObj: formElmObj, value: value }); return deferred.promise; @@ -3245,7 +3270,7 @@ angular var foundWatcher = self.commonObj.arrayFindObject(_watchers, 'elmName', formElmObj.fieldName); if(!!foundWatcher) { foundWatcher.watcherHandler(); // deregister the watch by calling his handler - _watchers.shift(); + self.commonObj.arrayRemoveObject(_watchers, 'elmName', formElmObj.fieldName); } // make the validation cancelled so it won't get called anymore in the blur eventHandler @@ -3328,7 +3353,7 @@ angular attrs.elm.bind('blur', _blurHandler = function(event) { if (!!formElmObj && !formElmObj.isValidationCancelled) { // attempt to validate & run validation callback if user requested it - var validationPromise = attemptToValidate(self, event.target.value, 10); + var validationPromise = attemptToValidate(self, (attrs.ctrl.$modelValue == undefined ? '' : attrs.ctrl.$modelValue), 10); if(!!_validationCallback) { self.commonObj.runValidationCallbackOnPromise(validationPromise, _validationCallback); } @@ -3350,4 +3375,4 @@ angular }); } -}]); // ValidationService \ No newline at end of file +}]); // ValidationService diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index 45b6cd1..7d230ae 100644 --- a/dist/angular-validation.min.js +++ b/dist/angular-validation.min.js @@ -2,11 +2,11 @@ * Angular-Validation Directive and Service (ghiscoding) * http://github.com/ghiscoding/angular-validation * @author: Ghislain B. - * @version: 1.5.21 + * @version: 1.5.28 * @license: MIT - * @build: Sun May 14 2017 23:35:23 GMT-0400 (Eastern Daylight Time) + * @build: Thu Jun 20 2019 21:18:15 GMT-0400 (Eastern Daylight Time) */ -angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$q","$timeout","ValidationCommon",function(a,e,i){return{restrict:"A",require:"ngModel",link:function(n,t,r,l){function o(i,r){var o=a.defer(),d=!1,m="undefined"!=typeof r?r:$.typingLimit,s=$.getFormElementByName(l.$name);if(Array.isArray(i)){if(O=[],h="",m=0,i.length>0)return"function"==typeof s.ctrl.$setTouched&&s.ctrl.$setTouched(),u(i,typeof i);m=0}return i&&i.badInput?c():($.validate(i,!1),$.isFieldRequired()||F||""!==i&&null!==i&&"undefined"!=typeof i?(s&&(s.isValidationCancelled=!1),(i||$.isFieldRequired()||F)&&l.$setValidity("validation",!1),"SELECT"===t.prop("tagName").toUpperCase()?(d=$.validate(i,!0),l.$setValidity("validation",d),o.resolve({isFieldValid:d,formElmObj:s,value:i}),o.promise):("undefined"!=typeof i&&(0===r?(d=$.validate(i,!0),n.$evalAsync(l.$setValidity("validation",d)),o.resolve({isFieldValid:d,formElmObj:s,value:i}),e.cancel(b)):($.updateErrorMsg(""),e.cancel(b),b=e(function(){d=$.validate(i,!0),n.$evalAsync(l.$setValidity("validation",d)),o.resolve({isFieldValid:d,formElmObj:s,value:i})},m))),o.promise)):(f(),o.resolve({isFieldValid:!0,formElmObj:s,value:i}),o.promise))}function d(a,e,i){var n=o(a,0);n&&"function"==typeof n.then&&(O.push(n),parseInt(e)===i-1&&O.forEach(function(a){a.then(function(a){switch(A){case"all":a.isFieldValid===!1&&a.formElmObj.translatePromise.then(function(e){h.length>0&&g.displayOnlyLastErrorMsg?h="["+a.value+"] :: "+(a.formElmObj.validator&&a.formElmObj.validator.params?String.format(e,a.formElmObj.validator.params):e):h+=" ["+a.value+"] :: "+(a.formElmObj.validator&&a.formElmObj.validator.params?String.format(e,a.formElmObj.validator.params):e),$.updateErrorMsg(h,{isValid:!1}),$.addToValidationSummary(a.formElmObj,h)});break;case"one":default:a.isFieldValid===!0&&(l.$setValidity("validation",!0),f())}})}))}function m(a){var e=$.getFormElementByName(l.$name),i="undefined"!=typeof l.$modelValue?l.$modelValue:a.target.value;if(e&&e.hasOwnProperty("isValidationCancelled")){var n=o(i,0);w&&$.runValidationCallbackOnPromise(n,w)}else l.$setValidity("validation",!0)}function u(a,e){var i=a.length;if("string"===e)for(var n in a)d(a[n],n,i);else if("object"===e)for(var n in a)if(a.hasOwnProperty(n)){var t=a[n];for(var r in t)if(t.hasOwnProperty(r)){if(C&&r!==C)continue;d(t[r],n,i)}}}function s(){f(),$.removeFromValidationSummary(j);var a=$.arrayFindObject(E,"elmName",l.$name);if(a&&"function"==typeof a.watcherHandler){a.watcherHandler();E.shift()}}function f(){var a=$.getFormElementByName(l.$name);a&&(a.isValidationCancelled=!0),e.cancel(b),$.updateErrorMsg(""),l.$setValidity("validation",!0),V()}function v(){return n.$watch(function(){var a=l.$modelValue;if(y())return{badInput:!0};if(C&&Array.isArray(a)&&0===a.length&&Object.keys(a).length>0){var e=[],i={};return i[C]=a[C],e.push(i),e}return a},function(a,e){if(a&&a.badInput)return V(),c();var i=o(a);w&&$.runValidationCallbackOnPromise(i,w)},!0)}function c(){e.cancel(b);var a=$.getFormElementByName(l.$name);$.updateErrorMsg("INVALID_KEY_CHAR",{isValid:!1,translate:!0}),$.addToValidationSummary(a,"INVALID_KEY_CHAR",!0)}function y(){return!!t.prop("validity")&&t.prop("validity").badInput===!0}function p(){var a=l.$modelValue||"";Array.isArray(a)||l.$setValidity("validation",$.validate(a,!1));var e=$.getFormElementByName(l.$name);e&&(e.isValidationCancelled=!1),V(),t.bind("blur",m)}function V(){"function"==typeof m&&t.unbind("blur",m)}var b,$=new i(n,t,r,l),h="",O=[],E=[],g=$.getGlobalOptions(),j=r.name,w=r.hasOwnProperty("validationCallback")?r.validationCallback:null,F=r.hasOwnProperty("validateOnEmpty")?$.parseBool(r.validateOnEmpty):!!g.validateOnEmpty,A=r.hasOwnProperty("validArrayRequireHowMany")?r.validArrayRequireHowMany:"one",C=r.hasOwnProperty("validationArrayObjprop")?r.validationArrayObjprop:null;E.push({elmName:j,watcherHandler:v()}),r.$observe("disabled",function(a){var e=""===a||("boolean"==typeof a?a:"undefined"!=typeof a&&n.$eval(a));e===!0?(f(),$.removeFromValidationSummary(j)):p()}),t.on("$destroy",function(){s()}),n.$watch(function(){return t.attr("validation")},function(a){if("undefined"==typeof a||""===a)s();else{$.defineValidation(),p();var e=$.arrayFindObject(E,"elmName",l.$name);e||E.push({elmName:j,watcherHandler:v()})}}),t.bind("blur",m),n.$on("angularValidation.revalidate",function(a,e){if(e==l.$name){l.revalidateCalled=!0;var i=l.$modelValue,n=$.getFormElementByName(l.$name);if(n&&n.hasOwnProperty("isValidationCancelled")){var t=o(i);w&&$.runValidationCallbackOnPromise(t,w)}else l.$setValidity("validation",!0)}})}}}]); -angular.module("ghiscoding.validation").factory("ValidationCommon",["$rootScope","$timeout","$translate","ValidationRules",function(e,t,a,r){function n(e,t,r){if("undefined"!=typeof e&&null!=e){var n=e.ctrl&&e.ctrl.$name?e.ctrl.$name:e.attrs&&e.attrs.name?e.attrs.name:e.elm.attr("name"),i=R(n,e),o=E(Q,"field",n);if(o>=0&&""===t)Q.splice(o,1);else if(""!==t){r&&(t=a.instant(t));var l=e.attrs&&e.friendlyName?a.instant(e.friendlyName):"",s={field:n,friendlyName:l,message:t,formName:i?i.$name:null};o>=0?Q[o]=s:Q.push(s)}if(e.scope.$validationSummary=Q,i&&(i.$validationSummary=A(Q,"formName",i.$name)),K&&K.controllerAs&&(K.controllerAs.$validationSummary=Q,i&&i.$name)){var u=i.$name.indexOf(".")>=0?i.$name.split(".")[1]:i.$name,p=K.controllerAs&&K.controllerAs[u]?K.controllerAs[u]:"undefined"!=typeof e.elm.controller()?e.elm.controller()[u]:null;p&&(p.$validationSummary=A(Q,"formName",i.$name))}return Q}}function i(){var e=this,t={};e.validators=[],e=S(e);var a=e.validatorAttrs.rules||e.validatorAttrs.validation;if(a.indexOf("pattern=/")>=0){var n=a.match(/pattern=(\/(?:(?!:alt).)*\/[igm]*)(:alt=(.*))?/);if(!n||n.length<3)throw'Regex validator within the validation needs to be define with an opening "/" and a closing "/", please review your validator.';var i=n[1],o=n[2]?n[2].replace(/\|(.*)/,""):"",l=i.match(new RegExp("^/(.*?)/([gimy]*)$")),s=new RegExp(l[1],l[2]);t={altMsg:o,message:o.replace(/:alt=/,""),pattern:s},a=a.replace("pattern="+i,"pattern")}else if(a.indexOf("regex:")>=0){var n=a.match("regex:(.*?):regex");if(n.length<2)throw'Regex validator within the validation needs to be define with an opening "regex:" and a closing ":regex", please review your validator.';var u=n[1].split(":=");t={message:u[0],pattern:u[1]},a=a.replace(n[0],"regex:")}var p=a.split("|");if(p){e.bFieldRequired=a.indexOf("required")>=0;for(var d=0,m=p.length;d=0,g=[];f?(g=p[d].substring(0,c-1).split(":"),g.push(p[d].substring(c))):g=p[d].split(":"),e.validators[d]=r.getElementValidators({altText:f===!0?2===g.length?g[1]:g[2]:"",customRegEx:t,rule:g[0],ruleParams:f&&2===g.length?null:g[1]})}}return e}function o(e){return w(z,"fieldName",e)}function l(e){return e?A(z,"formName",e):z}function s(){return K}function u(e,t,a,r){this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,$(t,a,r,e),this.defineValidation()}function p(){var e=this;return e.bFieldRequired}function d(e,t){var a={};for(var r in e)a[r]=e[r];for(var r in t)a[r]=t[r];return a}function m(e){var t=E(z,"fieldName",e);t>=0&&z.splice(t,1)}function c(e,t){var a=this,r=R(e,a),n=t||Q,i=E(n,"field",e);if(i>=0&&n.splice(i,1),i=E(Q,"field",e),i>=0&&Q.splice(i,1),a.scope.$validationSummary=Q,r&&(r.$validationSummary=A(Q,"formName",r.$name)),K&&K.controllerAs&&(K.controllerAs.$validationSummary=Q,r)){var o=r.$name.indexOf(".")>=0?r.$name.split(".")[1]:r.$name;K.controllerAs[o]&&(K.controllerAs[o].$validationSummary=A(Q,"formName",r.$name))}return Q}function f(e,t){var a;if(/\({1}.*\){1}/gi.test(t))a=e.scope.$eval(t);else{var r=N(e.scope,t,".");"function"==typeof r&&(a=r())}return a}function g(e,t){var a=this;"function"==typeof e.then&&e.then(function(){f(a,t)})}function v(e){K.displayOnlyLastErrorMsg=e}function y(e){var t=this;return K=d(K,e),t}function h(e,t){var r=this;t&&t.obj&&(r=t.obj,r.validatorAttrs=t.obj.attrs);var n=t&&t.elm?t.elm:r.elm,i=n&&n.attr("name")?n.attr("name"):null;if("undefined"==typeof i||null===i){var o=n?n.attr("ng-model"):"unknown";throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+o+'"'}var l=t&&t.translate?a.instant(e):e;l=l.trim();var s=i.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,"").replace(/\./g,"-"),u=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var p=r.validatorAttrs.validationErrorTo.charAt(0),d="."===p||"#"===p?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;u=angular.element(document.querySelector(d))}u&&0!==u.length||(u=angular.element(document.querySelector(".validation-"+s)));var m=!(!t||!t.isSubmitted)&&t.isSubmitted;!K.hideErrorUnderInputs&&t&&!t.isValid&&(m||r.ctrl.$dirty||r.ctrl.$touched||r.ctrl.revalidateCalled)?(u.length>0?u.html(l):n.after('
'+l+"
"),r.ctrl.isErrorMessageVisible=!0):(u.html(""),r.ctrl.isErrorMessageVisible=void 0)}function b(e,t){var r,i=this,l=!0,s=!0,u=0,p={message:""};"undefined"==typeof e&&(e="");for(var d=i.ctrl&&i.ctrl.$name?i.ctrl.$name:i.attrs&&i.attrs.name?i.attrs.name:i.elm.attr("name"),m=o(d),c=i.validatorAttrs.rules||i.validatorAttrs.validation,f=0,g=i.validators.length;f0&&(o=n.altText.replace("alt=",""));var u=a(o);e.translatePromise=u,e.validator=n,u.then(function(a){p.message.length>0&&K.displayOnlyLastErrorMsg?p.message=l+(n&&n.params?String.format(a,n.params):a):p.message+=l+(n&&n.params?String.format(a,n.params):a),O(i,e,p.message,s,t)})["catch"](function(a){if(!(n.altText&&n.altText.length>0))throw String.format("Could not translate: '{0}'. Please check your Angular-Translate $translateProvider configuration.",a);p.message.length>0&&K.displayOnlyLastErrorMsg?p.message=l+o:p.message+=l+o,O(i,e,p.message,s,t)})}(m,l,r)),l&&u++,i.validRequireHowMany==u&&l){s=!0;break}}return l&&(n(i,""),i.updateErrorMsg("",{isValid:l})),m&&(m.isValid=s,s&&(m.message="")),s}function $(e,t,r,n){var i=t.name?t.name:e.attr("name"),o=R(i,{scope:n}),l=t&&t.friendlyName?a.instant(t.friendlyName):"",s={fieldName:i,friendlyName:l,elm:e,attrs:t,ctrl:r,scope:n,isValid:!1,message:"",formName:o?o.$name:null},u=E(z,"fieldName",e.attr("name"));return u>=0?z[u]=s:z.push(s),z}function O(e,t,a,r,i){a=a.trim(),t&&t.isValidationCancelled===!0&&(a=""),(K.preValidateValidationSummary||"undefined"==typeof K.preValidateValidationSummary||i)&&n(t,a),(e.validatorAttrs.preValidateFormElements||K.preValidateFormElements)&&(t&&"function"==typeof e.ctrl.$setTouched&&t.ctrl.$setTouched(),e.ctrl.$dirty===!1&&h(a,{isSubmitted:!0,isValid:r,obj:t})),i&&t&&!t.isValid?e.updateErrorMsg(a,{isValid:r,obj:t}):t&&t.isValid&&n(t,"")}function S(e){return e.typingLimit=J,e.validatorAttrs.hasOwnProperty("debounce")?e.typingLimit=parseInt(e.validatorAttrs.debounce,10):e.validatorAttrs.hasOwnProperty("typingLimit")?e.typingLimit=parseInt(e.validatorAttrs.typingLimit,10):K&&K.hasOwnProperty("debounce")&&(e.typingLimit=parseInt(K.debounce,10)),e.validRequireHowMany=e.validatorAttrs.hasOwnProperty("validRequireHowMany")?e.validatorAttrs.validRequireHowMany:K.validRequireHowMany,W=e.validatorAttrs.hasOwnProperty("validateOnEmpty")?T(e.validatorAttrs.validateOnEmpty):K.validateOnEmpty,e}function w(e,t,a){if(e)for(var r=0;r=0?N(t.scope,a,"."):t.scope[a],parentForm)?("undefined"==typeof parentForm.$name&&(parentForm.$name=a),parentForm):null}function R(e,t){if(K&&K.formName){var a=document.querySelector('[name="'+K.formName+'"]');if(a)return a.$name=K.formName,a}for(var r=document.getElementsByName(e),a=null,n=0;n=0){var p=s.split(".");return t.scope[p[0]][p[1]]=u}return t.scope[s]=u}}return null}function x(e){return!isNaN(parseFloat(e))&&isFinite(e)}function N(e,t,a){for(var r=a?t.split(a):t,n=0,i=r.length;n8?e.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":a=e.substring(0,8),r=e.substring(2,3),n=k(a,r),s=n[0],l=n[1],o=parseInt(n[2])<50?"20"+n[2]:"19"+n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":a=e.substring(0,10),r=e.substring(2,3),n=k(a,r),l=n[0],s=n[1],o=n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":a=e.substring(0,8),r=e.substring(2,3),n=k(a,r),l=n[0],s=n[1],o=parseInt(n[2])<50?"20"+n[2]:"19"+n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"ISO":default:a=e.substring(0,10),r=e.substring(4,5),n=k(a,r),o=n[0],l=n[1],s=n[2],i=e.length>10?e.substring(11).split(":"):null}var u=i&&3===i.length?i[0]:0,p=i&&3===i.length?i[1]:0,d=i&&3===i.length?i[2]:0;return new Date(o,l-1,s,u,p,d)}function q(e){e&&(K={displayOnlyLastErrorMsg:!1,errorMessageSeparator:" ",hideErrorUnderInputs:!1,preValidateFormElements:!1,preValidateValidationSummary:!0,isolatedScope:null,scope:null,validateOnEmpty:!1,validRequireHowMany:"all",resetGlobalOptionsOnRouteChange:!0},z=[],Q=[])}function k(e,t){var a=[];switch(t){case"/":a=e.split("/");break;case".":a=e.split(".");break;case"-":default:a=e.split("-")}return a}function M(e,t,a){var r=!1;switch(e){case"<":r=t":r=t>a;break;case">=":r=t>=a;break;case"!=":case"<>":r=t!=a;break;case"!==":r=t!==a;break;case"=":case"==":r=t==a;break;case"===":r=t===a;break;default:r=!1}return r}function C(){Element.prototype.closest=function(e){var t,a=(this.document||this.ownerDocument).querySelectorAll(e),r=this;do for(t=a.length;--t>=0&&a.item(t)!==r;);while(t<0&&(r=r.parentElement));return r}}function L(){return this.replace(/^\s+|\s+$/g,"")}function U(){var e=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(t,a){return"undefined"!=typeof e[a]?e[a]:t})}function P(e){var t=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return e.replace(/{(\d+)}/g,function(e,a){return"undefined"!=typeof t[a]?t[a]:e})}function j(e,t,a){var r=!0,n=r=!1;if(e instanceof Date)n=!0;else{var i=new RegExp(t.pattern,t.patternFlag);n=!((!t.pattern||"/\\S+/"===t.pattern.toString()||a&&"required"===t.pattern)&&null===e)&&i.test(e)}if(n){var o=t.dateType,l=e instanceof Date?e:F(e,o).getTime();if(2==t.params.length){var s=F(t.params[0],o).getTime(),u=F(t.params[1],o).getTime(),p=M(t.condition[0],l,s),d=M(t.condition[1],l,u);r=p&&d}else{var m=F(t.params[0],o).getTime();r=M(t.condition,l,m)}}return r}function G(e,t){var a=!0;if(2==t.params.length){var r=M(t.condition[0],parseFloat(e),parseFloat(t.params[0])),n=M(t.condition[1],parseFloat(e),parseFloat(t.params[1]));a=r&&n}else a=M(t.condition,parseFloat(e),parseFloat(t.params[0]));return a}function D(e,a,r,n,i,o){var l=!0,s="Custom Javascript Validation requires an error message defined as 'alt=' in your validator or defined in your custom javascript function as { isValid: bool, message: 'your error' }",u="Custom Javascript Validation requires a declared function (in your Controller), please review your code.";if(e||W){var p=a.params[0],d=f(r,p);if("boolean"==typeof d)l=!!d;else{if("object"!=typeof d)throw u;l=!!d.isValid}if(l===!1?(n.isValid=!1,t(function(){var e=o.message+" ";if(d.message&&(e+=d.message||a.altText)," "===e&&a.altText&&(e+=a.altText)," "===e)throw s;O(r,n,e,!1,i)})):l===!0&&(n.isValid=!0,O(r,n,"",!0,i)),"undefined"==typeof d)throw u}return l}function H(e,t,r,n){var i=!0,l=t.params[0],s=r.scope.$eval(l),u=angular.element(document.querySelector('[name="'+l+'"]')),p=t,d=r.ctrl,m=o(r.ctrl.$name);return i=!((!t.pattern||"/\\S+/"===t.pattern.toString()||rules&&"required"===t.pattern)&&null===e)&&(M(t.condition,e,s)&&!!e),u&&u.attr("friendly-name")?t.params[1]=u.attr("friendly-name"):t.params.length>1&&(t.params[1]=t.params[1]),r.scope.$watch(l,function(i,o){var l=!((!t.pattern||"/\\S+/"===t.pattern.toString()||rules&&"required"===t.pattern)&&null===e)&&(M(t.condition,e,s)&&!!e);if(i!==o){if(l)O(r,m,"",!0,!0);else{m.isValid=!1;var u=p.message;p.altText&&p.altText.length>0&&(u=p.altText.replace("alt=","")),a(u).then(function(e){var t=K.errorMessageSeparator||" ";n.message=t+(p&&p.params?String.format(e,p.params):e),O(r,m,n.message,l,!0)})}d.$setValidity("validation",l)}},!0),i}function I(e,t,a,r,n,i){var o=!0,l="Remote Javascript Validation requires an error message defined as 'alt=' in your validator or defined in your custom remote function as { isValid: bool, message: 'your error' }",s="Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";if(e&&n||W){a.ctrl.$processing=!0;var u=t.params[0],p=f(a,u);if(Y.length>1)for(;Y.length>0;){var d=Y.pop();d&&"function"==typeof d.abort&&d.abort()}if(Y.push(p),!p||"function"!=typeof p.then)throw s;a.ctrl.$setValidity("remote",!1),function(e){p.then(function(t){t=t.data||t,Y.pop(),a.ctrl.$processing=!1;var u=i.message+" ";if("boolean"==typeof t)o=!!t;else{if("object"!=typeof t)throw s;o=!!t.isValid}if(o===!1){if(r.isValid=!1,u+=t.message||e," "===u)throw l;O(a,r,u,!1,n)}else o===!0&&(r.isValid=!0,a.ctrl.$setValidity("remote",!0),O(a,r,"",!0,n))})}(t.altText)}return o}function B(e,t,a,r){var n=!0,i=r.attrs?r.attrs.ngDisabled:r.validatorAttrs.ngDisabled,o=r.elm.prop("disabled"),l=""===o||("boolean"==typeof o?o:"undefined"!=typeof o&&r.scope.$eval(o)),s=""===i||("boolean"==typeof i?i:"undefined"!=typeof i&&r.scope.$eval(i));if(l||s)n=!0;else if("string"==typeof e&&""===e&&r.elm.prop("type")&&"NUMBER"===r.elm.prop("type").toUpperCase())n=!1;else{var u=new RegExp(t.pattern,t.patternFlag);n=!((!t.pattern||"/\\S+/"===t.pattern.toString()||a&&"required"===t.pattern)&&null===e)&&u.test(e)}return n}function _(e,t){return x(t)?{condition:e.conditionNum,message:e.messageNum,params:e.params,type:"conditionalNumber"}:{pattern:e.patternLength,message:e.messageLength,params:e.params,type:"regex"}}var J=1e3,z=[],K={resetGlobalOptionsOnRouteChange:!0},Y=[],Q=[],W=!1;e.$on("$routeChangeStart",function(e,t,a){q(K.resetGlobalOptionsOnRouteChange)}),e.$on("$stateChangeStart",function(e,t,a){q(K.resetGlobalOptionsOnRouteChange)});var X=function(e,t,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=J,this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,this.validateOnEmpty=!1,this.validRequireHowMany="all",e&&e.$validationOptions&&(K=e.$validationOptions),e&&(K.isolatedScope||K.scope)&&(this.scope=K.isolatedScope||K.scope,K=d(e.$validationOptions,K)),"undefined"==typeof K.resetGlobalOptionsOnRouteChange&&(K.resetGlobalOptionsOnRouteChange=!0),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&($(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return X.prototype.addToValidationSummary=n,X.prototype.arrayFindObject=w,X.prototype.defineValidation=i,X.prototype.getFormElementByName=o,X.prototype.getFormElements=l,X.prototype.getGlobalOptions=s,X.prototype.isFieldRequired=p,X.prototype.initialize=u,X.prototype.mergeObjects=d,X.prototype.parseBool=T,X.prototype.removeFromValidationSummary=c,X.prototype.removeFromFormElementObjectList=m,X.prototype.runValidationCallbackOnPromise=g,X.prototype.setDisplayOnlyLastErrorMsg=v,X.prototype.setGlobalOptions=y,X.prototype.updateErrorMsg=h,X.prototype.validate=b,window.Element&&!Element.prototype.closest&&(Element.prototype.closest=C),String.prototype.trim=L,String.prototype.format=U,String.format=P,X}]); +angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$q","$timeout","ValidationCommon",function(a,e,i){return{restrict:"A",require:"ngModel",link:function(n,t,r,l){function o(i,r){var o=a.defer(),d=!1,m="undefined"!=typeof r?r:$.typingLimit,s=$.getFormElementByName(l.$name);if(Array.isArray(i)){if(O=[],h="",m=0,i.length>0)return"function"==typeof s.ctrl.$setTouched&&s.ctrl.$setTouched(),u(i,typeof i);m=0}return i&&i.badInput?c():($.validate(i,!1),$.isFieldRequired()||F||""!==i&&null!==i&&"undefined"!=typeof i?(s&&(s.isValidationCancelled=!1),(""!==i&&null!==i&&"undefined"!=typeof i||$.isFieldRequired()||F)&&l.$setValidity("validation",!1),"SELECT"===t.prop("tagName").toUpperCase()?(d=$.validate(i,!0),l.$setValidity("validation",d),o.resolve({isFieldValid:d,formElmObj:s,value:i}),o.promise):("undefined"!=typeof i&&(0===r?(d=$.validate(i,!0),n.$evalAsync(l.$setValidity("validation",d)),o.resolve({isFieldValid:d,formElmObj:s,value:i}),e.cancel(b)):($.updateErrorMsg(""),e.cancel(b),b=e(function(){d=$.validate(i,!0),n.$evalAsync(l.$setValidity("validation",d)),o.resolve({isFieldValid:d,formElmObj:s,value:i})},m))),o.promise)):(f(),o.resolve({isFieldValid:!0,formElmObj:s,value:i}),o.promise))}function d(a,e,i){var n=o(a,0);n&&"function"==typeof n.then&&(O.push(n),parseInt(e)===i-1&&O.forEach(function(a){a.then(function(a){switch(A){case"all":a.isFieldValid===!1&&a.formElmObj.translatePromise.then(function(e){h.length>0&&g.displayOnlyLastErrorMsg?h="["+a.value+"] :: "+(a.formElmObj.validator&&a.formElmObj.validator.params?String.format(e,a.formElmObj.validator.params):e):h+=" ["+a.value+"] :: "+(a.formElmObj.validator&&a.formElmObj.validator.params?String.format(e,a.formElmObj.validator.params):e),$.updateErrorMsg(h,{isValid:!1}),$.addToValidationSummary(a.formElmObj,h)});break;case"one":default:a.isFieldValid===!0&&(l.$setValidity("validation",!0),f())}})}))}function m(a){var e=$.getFormElementByName(l.$name),i="undefined"!=typeof l.$modelValue?l.$modelValue:a.target.value;if(e&&e.hasOwnProperty("isValidationCancelled")){var n=o(i,0);w&&$.runValidationCallbackOnPromise(n,w)}else l.$setValidity("validation",!0)}function u(a,e){var i=a.length;if("string"===e)for(var n in a)d(a[n],n,i);else if("object"===e)for(var n in a)if(a.hasOwnProperty(n)){var t=a[n];for(var r in t)if(t.hasOwnProperty(r)){if(C&&r!==C)continue;d(t[r],n,i)}}}function s(){f(),$.removeFromValidationSummary(j);var a=$.arrayFindObject(E,"elmName",l.$name);if(a&&"function"==typeof a.watcherHandler){a.watcherHandler();E.shift()}}function f(){var a=$.getFormElementByName(l.$name);a&&(a.isValidationCancelled=!0),e.cancel(b),$.updateErrorMsg(""),l.$setValidity("validation",!0),V()}function v(){return n.$watch(function(){var a=l.$modelValue;if(y())return{badInput:!0};if(C&&Array.isArray(a)&&0===a.length&&Object.keys(a).length>0){var e=[],i={};return i[C]=a[C],e.push(i),e}return a},function(a,e){if(a&&a.badInput)return V(),c();var i=o(a);w&&$.runValidationCallbackOnPromise(i,w)},!0)}function c(){e.cancel(b);var a=$.getFormElementByName(l.$name);$.updateErrorMsg("INVALID_KEY_CHAR",{isValid:!1,translate:!0}),$.addToValidationSummary(a,"INVALID_KEY_CHAR",!0)}function y(){return!!t.prop("validity")&&t.prop("validity").badInput===!0}function p(){var a=null!==l.$modelValue&&"undefined"!=typeof l.$modelValue?l.$modelValue:"";Array.isArray(a)||l.$setValidity("validation",$.validate(a,!1));var e=$.getFormElementByName(l.$name);e&&(e.isValidationCancelled=!1),V(),t.bind("blur",m)}function V(){"function"==typeof m&&t.unbind("blur",m)}var b,$=new i(n,t,r,l),h="",O=[],E=[],g=$.getGlobalOptions(),j=r.name,w=r.hasOwnProperty("validationCallback")?r.validationCallback:null,F=r.hasOwnProperty("validateOnEmpty")?$.parseBool(r.validateOnEmpty):!!g.validateOnEmpty,A=r.hasOwnProperty("validArrayRequireHowMany")?r.validArrayRequireHowMany:"one",C=r.hasOwnProperty("validationArrayObjprop")?r.validationArrayObjprop:null;E.push({elmName:j,watcherHandler:v()}),r.$observe("disabled",function(a){var e=""===a||("boolean"==typeof a?a:"undefined"!=typeof a&&n.$eval(a));e===!0?(f(),$.removeFromValidationSummary(j)):p()}),t.on("$destroy",function(){s()}),n.$watch(function(){return t.attr("validation")},function(a){if("undefined"==typeof a||""===a)s();else{$.defineValidation(),p();var e=$.arrayFindObject(E,"elmName",l.$name);e||E.push({elmName:j,watcherHandler:v()})}}),t.bind("blur",m),n.$on("angularValidation.revalidate",function(a,e){if(e==l.$name){l.revalidateCalled=!0;var i=l.$modelValue,n=$.getFormElementByName(l.$name);if(n&&n.hasOwnProperty("isValidationCancelled")){var t=o(i);w&&$.runValidationCallbackOnPromise(t,w)}else l.$setValidity("validation",!0)}})}}}]); +angular.module("ghiscoding.validation").factory("ValidationCommon",["$rootScope","$timeout","$translate","ValidationRules",function(e,t,a,r){function n(e,t,r){if("undefined"!=typeof e&&null!=e){var n=e.ctrl&&e.ctrl.$name?e.ctrl.$name:e.attrs&&e.attrs.name?e.attrs.name:e.elm.attr("name"),i=x(n,e),o=V(W,"field",n);if(o>=0&&""===t)W.splice(o,1);else if(""!==t){r&&(t=a.instant(t));var l=e.attrs&&e.friendlyName?a.instant(e.friendlyName):"",s={field:n,friendlyName:l,message:t,formName:i?i.$name:null};o>=0?W[o]=s:W.push(s)}if(e.scope.$validationSummary=W,i&&(i.$validationSummary=E(W,"formName",i.$name)),Y&&Y.controllerAs&&(Y.controllerAs.$validationSummary=W,i&&i.$name)){var u=i.$name.indexOf(".")>=0?i.$name.split(".")[1]:i.$name,p=Y.controllerAs&&Y.controllerAs[u]?Y.controllerAs[u]:"undefined"!=typeof e.elm.controller()?e.elm.controller()[u]:null;p&&(p.$validationSummary=E(W,"formName",i.$name))}return W}}function i(){var e=this,t={};e.validators=[],e=S(e);var a=e.validatorAttrs.rules||e.validatorAttrs.validation||"";if(a.indexOf("pattern=/")>=0){var n=a.match(/pattern=(\/(?:(?!:alt).)*\/[igm]*)(:alt=(.*))?/);if(!n||n.length<3)throw'Regex validator within the validation needs to be define with an opening "/" and a closing "/", please review your validator.';var i=n[1],o=n[2]?n[2].replace(/\|(.*)/,""):"",l=i.match(new RegExp("^/(.*?)/([gimy]*)$")),s=new RegExp(l[1],l[2]);t={altMsg:o,message:o.replace(/:alt=/,""),pattern:s},a=a.replace("pattern="+i,"pattern")}else if(a.indexOf("regex:")>=0){var n=a.match("regex:(.*?):regex");if(n.length<2)throw'Regex validator within the validation needs to be define with an opening "regex:" and a closing ":regex", please review your validator.';var u=n[1].split(":=");t={message:u[0],pattern:u[1]},a=a.replace(n[0],"regex:")}var p=a.split("|");if(p){e.bFieldRequired=a.indexOf("required")>=0;for(var d=0,m=p.length;d=0,g=[];f?(g=p[d].substring(0,c-1).split(":"),g.push(p[d].substring(c))):g=p[d].split(":"),e.validators[d]=r.getElementValidators({altText:f===!0?2===g.length?g[1]:g[2]:"",customRegEx:t,rule:g[0],ruleParams:f&&2===g.length?null:g[1]})}}return e}function o(e){return w(K,"fieldName",e)}function l(e){return e?E(K,"formName",e):K}function s(){return Y}function u(e,t,a,r){this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,$(t,a,r,e),this.defineValidation()}function p(){var e=this;return e.bFieldRequired}function d(e,t){var a={};for(var r in e)a[r]=e[r];for(var r in t)a[r]=t[r];return a}function m(e){var t=V(K,"fieldName",e);t>=0&&K.splice(t,1)}function c(e,t){var a=this,r=x(e,a),n=t||W,i=V(n,"field",e);if(i>=0&&n.splice(i,1),i=V(W,"field",e),i>=0&&W.splice(i,1),a.scope.$validationSummary=W,r&&(r.$validationSummary=E(W,"formName",r.$name)),Y&&Y.controllerAs&&(Y.controllerAs.$validationSummary=W,r)){var o=r.$name.indexOf(".")>=0?r.$name.split(".")[1]:r.$name;Y.controllerAs[o]&&(Y.controllerAs[o].$validationSummary=E(W,"formName",r.$name))}return W}function f(e,t){var a;if(/\({1}.*\){1}/gi.test(t))a=e.scope.$eval(t);else{var r=T(e.scope,t,".");"function"==typeof r&&(a=r())}return a}function g(e,t){var a=this;"function"==typeof e.then&&e.then(function(){f(a,t)})}function v(e){Y.displayOnlyLastErrorMsg=e}function y(e){var t=this;return Y=d(Y,e),t}function h(e,t){var r=this;t&&t.obj&&(r=t.obj,r.validatorAttrs=t.obj.attrs);var n=t&&t.elm?t.elm:r.elm,i=n&&n.attr("name")?n.attr("name"):null;if("undefined"==typeof i||null===i){var o=n?n.attr("ng-model"):"unknown";throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+o+'"'}var l=t&&t.translate?a.instant(e):e;l=l.trim();var s=i.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,"").replace(/\./g,"-"),u=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var p=r.validatorAttrs.validationErrorTo.charAt(0),d="."===p||"#"===p?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;u=angular.element(document.querySelector(d))}u&&0!==u.length||(u=angular.element(document.querySelector(".validation-"+s)));var m=!(!t||!t.isSubmitted)&&t.isSubmitted;!Y.hideErrorUnderInputs&&t&&!t.isValid&&(m||r.ctrl.$dirty||r.ctrl.$touched||r.ctrl.revalidateCalled)?(u.length>0?u.html(l):n.after('
'+l+"
"),r.ctrl.isErrorMessageVisible=!0):(u.html(""),r.ctrl.isErrorMessageVisible=void 0)}function b(e,t){var r,i=this,l=!0,s=!0,u=0,p={message:""};"undefined"==typeof e&&(e="");for(var d=i.ctrl&&i.ctrl.$name?i.ctrl.$name:i.attrs&&i.attrs.name?i.attrs.name:i.elm.attr("name"),m=o(d),c=i.validatorAttrs.rules||i.validatorAttrs.validation,f=0,g=i.validators.length;f0&&(o=n.altText.replace("alt=",""));var u=a(o);e.translatePromise=u,e.validator=n,u.then(function(a){p.message.length>0&&Y.displayOnlyLastErrorMsg?p.message=l+(n&&n.params?String.format(a,n.params):a):p.message+=l+(n&&n.params?String.format(a,n.params):a),O(i,e,p.message,s,t)})["catch"](function(a){if(!(n.altText&&n.altText.length>0))throw String.format("Could not translate: '{0}'. Please check your Angular-Translate $translateProvider configuration.",a);p.message.length>0&&Y.displayOnlyLastErrorMsg?p.message=l+o:p.message+=l+o,O(i,e,p.message,s,t)})}(m,l,r)),l&&u++,i.validRequireHowMany==u&&l){s=!0;break}}return l&&(n(i,""),i.updateErrorMsg("",{isValid:l})),m&&(m.isValid=s,s&&(m.message="")),s}function $(e,t,r,n){var i=t.name?t.name:e.attr("name"),o=x(i,{scope:n}),l=t&&t.friendlyName?a.instant(t.friendlyName):"",s={fieldName:i,friendlyName:l,elm:e,attrs:t,ctrl:r,scope:n,isValid:!1,message:"",formName:o?o.$name:null},u=V(K,"fieldName",e.attr("name"));return u>=0?K[u]=s:K.push(s),K}function O(e,t,a,r,i){a=a.trim(),t&&t.isValidationCancelled===!0&&(a=""),(Y.preValidateValidationSummary||"undefined"==typeof Y.preValidateValidationSummary||i)&&n(t,a),(e.validatorAttrs.preValidateFormElements||Y.preValidateFormElements)&&(t&&"function"==typeof e.ctrl.$setTouched&&t.ctrl.$setTouched(),e.ctrl.$dirty===!1&&h(a,{isSubmitted:!0,isValid:r,obj:t})),i&&t&&!t.isValid?e.updateErrorMsg(a,{isValid:r,obj:t}):t&&t.isValid&&n(t,"")}function S(e){return e.typingLimit=z,e.validatorAttrs.hasOwnProperty("debounce")?e.typingLimit=parseInt(e.validatorAttrs.debounce,10):e.validatorAttrs.hasOwnProperty("typingLimit")?e.typingLimit=parseInt(e.validatorAttrs.typingLimit,10):Y&&Y.hasOwnProperty("debounce")&&(e.typingLimit=parseInt(Y.debounce,10)),e.validRequireHowMany=e.validatorAttrs.hasOwnProperty("validRequireHowMany")?e.validatorAttrs.validRequireHowMany:Y.validRequireHowMany,X=e.validatorAttrs.hasOwnProperty("validateOnEmpty")?q(e.validatorAttrs.validateOnEmpty):Y.validateOnEmpty,e}function w(e,t,a){if(e)for(var r=0;r=0?T(t.scope,a,"."):t.scope[a];if(r)return"undefined"==typeof r.$name&&(r.$name=a),r}return null}function x(e,t){if(Y&&Y.formName){var a=document.querySelector('[name="'+Y.formName+'"]');if(a)return a.$name=Y.formName,a}for(var r=document.getElementsByName(e),a=null,n=0;n=0){var p=s.split(".");return t.scope[p[0]][p[1]]=u}return t.scope[s]=u}}return null}function N(e){return!isNaN(parseFloat(e))&&isFinite(e)}function T(e,t,a){for(var r=a?t.split(a):t,n=0,i=r.length;n8?e.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":a=e.substring(0,8),r=e.substring(2,3),n=M(a,r),s=n[0],l=n[1],o=parseInt(n[2])<50?"20"+n[2]:"19"+n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":a=e.substring(0,10),r=e.substring(2,3),n=M(a,r),l=n[0],s=n[1],o=n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":a=e.substring(0,8),r=e.substring(2,3),n=M(a,r),l=n[0],s=n[1],o=parseInt(n[2])<50?"20"+n[2]:"19"+n[2],i=e.length>8?e.substring(9).split(":"):null;break;case"ISO":default:a=e.substring(0,10),r=e.substring(4,5),n=M(a,r),o=n[0],l=n[1],s=n[2],i=e.length>10?e.substring(11).split(":"):null}var u=i&&3===i.length?i[0]:0,p=i&&3===i.length?i[1]:0,d=i&&3===i.length?i[2]:0;return new Date(o,l-1,s,u,p,d)}function k(e){e&&(Y={displayOnlyLastErrorMsg:!1,errorMessageSeparator:" ",hideErrorUnderInputs:!1,preValidateFormElements:!1,preValidateValidationSummary:!0,isolatedScope:null,scope:null,validateOnEmpty:!1,validRequireHowMany:"all",resetGlobalOptionsOnRouteChange:!0},K=[],W=[])}function M(e,t){var a=[];switch(t){case"/":a=e.split("/");break;case".":a=e.split(".");break;case"-":default:a=e.split("-")}return a}function C(e,t,a){var r=!1;switch(e){case"<":r=t":r=t>a;break;case">=":r=t>=a;break;case"!=":case"<>":r=t!=a;break;case"!==":r=t!==a;break;case"=":case"==":r=t==a;break;case"===":r=t===a;break;default:r=!1}return r}function L(){Element.prototype.closest=function(e){var t,a=(this.document||this.ownerDocument).querySelectorAll(e),r=this;do for(t=a.length;--t>=0&&a.item(t)!==r;);while(t<0&&(r=r.parentElement));return r}}function U(){return this.replace(/^\s+|\s+$/g,"")}function j(){var e=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(t,a){return"undefined"!=typeof e[a]?e[a]:t})}function P(e){var t=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return e.replace(/{(\d+)}/g,function(e,a){return"undefined"!=typeof t[a]?t[a]:e})}function G(e,t,a){var r=!0,n=r=!1;if(e instanceof Date)n=!0;else{var i=new RegExp(t.pattern,t.patternFlag);n=!((!t.pattern||"/\\S+/"===t.pattern.toString()||a&&"required"===t.pattern)&&null===e)&&i.test(e)}if(n){var o=t.dateType,l=e instanceof Date?e:F(e,o).getTime();if(2==t.params.length){var s=F(t.params[0],o).getTime(),u=F(t.params[1],o).getTime(),p=C(t.condition[0],l,s),d=C(t.condition[1],l,u);r=p&&d}else{var m=F(t.params[0],o).getTime();r=C(t.condition,l,m)}}return r}function D(e,t){var a=!0;if(2==t.params.length){var r=C(t.condition[0],parseFloat(e),parseFloat(t.params[0])),n=C(t.condition[1],parseFloat(e),parseFloat(t.params[1]));a=r&&n}else a=C(t.condition,parseFloat(e),parseFloat(t.params[0]));return a}function H(e,a,r,n,i,o){var l=!0,s="Custom Javascript Validation requires an error message defined as 'alt=' in your validator or defined in your custom javascript function as { isValid: bool, message: 'your error' }",u="Custom Javascript Validation requires a declared function (in your Controller), please review your code.";if(e||X){var p=a.params[0],d=f(r,p);if("boolean"==typeof d)l=!!d;else{if("object"!=typeof d)throw u;l=!!d.isValid}if(l===!1?(n.isValid=!1,t(function(){var e=o.message+" ";if(d.message&&(e+=d.message||a.altText)," "===e&&a.altText&&(e+=a.altText)," "===e)throw s;O(r,n,e,!1,i)})):l===!0&&(n.isValid=!0,O(r,n,"",!0,i)),"undefined"==typeof d)throw u}return l}function I(e,t,r,n){var i=!0,l=t.params[0],s=r.scope.$eval(l),u=angular.element(document.querySelector('[name="'+l+'"]')),p=t,d=r.ctrl,m=o(r.ctrl.$name);return i=!((!t.pattern||"/\\S+/"===t.pattern.toString()||rules&&"required"===t.pattern)&&null===e)&&(C(t.condition,e,s)&&!!e),u&&u.attr("friendly-name")?t.params[1]=u.attr("friendly-name"):t.params.length>1&&(t.params[1]=t.params[1]),r.scope.$watch(l,function(i,o){var l=!((!t.pattern||"/\\S+/"===t.pattern.toString()||rules&&"required"===t.pattern)&&null===e)&&(C(t.condition,e,s)&&!!e);if(i!==o){if(l)O(r,m,"",!0,!0);else{m.isValid=!1;var u=p.message;p.altText&&p.altText.length>0&&(u=p.altText.replace("alt=","")),a(u).then(function(e){var t=Y.errorMessageSeparator||" ";n.message=t+(p&&p.params?String.format(e,p.params):e),O(r,m,n.message,l,!0)})}d.$setValidity("validation",l)}},!0),i}function B(e,t,a,r,n,i){var o=!0,l="Remote Javascript Validation requires an error message defined as 'alt=' in your validator or defined in your custom remote function as { isValid: bool, message: 'your error' }",s="Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";if(e&&n||X){a.ctrl.$processing=!0;var u=t.params[0],p=f(a,u);if(Q.length>1)for(;Q.length>0;){var d=Q.pop();d&&"function"==typeof d.abort&&d.abort()}if(Q.push(p),!p||"function"!=typeof p.then)throw s;a.ctrl.$setValidity("remote",!1),function(e){p.then(function(t){t=t.data||t,Q.pop(),a.ctrl.$processing=!1;var u=i.message+" ";if("boolean"==typeof t)o=!!t;else{if("object"!=typeof t)throw s;o=!!t.isValid}if(o===!1){if(r.isValid=!1,u+=t.message||e," "===u)throw l;O(a,r,u,!1,n)}else o===!0&&(r.isValid=!0,a.ctrl.$setValidity("remote",!0),O(a,r,"",!0,n))})}(t.altText)}return o}function _(e,t,a,r){var n=!0,i=r.attrs?r.attrs.ngDisabled:r.validatorAttrs.ngDisabled,o=r.elm.prop("disabled"),l=""===o||("boolean"==typeof o?o:"undefined"!=typeof o&&r.scope.$eval(o)),s=""===i||("boolean"==typeof i?i:"undefined"!=typeof i&&r.scope.$eval(i));if(l||s)n=!0;else if("string"==typeof e&&""===e&&r.elm.prop("type")&&"NUMBER"===r.elm.prop("type").toUpperCase())n=!1;else{var u=new RegExp(t.pattern,t.patternFlag);n=!((!t.pattern||"/\\S+/"===t.pattern.toString()||a&&"required"===t.pattern)&&null===e)&&u.test(e)}return n}function J(e,t){return N(t)?{condition:e.conditionNum,message:e.messageNum,params:e.params,type:"conditionalNumber"}:{pattern:e.patternLength,message:e.messageLength,params:e.params,type:"regex"}}var z=1e3,K=[],Y={resetGlobalOptionsOnRouteChange:!0},Q=[],W=[],X=!1;e.$on("$routeChangeStart",function(e,t,a){k(Y.resetGlobalOptionsOnRouteChange)}),e.$on("$stateChangeStart",function(e,t,a){k(Y.resetGlobalOptionsOnRouteChange)});var Z=function(e,t,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=z,this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,this.validateOnEmpty=!1,this.validRequireHowMany="all",e&&e.$validationOptions&&(Y=e.$validationOptions),e&&(Y.isolatedScope||Y.scope)&&(this.scope=Y.isolatedScope||Y.scope,Y=d(e.$validationOptions,Y)),"undefined"==typeof Y.resetGlobalOptionsOnRouteChange&&(Y.resetGlobalOptionsOnRouteChange=!0),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&($(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return Z.prototype.addToValidationSummary=n,Z.prototype.arrayFindObject=w,Z.prototype.arrayRemoveObject=A,Z.prototype.defineValidation=i,Z.prototype.getFormElementByName=o,Z.prototype.getFormElements=l,Z.prototype.getGlobalOptions=s,Z.prototype.isFieldRequired=p,Z.prototype.initialize=u,Z.prototype.mergeObjects=d,Z.prototype.parseBool=q,Z.prototype.removeFromValidationSummary=c,Z.prototype.removeFromFormElementObjectList=m,Z.prototype.runValidationCallbackOnPromise=g,Z.prototype.setDisplayOnlyLastErrorMsg=v,Z.prototype.setGlobalOptions=y,Z.prototype.updateErrorMsg=h,Z.prototype.validate=b,window.Element&&!Element.prototype.closest&&(Element.prototype.closest=L),String.prototype.trim=U,String.prototype.format=j,String.format=P,Z}]); angular.module("ghiscoding.validation").factory("ValidationRules",[function(){function e(e){var a="undefined"!=typeof e.altText?e.altText.replace("alt=",""):null,t=e.hasOwnProperty("customRegEx")?e.customRegEx:null,s=e.hasOwnProperty("rule")?e.rule:null,n=e.hasOwnProperty("ruleParams")?e.ruleParams:null,d={};switch(s){case"accepted":d={pattern:/^(yes|on|1|true)$/i,message:"INVALID_ACCEPTED",type:"regex"};break;case"alpha":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ])+$/i,message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ\s])+$/i,message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9])+$/i,message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9\s])+$/i,message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9_-])+$/i,message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":d={pattern:/^([a-zа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9\s_-])+$/i,message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"between":case"range":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between:1,5";d={patternLength:"^(.|[\\r\\n]){"+r[0]+","+r[1]+"}$",messageLength:"INVALID_BETWEEN_CHAR",conditionNum:[">=","<="],messageNum:"INVALID_BETWEEN_NUM",params:[r[0],r[1]],type:"autoDetect"};break;case"betweenLen":case"between_len":case"stringLen":case"string_len":case"stringLength":case"string_length":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";d={pattern:"^(.|[\\r\\n]){"+r[0]+","+r[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[r[0],r[1]],type:"regex"};break;case"betweenNum":case"between_num":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";d={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[r[0],r[1]],type:"conditionalNumber"};break;case"boolean":d={pattern:/^(true|false|0|1)$/i,message:"INVALID_BOOLEAN",type:"regex"};break;case"checked":d={pattern:/^true$/i,message:"INVALID_CHECKBOX_SELECTED",type:"regex"};break;case"creditCard":case"credit_card":d={pattern:/^3(?:[47]\d([ -]?)\d{4}(?:\1\d{4}){2}|0[0-5]\d{11}|[68]\d{12})$|^4(?:\d\d\d)?([ -]?)\d{4}(?:\2\d{4}){2}$|^6011([ -]?)\d{4}(?:\3\d{4}){2}$|^5[1-5]\d\d([ -]?)\d{4}(?:\4\d{4}){2}$|^2014\d{11}$|^2149\d{11}$|^2131\d{11}$|^1800\d{11}$|^3\d{15}$/,message:"INVALID_CREDIT_CARD",type:"regex"};break;case"custom":case"javascript":d={message:"",params:[n],type:"javascript"};break;case"dateEuro":case"date_euro":d={pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_EURO",type:"regex"};break;case"dateEuroBetween":case"date_euro_between":case"betweenDateEuro":case"between_date_euro":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro:01-01-1990,31-12-2015";d={condition:[">=","<="],dateType:"EURO_LONG",params:[r[0],r[1]],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_EURO_BETWEEN",type:"conditionalDate"};break;case"dateEuroMax":case"date_euro_max":case"maxDateEuro":case"max_date_euro":d={condition:"<=",dateType:"EURO_LONG",params:[n],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_EURO_MAX",type:"conditionalDate"};break;case"dateEuroMin":case"date_euro_min":case"minDateEuro":case"min_date_euro":d={condition:">=",dateType:"EURO_LONG",params:[n],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_EURO_MIN",type:"conditionalDate"};break;case"dateEuroLong":case"date_euro_long":d={pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{4})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_EURO_LONG",type:"regex"};break;case"dateEuroLongBetween":case"date_euro_long_between":case"betweenDateEuroLong":case"between_date_euro_long":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_long:01-01-1990,31-12-2015";d={condition:[">=","<="],dateType:"EURO_LONG",params:[r[0],r[1]],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{4})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_EURO_LONG_BETWEEN",type:"conditionalDate"};break;case"dateEuroLongMax":case"date_euro_long_max":case"maxDateEuroLong":case"max_date_euro_long":d={condition:"<=",dateType:"EURO_LONG",params:[n],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{4})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_EURO_LONG_MAX",type:"conditionalDate"};break;case"dateEuroLongMin":case"date_euro_long_min":case"minDateEuroLong":case"min_date_euro_long":d={condition:">=",dateType:"EURO_LONG",params:[n],pattern:/^(?:(?:31(\/|-|\.)(?:0[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{4})$|^(?:29(\/|-|\.)02\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_EURO_LONG_MIN",type:"conditionalDate"};break;case"dateEuroShort":case"date_euro_short":d={pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,message:"INVALID_DATE_EURO_SHORT",type:"regex"};break;case"dateEuroShortBetween":case"date_euro_short_between":case"betweenDateEuroShort":case"between_date_euro_short":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_short:01-01-90,31-12-15";d={condition:[">=","<="],dateType:"EURO_SHORT",params:[r[0],r[1]],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,message:"INVALID_DATE_EURO_SHORT_BETWEEN",type:"conditionalDate"};break;case"dateEuroShortMax":case"date_euro_short_max":case"maxDateEuroShort":case"max_date_euro_short":d={condition:"<=",dateType:"EURO_SHORT",params:[n],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,message:"INVALID_DATE_EURO_SHORT_MAX",type:"conditionalDate"};break;case"dateEuroShortMin":case"date_euro_short_min":case"minDateEuroShort":case"min_date_euro_short":d={condition:">=",dateType:"EURO_SHORT",params:[n],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,message:"INVALID_DATE_EURO_SHORT_MIN",type:"conditionalDate"};break;case"dateIso":case"date_iso":d={pattern:/^(?=\d)(?:(?!(?:1582(?:\-)10(?:\-)(?:0?[5-9]|1[0-4]))|(?:1752(?:\-)0?9(?:\-)(?:0?[3-9]|1[0-3])))(?=(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:\d\d)(?:[02468][048]|[13579][26]))\D0?2\D29)|(?:\d{4}\D(?!(?:0?[2469]|11)\D31)(?!0?2(?:\-)(?:29|30))))(\d{4})(\-)(0{1}\d|1[012])\2((?!00)[012]{1}\d|3[01])(?:$|(?=\d)))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2})|(?:[01]\d|2[0-3])(?::[0-5]\d){2})?$/,message:"INVALID_DATE_ISO",type:"regex"};break;case"dateIsoBetween":case"date_iso_between":case"betweenDateIso":case"between_date_iso":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_iso:1990-01-01,2000-12-31";d={condition:[">=","<="],dateType:"ISO",params:[r[0],r[1]],pattern:/^(?=\d)(?:(?!(?:1582(?:\-)10(?:\-)(?:0?[5-9]|1[0-4]))|(?:1752(?:\-)0?9(?:\-)(?:0?[3-9]|1[0-3])))(?=(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:\d\d)(?:[02468][048]|[13579][26]))\D0?2\D29)|(?:\d{4}\D(?!(?:0?[2469]|11)\D31)(?!0?2(?:\-)(?:29|30))))(\d{4})(\-)(0{1}\d|1[012])\2((?!00)[012]{1}\d|3[01])(?:$|(?=\d)))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2})|(?:[01]\d|2[0-3])(?::[0-5]\d){2})?$/,message:"INVALID_DATE_ISO_BETWEEN",type:"conditionalDate"};break;case"dateIsoMax":case"date_iso_max":case"maxDateIso":case"max_date_iso":d={condition:"<=",dateType:"ISO",params:[n],pattern:/^(?=\d)(?:(?!(?:1582(?:\-)10(?:\-)(?:0?[5-9]|1[0-4]))|(?:1752(?:\-)0?9(?:\-)(?:0?[3-9]|1[0-3])))(?=(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:\d\d)(?:[02468][048]|[13579][26]))\D0?2\D29)|(?:\d{4}\D(?!(?:0?[2469]|11)\D31)(?!0?2(?:\-)(?:29|30))))(\d{4})(\-)(0{1}\d|1[012])\2((?!00)[012]{1}\d|3[01])(?:$|(?=\d)))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2})|(?:[01]\d|2[0-3])(?::[0-5]\d){2})?$/,message:"INVALID_DATE_ISO_MAX",type:"conditionalDate"};break;case"dateIsoMin":case"date_iso_min":case"minDateIso":case"min_date_iso":d={condition:">=",dateType:"ISO",params:[n],pattern:/^(?=\d)(?:(?!(?:1582(?:\-)10(?:\-)(?:0?[5-9]|1[0-4]))|(?:1752(?:\-)0?9(?:\-)(?:0?[3-9]|1[0-3])))(?=(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:\d\d)(?:[02468][048]|[13579][26]))\D0?2\D29)|(?:\d{4}\D(?!(?:0?[2469]|11)\D31)(?!0?2(?:\-)(?:29|30))))(\d{4})(\-)(0{1}\d|1[012])\2((?!00)[012]{1}\d|3[01])(?:$|(?=\d)))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2})|(?:[01]\d|2[0-3])(?::[0-5]\d){2})?$/,message:"INVALID_DATE_ISO_MIN",type:"conditionalDate"};break;case"dateUs":case"date_us":d={pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_US",type:"regex"};break;case"dateUsBetween":case"date_us_between":case"betweenDateUs":case"between_date_us":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us:01/01/1990,12/31/2015";d={condition:[">=","<="],dateType:"US_LONG",params:[r[0],r[1]],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_US_BETWEEN",type:"conditionalDate"};break;case"dateUsMax":case"date_us_max":case"maxDateUs":case"max_date_us":d={condition:"<=",dateType:"US_LONG",params:[n],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_US_MAX",type:"conditionalDate"};break;case"dateUsMin":case"date_us_min":case"minDateUs":case"min_date_us":d={condition:">=",dateType:"US_LONG",params:[n],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])?00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,message:"INVALID_DATE_US_MIN",type:"conditionalDate"};break;case"dateUsLong":case"date_us_long":d={pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_US_LONG",type:"regex"};break;case"dateUsLongBetween":case"date_us_long_between":case"betweenDateUsLong":case"between_date_us_long":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_long:01/01/1990,12/31/2015";d={condition:[">=","<="],dateType:"US_LONG",params:[r[0],r[1]],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_US_LONG_BETWEEN",type:"conditionalDate"};break;case"dateUsLongMax":case"date_us_long_max":case"maxDateUsLong":case"max_date_us_long":d={condition:"<=",dateType:"US_LONG",params:[n],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_US_LONG_MAX",type:"conditionalDate"};break;case"dateUsLongMin":case"date_us_long_min":case"minDateUsLong":case"min_date_us_long":d={condition:">=",dateType:"US_LONG",params:[n],pattern:/^(?:(?:(?:0[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0[1-9])|(?:1[0-2]))(\/|-|\.)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{4})$/,message:"INVALID_DATE_US_LONG_MIN",type:"conditionalDate"};break;case"dateUsShort":case"date_us_short":d={pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,message:"INVALID_DATE_US_SHORT",type:"regex"};break;case"dateUsShortBetween":case"date_us_short_between":case"betweenDateUsShort":case"between_date_us_short":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_short:01/01/90,12/31/15";d={condition:[">=","<="],dateType:"US_SHORT",params:[r[0],r[1]],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,message:"INVALID_DATE_US_SHORT_BETWEEN",type:"conditionalDate"};break;case"dateUsShortMax":case"date_us_short_max":case"maxDateUsShort":case"max_date_us_short":d={condition:"<=",dateType:"US_SHORT",params:[n],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,message:"INVALID_DATE_US_SHORT_MAX",type:"conditionalDate"};break;case"dateUsShortMin":case"date_us_short_min":case"minDateUsShort":case"min_date_us_short":d={condition:">=",dateType:"US_SHORT",params:[n],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,message:"INVALID_DATE_US_SHORT_MIN",type:"conditionalDate"};break;case"different":case"differentInput":case"different_input":var e=n.split(",");d={condition:"!=",message:"INVALID_INPUT_DIFFERENT",params:e,type:"matching"};break;case"digits":d={pattern:"^\\d{"+n+"}$",message:"INVALID_DIGITS",params:[n],type:"regex"};break;case"digitsBetween":case"digits_between":var r=n.split(",");if(2!==r.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: digits_between:1,5";d={pattern:"^\\d{"+r[0]+","+r[1]+"}$",message:"INVALID_DIGITS_BETWEEN",params:[r[0],r[1]],type:"regex"};break;case"email":case"emailAddress":case"email_address":d={pattern:/^[-\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9#~!$%^&*_=+\/`\|}{\'?]+(\.[-\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9#~!$%^&*_=+\/`\|}{\'?]+)*@([\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9_][-\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9_]*(\.[-\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ0-9_]+)*([\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ]+)|(\.[\wа-яàáâãäåąæçćèéêëęœìíïîłńðòóôõöøśùúûñüýÿżźßÞďđ]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i,message:"INVALID_EMAIL",type:"regex"};break;case"exactLen":case"exact_len":d={pattern:"^(.|[\\r\\n]){"+n+"}$",message:"INVALID_EXACT_LEN",params:[n],type:"regex"};break;case"float":d={pattern:/^\d*\.{1}\d+$/,message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":d={pattern:/^[-+]?\d*\.{1}\d+$/,message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":d={pattern:/^[a-zA-Z]{2}\d{2}\s?([0-9a-zA-Z]{4}\s?){4}[0-9a-zA-Z]{2}$/i,message:"INVALID_IBAN",type:"regex"};break;case"enum":case"in":case"inList":case"in_list":var _=RegExp().escape(n).replace(/,/g,"|");d={pattern:"^("+_+")$",patternFlag:"i",message:"INVALID_IN_LIST",params:[n],type:"regex"};break;case"int":case"integer":d={pattern:/^\d+$/,message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":d={pattern:/^[+-]?\d+$/,message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ip":case"ipv4":d={pattern:/^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$/,message:"INVALID_IPV4",type:"regex"};break;case"ipv6":d={pattern:/^(::|(([a-fA-F0-9]{1,4}):){7}(([a-fA-F0-9]{1,4}))|(:(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){1,6}:)|((([a-fA-F0-9]{1,4}):)(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){2}(:([a-fA-F0-9]{1,4})){1,5})|((([a-fA-F0-9]{1,4}):){3}(:([a-fA-F0-9]{1,4})){1,4})|((([a-fA-F0-9]{1,4}):){4}(:([a-fA-F0-9]{1,4})){1,3})|((([a-fA-F0-9]{1,4}):){5}(:([a-fA-F0-9]{1,4})){1,2}))$/i,message:"INVALID_IPV6",type:"regex"};break;case"compare":case"match":case"matchInput":case"match_input":case"same":var e=n.split(",");d={condition:"===",message:"INVALID_INPUT_MATCH",params:e,type:"matching"};break;case"max":d={patternLength:"^(.|[\\r\\n]){0,"+n+"}$",messageLength:"INVALID_MAX_CHAR",conditionNum:"<=",messageNum:"INVALID_MAX_NUM",params:[n],type:"autoDetect"};break;case"maxLen":case"max_len":case"maxLength":case"max_length":d={pattern:"^(.|[\\r\\n]){0,"+n+"}$",message:"INVALID_MAX_CHAR",params:[n],type:"regex"};break;case"maxNum":case"max_num":d={condition:"<=",message:"INVALID_MAX_NUM",params:[n],type:"conditionalNumber"};break;case"min":d={patternLength:"^(.|[\\r\\n]){"+n+",}$",messageLength:"INVALID_MIN_CHAR",conditionNum:">=",messageNum:"INVALID_MIN_NUM",params:[n],type:"autoDetect"};break;case"minLen":case"min_len":case"minLength":case"min_length":d={pattern:"^(.|[\\r\\n]){"+n+",}$",message:"INVALID_MIN_CHAR",params:[n],type:"regex"};break;case"minNum":case"min_num":d={condition:">=",message:"INVALID_MIN_NUM",params:[n],type:"conditionalNumber"};break;case"notIn":case"not_in":case"notInList":case"not_in_list":var _=RegExp().escape(n).replace(/,/g,"|");d={pattern:"^((?!("+_+")).)+$",patternFlag:"i",message:"INVALID_NOT_IN_LIST",params:[n],type:"regex"};break;case"numeric":d={pattern:/^\d*\.?\d+$/,message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":d={pattern:/^[-+]?\d*\.?\d+$/,message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"phone":d={pattern:/^([0-9]( |[-.])?)?((\(\d{3}\) ?)|(\d{3}[-.]))?\d{3}[-.]\d{4}$/,message:"INVALID_PHONE_US",type:"regex"};break;case"phoneInternational":case"phone_international":d={pattern:/^\+(?:[0-9]\x20?){6,14}[0-9]$/,message:"INVALID_PHONE_INTERNATIONAL",type:"regex"};break;case"pattern":case"regex":d={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"remote":d={message:"",params:[n],type:"remote"};break;case"required":d={pattern:/\S+/,message:"INVALID_REQUIRED",type:"regex"};break;case"size":d={patternLength:"^(.|[\\r\\n]){"+n+"}$",messageLength:"INVALID_EXACT_LEN",conditionNum:"==",messageNum:"INVALID_EXACT_NUM",params:[n],type:"autoDetect"};break;case"url":d={pattern:/^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i,message:"INVALID_URL",type:"regex"};break;case"time":d={pattern:/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/,message:"INVALID_TIME",type:"regex"}}return d.altText=a,d}var a={getElementValidators:e};return a}]),RegExp.prototype.escape=function(e){if(!arguments.callee.sRE){var a=["/",".","*","+","?","|","(",")","[","]","{","}","\\"];arguments.callee.sRE=new RegExp("(\\"+a.join("|\\")+")","g")}return e.replace(arguments.callee.sRE,"\\$1")}; -angular.module("ghiscoding.validation").service("ValidationService",["$interpolate","$q","$timeout","ValidationCommon",function(e,o,t,a){function n(o,t,a){var n=this,i={};if("string"==typeof o&&"string"==typeof t?(i.elmName=o,i.rules=t,i.friendlyName="string"==typeof a?a:""):i=o,"object"!=typeof i||!i.hasOwnProperty("elmName")||!i.hasOwnProperty("rules")||!i.hasOwnProperty("scope")&&"undefined"==typeof n.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";var l=i.scope?i.scope:n.validationAttrs.scope;if(i.elm=angular.element(document.querySelector('[name="'+i.elmName+'"]')),"object"!=typeof i.elm||0===i.elm.length)return n;if(new RegExp("{{(.*?)}}").test(i.elmName)&&(i.elmName=e(i.elmName)(l)),i.name=i.elmName,n.validationAttrs.isolatedScope){var m=l.$validationOptions||null;l=n.validationAttrs.isolatedScope,m&&(l.$validationOptions=m)}return g=n.validationAttrs.hasOwnProperty("validationCallback")?n.validationAttrs.validationCallback:null,$=n.validationAttrs.hasOwnProperty("validateOnEmpty")?n.commonObj.parseBool(n.validationAttrs.validateOnEmpty):!!V.validateOnEmpty,i.elm.bind("blur",j=function(e){var o=n.commonObj.getFormElementByName(i.elmName);if(o&&!o.isValidationCancelled){n.commonObj.initialize(l,i.elm,i,i.ctrl);var t=s(n,e.target.value,0);g&&n.commonObj.runValidationCallbackOnPromise(t,g)}}),i=n.commonObj.mergeObjects(n.validationAttrs,i),O(n,l,i),i.elm.on("$destroy",function(){var e=n.commonObj.getFormElementByName(n.commonObj.ctrl.$name);e&&(u(n,e),n.commonObj.removeFromValidationSummary(i.name))}),h.push({elmName:i.elmName,watcherHandler:f(l,i,n)}),n}function i(e,o){var t=this,a="",n=!0;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"checkFormValidity() requires a valid Angular Form or $scope/vm object passed as argument to work properly, for example:: fn($scope) OR fn($scope.form1) OR fn(vm) OR fn(vm.form1)";for(var i=0,l=e.$validationSummary.length;i0&&("function"!=typeof m.ctrl.$setTouched||o||m.ctrl.$setTouched(),t.commonObj.updateErrorMsg(e.$validationSummary[i].message,{isSubmitted:!o,isValid:m.isValid,obj:m}))}return n}function l(e){var o=this;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"clearInvalidValidatorsInSummary() requires a valid Angular Form or $scope/vm object passed as argument to work properly, for example:: fn($scope) OR fn($scope.form1) OR fn(vm) OR fn(vm.form1)";for(var t=[],a=0,n=e.$validationSummary.length;a0&&("function"!=typeof m.ctrl.$setTouched||o||m.ctrl.$setTouched(),t.commonObj.updateErrorMsg(e.$validationSummary[i].message,{isSubmitted:!o,isValid:m.isValid,obj:m}))}return n}function l(e){var o=this;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"clearInvalidValidatorsInSummary() requires a valid Angular Form or $scope/vm object passed as argument to work properly, for example:: fn($scope) OR fn($scope.form1) OR fn(vm) OR fn(vm.form1)";for(var t=[],a=0,n=e.$validationSummary.length;a = 2001-01-01", + "INPUT20":"请用简短美式日期 (mm/dd/yy) --日期12/01/99和12/31/15之间", + "INPUT21":"在这个列表中选择(banana,orange,ice cream,sweet & sour)", + "FIRST_NAME":"名字", + "LAST_NAME":"姓", + "RESET_FORM":"复位形式", + "SAVE":"保存", + "SELECT1":"要求(select)-验证与(blur)事件", + "SHOW_VALIDATION_SUMMARY":"显示验证总结" +} \ No newline at end of file diff --git a/locales/validation/zh_CN.json b/locales/validation/zh_CN.json new file mode 100644 index 0000000..f428d4f --- /dev/null +++ b/locales/validation/zh_CN.json @@ -0,0 +1,105 @@ +{ + "INVALID_ACCEPTED": "必须接受。 ", + "INVALID_ALPHA": "可能只包含字母。 ", + "INVALID_ALPHA_SPACE": "可能只包含字母和空格。 ", + "INVALID_ALPHA_NUM": "可能只包含字母和数字。 ", + "INVALID_ALPHA_NUM_SPACE": "只能包含字母,数字和空格。 ", + "INVALID_ALPHA_DASH": "只能包含字母,数字和破折号。 ", + "INVALID_ALPHA_DASH_SPACE": "可能只包含字母,数字,破折号和空格。 ", + "INVALID_BETWEEN_CHAR": "文本长度必须在{0}和{1}个字符之间。 ", + "INVALID_BETWEEN_NUM": "需要是{0}到{1}之间的数值。 ", + "INVALID_BOOLEAN": "可能只包含真实或虚假的价值。 ", + "INVALID_CREDIT_CARD": "必须是有效的信用卡号。 ", + "INVALID_DATE_EURO": "必须是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy)。 ", + "INVALID_DATE_EURO_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy)。 ", + "INVALID_DATE_EURO_MAX": "需要是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy), 等于或低于 {0}。 ", + "INVALID_DATE_EURO_MIN": "需要是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy), 等于或高于 {0}。 ", + "INVALID_DATE_EURO_LONG": "必须是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy)。 ", + "INVALID_DATE_EURO_LONG_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy)。 ", + "INVALID_DATE_EURO_LONG_MAX": "需要是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy), 等于或低于 {0}。 ", + "INVALID_DATE_EURO_LONG_MIN": "需要是有效的日期格式 (dd-mm-yyyy) 或 (dd/mm/yyyy), 等于或高于 {0}。 ", + "INVALID_DATE_EURO_SHORT": "必须是有效的日期格式 (dd-mm-yy) 或 (dd/mm/yy)。 ", + "INVALID_DATE_EURO_SHORT_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (dd-mm-yy) 或 (dd/mm/yy)。 ", + "INVALID_DATE_EURO_SHORT_MAX": "需要是有效的日期格式 (dd-mm-yy) 或 (dd/mm/yy), 等于或低于 {0}。 ", + "INVALID_DATE_EURO_SHORT_MIN": "需要是有效的日期格式 (dd-mm-yy) 或 (dd/mm/yy), 等于或高于 {0}。 ", + "INVALID_DATE_ISO": "必须是有效的日期格式 (yyyy-mm-dd)。 ", + "INVALID_DATE_ISO_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (yyyy-mm-dd)。 ", + "INVALID_DATE_ISO_MAX": "需要是有效的日期格式 (yyyy-mm-dd), 等于或低于 {0}。 ", + "INVALID_DATE_ISO_MIN": "需要是有效的日期格式 (yyyy-mm-dd), 等于或高于 {0}。 ", + "INVALID_DATE_US": "必须是有效的日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy)。 ", + "INVALID_DATE_US_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy)。 ", + "INVALID_DATE_US_MAX": "需要是有效的日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy), 等于或低于 {0}。 ", + "INVALID_DATE_US_MIN": "需要是有效的日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy), 等于或高于 {0}。 ", + "INVALID_DATE_US_LONG": "必须是有效的日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy)。 ", + "INVALID_DATE_US_LONG_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (mm/dd/yyyy) 或 (mm-dd-yyyy)。 ", + "INVALID_DATE_US_LONG_MAX": "需要是有效的日期格式(mm / dd / yy)OR(mm-dd-yy),等于或低于{0}。 ", + "INVALID_DATE_US_LONG_MIN": "需要是有效的日期格式(mm / dd / yy)或(mm-dd-yy),等于或低于{0}。 ", + "INVALID_DATE_US_SHORT": "必须是有效的日期格式 (mm/dd/yy) 或 (mm-dd-yy)。 ", + "INVALID_DATE_US_SHORT_BETWEEN": "需要在{0}和{1}之间的有效日期格式 (mm/dd/yy) 或 (mm-dd-yy)。 ", + "INVALID_DATE_US_SHORT_MAX": "需要是有效的日期格式 (mm/dd/yy) 或 (mm-dd-yy), 等于或低于 {0}。 ", + "INVALID_DATE_US_SHORT_MIN": "需要是有效的日期格式 (mm/dd/yy) 或 (mm-dd-yy), 等于或低于 {0}。 ", + "INVALID_DIGITS": "必须是{0}位数。 ", + "INVALID_DIGITS_BETWEEN": "必须介于{0}到{1}位数之间。 ", + "INVALID_EMAIL": "必须是一个有效的电子邮箱地址。 ", + "INVALID_EXACT_LEN": "必须有{0}个字符的长度。 ", + "INVALID_EXACT_NUM": "“必须完全是{0}。 ", + "INVALID_FLOAT": "可能只包含一个正的浮点值(不包括整数)。 ", + "INVALID_FLOAT_SIGNED": "可能只包含正值或负值浮点值(不包括整数)。 ", + "INVALID_IBAN": "必须是有效的IBAN。 ", + "INVALID_IN_LIST": "必须是这个列表中的选择:({0})。 ", + "INVALID_INPUT_DIFFERENT": "字段必须与指定字段[{1}]不同。 ", + "INVALID_INPUT_MATCH": "确认字段与指定字段[{1}]不匹配。 ", + "INVALID_INTEGER": "必须是正整数。 ", + "INVALID_INTEGER_SIGNED": "必须是正整数或负整数。 ", + "INVALID_IPV4": "必须是有效的IP(IPV4)。 ", + "INVALID_IPV6": "必须是有效的IP(IPV6)。 ", + "INVALID_IPV6_HEX": "必须是有效的IP(IPV6 Hex)。 ", + "INVALID_KEY_CHAR": "在”数字“类型的字段上输入的键盘无效。 ", + "INVALID_MAX_CHAR": "不能超过{0}个字符。 ", + "INVALID_MAX_NUM": "需要是数值,等于或低于{0}。 ", + "INVALID_MIN_CHAR": "必须至少{0}个字符。 ", + "INVALID_MIN_NUM": "需要是数值,等于或高于{0}。 ", + "INVALID_NOT_IN_LIST": "必须是这个列表之外的选择:({0})。 ", + "INVALID_NUMERIC": "必须是正数。 ", + "INVALID_NUMERIC_SIGNED": "必须是正数或负数。 ", + "INVALID_PATTERN": "必须遵循以下格式:{0}。 ", + "INVALID_PATTERN_DATA": "必须遵循此格式{{data}}。 ", + "INVALID_PHONE_US": "必须是有效的电话号码,必须包含区号。 ", + "INVALID_PHONE_INTERNATIONAL": "必须是有效的国际电话号码。 ", + "INVALID_REQUIRED": "此项是必须的。 ", + "INVALID_URL": "必须是有效的URL。 ", + "INVALID_TIME": "必须是有效的时间格式(hh:mm)或(hh:mm:ss)。 ", + "INVALID_CHECKBOX_SELECTED": "必须选中复选框。 ", + + "AREA1": "TextArea: 字母数字+最小(15)+ 必需", + "ERRORS": "错误", + "CHANGE_LANGUAGE": "改变语言", + "FORM_PREVALIDATED": "表格预先验证", + "INPUT1": "远程验证 - 为有效答案键入'abc' ", + "INPUT2": "数字正数或负数 - 输入类型='数字 - 非数字字符错误 ", + "INPUT3": "浮动数范围(不包括整数) - between_num:x,y OR min_num:x | max_num:y ", + "INPUT4": "多个验证+日期代码的自定义正则表达式(YYWW)", + "INPUT5": "电子邮件", + "INPUT6": "URL", + "INPUT7": "IP (IPV4)", + "INPUT8": "信用卡", + "INPUT9": "间于(2,6)之间的字符", + "INPUT10": "日期标准格式 (yyyy-mm-dd)", + "INPUT11": "美国长日期格式 (mm/dd/yyyy)", + "INPUT12": "时间 (hh:mm OR hh:mm:ss) -- 非必要项", + "INPUT13": "字母横杠空格 + 必需 + 最小(5) 字符 -- 必须使用: validation-error-to=' '", + "INPUT14": "字母数字+必需 - 未禁用", + "INPUT15": "密码", + "INPUT16": "确认密码", + "INPUT17": "不同的密码", + "INPUT18": "字母数字+确切(3)+必需 - 减震(3秒)", + "INPUT19": "标准日期格式 (yyyy-mm-dd) -- 最小条件> = 2001-01-01", + "INPUT20": "美国短日期格式 (mm/dd/yy) -- 在12/01/99和12/31/15之间", + "INPUT21": "在这些词中选择(香蕉,橙子,冰淇淋,酸甜)", + "FIRST_NAME": "名字", + "LAST_NAME": "姓", + "RESET_FORM": "重置表", + "SAVE": "保存", + "SELECT1": "必需(选择) - 验证(模糊)事件", + "SHOW_VALIDATION_SUMMARY": "显示验证摘要" +} \ No newline at end of file diff --git a/package.json b/package.json index 08ede07..9e72e55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-validation-ghiscoding", - "version": "1.5.21", + "version": "1.5.28", "author": "Ghislain B.", "description": "Angular-Validation Directive and Service (ghiscoding)", "main": "dist/angular-validation.min", diff --git a/protractor/badInput_spec.js b/protractor/badInput_spec.js index 2376aaa..623f214 100644 --- a/protractor/badInput_spec.js +++ b/protractor/badInput_spec.js @@ -45,7 +45,6 @@ describe('Angular-Validation badInput Tests:', function () { it('Should display same invalid character error message even after a Tab', function() { // make input3 invalid, remove text var elmInput2 = $('[name=input2]'); - element(by.css('body')).click(); elmInput2.sendKeys(protractor.Key.TAB); // error should appear on input2 @@ -82,7 +81,7 @@ describe('Angular-Validation badInput Tests:', function () { }); it('Should hide ValidationSummary after clicking on checkbox', function() { - var btnShowSummary = $('[name=btn_showValidation]'); + var btnShowSummary = $('[name=chkbox_validationSummary]'); btnShowSummary.click(); browser.waitForAngular(); @@ -96,7 +95,6 @@ describe('Angular-Validation badInput Tests:', function () { var elmInput2 = $('[name=input2]'); elmInput2.click(); clearInput(elmInput2, 5); - element(by.css('body')).click(); elmInput2.sendKeys(protractor.Key.TAB); // error should appear on input2 @@ -105,7 +103,7 @@ describe('Angular-Validation badInput Tests:', function () { }); it('Should show ValidationSummary after clicking on show checkbox', function() { - var btnShowSummary = $('[name=btn_showValidation]'); + var btnShowSummary = $('[name=chkbox_validationSummary]'); btnShowSummary.click(); browser.waitForAngular(); diff --git a/readme.md b/readme.md index 58c3ce7..c06fab6 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,22 @@ # Angular Validation (Directive / Service) -`Version: 1.5.21` +`Version: 1.5.28` + +## Project in Life Support +#### still accepting PR for any bug fix +**Also note that only NPM will updated with new releases when PR get merged** + +This project is now in Life Support since most of us already moved to newer version of Angular. However I do want to point out that if you still use the lib and find a Bug, I certainly still welcome PR (Pull Request) to address bug fixes. So I'm not totally gone but I won't personally invest more time in the lib. Also note that the lib will not be rewritten to support Angular 2+ + +On a totally different note, I'm still very active in the Angular 4+ world (even Aurelia world) and you might be interested in looking at some of my other libraries. +- [Angular-Slickgrid](https://github.com/ghiscoding/Angular-Slickgrid) +- [Angular Markdown Preview Editor](https://github.com/ghiscoding/angular-markdown-editor) + +In the Aurelia world +- [Aurelia-Slickgrid](https://github.com/ghiscoding/aurelia-slickgrid) +- [Aurelia Bootstrap Plugin](https://github.com/ghiscoding/Aurelia-Bootstrap-Plugins) + +--- + ### Forms Validation with Angular made easy! ##### (Concept comes from the amazing Laravel) diff --git a/src/validation-common.js b/src/validation-common.js index 8b83b95..ef55de0 100644 --- a/src/validation-common.js +++ b/src/validation-common.js @@ -66,6 +66,7 @@ angular // list of available published public functions of this object validationCommon.prototype.addToValidationSummary = addToValidationSummary; // add an element to the $validationSummary validationCommon.prototype.arrayFindObject = arrayFindObject; // search an object inside an array of objects + validationCommon.prototype.arrayRemoveObject = arrayRemoveObject; // search an object inside an array of objects and remove it from array validationCommon.prototype.defineValidation = defineValidation; // define our validation object validationCommon.prototype.getFormElementByName = getFormElementByName; // get the form element custom object by it's name validationCommon.prototype.getFormElements = getFormElements; // get the array of form elements (custom objects) @@ -178,7 +179,7 @@ angular self = analyzeElementAttributes(self); // get the rules(or validation), inside directive it's named (validation), inside service(rules) - var rules = self.validatorAttrs.rules || self.validatorAttrs.validation; + var rules = self.validatorAttrs.rules || self.validatorAttrs.validation || ''; // We first need to see if the validation holds a custom user regex, if it does then deal with it first // So why deal with it separately? Because a Regex might hold pipe '|' and so we don't want to mix it with our regular validation pipe @@ -771,6 +772,25 @@ angular return null; } + /** Quick function to remove an object inside an array by it's given field name and value, return and remove the object found or null + * @param Array sourceArray + * @param string searchId: search property id + * @param string searchValue: value to search + * @return object found from source array or null + */ + function arrayRemoveObject(sourceArray, searchId, searchValue) { + if (!!sourceArray) { + for (var i = 0; i < sourceArray.length; i++) { + if (sourceArray[i][searchId] === searchValue) { + var itemToRemove = sourceArray[i]; + sourceArray.splice(i,1); + return itemToRemove; + } + } + } + return null; + } + /** Quick function to find all object(s) inside an array of objects by it's given field name and value, return array of object found(s) or empty array * @param Array sourceArray * @param string searchId: search property id @@ -816,7 +836,7 @@ angular var formName = (!!formObj) ? formObj.getAttribute("name") : null; if (!!formObj && !!formName) { - parentForm = (!!_globalOptions && !!_globalOptions.controllerAs && formName.indexOf('.') >= 0) + var parentForm = (!!_globalOptions && !!_globalOptions.controllerAs && formName.indexOf('.') >= 0) ? objectFindById(self.scope, formName, '.') : self.scope[formName]; diff --git a/src/validation-directive.js b/src/validation-directive.js index 3bd2dcc..49fe9b4 100644 --- a/src/validation-directive.js +++ b/src/validation-directive.js @@ -179,7 +179,7 @@ } // invalidate field before doing any validation - if(!!value || commonObj.isFieldRequired() || _validateOnEmpty) { + if((value !== "" && value !== null && typeof value !== "undefined") || commonObj.isFieldRequired() || _validateOnEmpty) { ctrl.$setValidity('validation', false); } @@ -403,7 +403,9 @@ /** Re-evaluate the element and revalidate it, also re-attach the onBlur event on the element */ function revalidateAndAttachOnBlur() { // Revalidate the input when enabled (without displaying the error) - var value = ctrl.$modelValue || ''; + var value = ctrl.$modelValue !== null && typeof ctrl.$modelValue !== 'undefined' + ? ctrl.$modelValue + : ''; if(!Array.isArray(value)) { ctrl.$setValidity('validation', commonObj.validate(value, false)); } diff --git a/src/validation-service.js b/src/validation-service.js index 5f829e0..7ce53a8 100644 --- a/src/validation-service.js +++ b/src/validation-service.js @@ -88,18 +88,14 @@ angular attrs.name = attrs.elmName; // user could pass his own scope, useful in a case of an isolate scope - if (!!self.validationAttrs.isolatedScope) { - var tempValidationOptions = scope.$validationOptions || null; // keep global validationOptions - scope = self.validationAttrs.isolatedScope; // rewrite original scope + if (!!self.validationAttrs.isolatedScope || attrs.isolatedScope) { + var tempValidationOptions = scope.$validationOptions || null; // keep global validationOptions + scope = self.validationAttrs.isolatedScope || attrs.isolatedScope; // rewrite original scope if(!!tempValidationOptions) { - scope.$validationOptions = tempValidationOptions; // reuse the validationOption from original scope + scope.$validationOptions = tempValidationOptions; // reuse the validationOption from original scope } } - // Possible element attributes - _validationCallback = (self.validationAttrs.hasOwnProperty('validationCallback')) ? self.validationAttrs.validationCallback : null; - _validateOnEmpty = (self.validationAttrs.hasOwnProperty('validateOnEmpty')) ? self.commonObj.parseBool(self.validationAttrs.validateOnEmpty) : !!_globalOptions.validateOnEmpty; - // onBlur make validation without waiting attrs.elm.bind('blur', _blurHandler = function(event) { // get the form element custom object and use it after @@ -110,7 +106,7 @@ angular self.commonObj.initialize(scope, attrs.elm, attrs, attrs.ctrl); // attempt to validate & run validation callback if user requested it - var validationPromise = attemptToValidate(self, event.target.value, 0); + var validationPromise = attemptToValidate(self, (attrs.ctrl.$modelValue == undefined ? '' : attrs.ctrl.$modelValue), 0); if(!!_validationCallback) { self.commonObj.runValidationCallbackOnPromise(validationPromise, _validationCallback); } @@ -121,6 +117,10 @@ angular // so the position inside the mergeObject call is very important attrs = self.commonObj.mergeObjects(self.validationAttrs, attrs); + // Possible element attributes + _validationCallback = (attrs.hasOwnProperty('validationCallback')) ? attrs.validationCallback : null; + _validateOnEmpty = (attrs.hasOwnProperty('validateOnEmpty')) ? self.commonObj.parseBool(attrs.validateOnEmpty) : !!_globalOptions.validateOnEmpty; + // watch the `disabled` attribute for changes // if it become disabled then skip validation else it becomes enable then we need to revalidate it watchNgDisabled(self, scope, attrs); @@ -334,9 +334,12 @@ angular // pre-validate without any events just to pre-fill our validationSummary with all field errors // passing false as 2nd argument for not showing any errors on screen self.commonObj.validate(value, false); - + + // check field level setting for validateOnEmpty + var isFieldValidateOnEmpty = (self.commonObj.validatorAttrs && self.commonObj.validatorAttrs.validateOnEmpty); + // if field is not required and his value is empty, cancel validation and exit out - if(!self.commonObj.isFieldRequired() && !_validateOnEmpty && (value === "" || value === null || typeof value === "undefined")) { + if(!self.commonObj.isFieldRequired() && !(_validateOnEmpty || isFieldValidateOnEmpty) && (value === "" || value === null || typeof value === "undefined")) { cancelValidation(self, formElmObj); deferred.resolve({ isFieldValid: true, formElmObj: formElmObj, value: value }); return deferred.promise; @@ -491,7 +494,7 @@ angular var foundWatcher = self.commonObj.arrayFindObject(_watchers, 'elmName', formElmObj.fieldName); if(!!foundWatcher) { foundWatcher.watcherHandler(); // deregister the watch by calling his handler - _watchers.shift(); + self.commonObj.arrayRemoveObject(_watchers, 'elmName', formElmObj.fieldName); } // make the validation cancelled so it won't get called anymore in the blur eventHandler @@ -574,7 +577,7 @@ angular attrs.elm.bind('blur', _blurHandler = function(event) { if (!!formElmObj && !formElmObj.isValidationCancelled) { // attempt to validate & run validation callback if user requested it - var validationPromise = attemptToValidate(self, event.target.value, 10); + var validationPromise = attemptToValidate(self, (attrs.ctrl.$modelValue == undefined ? '' : attrs.ctrl.$modelValue), 10); if(!!_validationCallback) { self.commonObj.runValidationCallbackOnPromise(validationPromise, _validationCallback); } @@ -596,4 +599,4 @@ angular }); } -}]); // ValidationService \ No newline at end of file +}]); // ValidationService