From 786e80e857c10ae75cbd35796d5168a7438bf83b Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Thu, 3 Sep 2015 23:08:47 -0400 Subject: [PATCH] Fixed issue #63 make custom Regex pattern greedy Custom Regex pattern was non-greedy and was causing problem when user had a '/' inside his own custom pattern. --- bower.json | 2 +- changelog.txt | 1 + dist/angular-validation.min.js | 6 +++--- package.json | 2 +- readme.md | 4 ++-- src/validation-common.js | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bower.json b/bower.json index 3cb45cc..f577d23 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-validation-ghiscoding", - "version": "1.4.4", + "version": "1.4.5", "author": "Ghislain B.", "description": "Angular-Validation Directive and Service (ghiscoding)", "main": [ diff --git a/changelog.txt b/changelog.txt index 593f2ba..4ced978 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,6 @@ Angular-Validation change logs +1.4.5 (2015-09-03) Fixed issue #63 - Custom Regex pattern should be greedy (instead of non-greedy), this was causing a problem when user add a `/` in his pattern and was stopping on first occurence. 1.4.4 (2015-08-21) Enhancement #59 - Added few Validators that are like Laravel for reusability. The `in` and `not_in` Validators are the most interesting. 1.4.3 (2015-08-18) Fixed issue #58 - multiple ControllerAs with Route change giving error of 'undefined' on $validationSummary. 1.4.2 (2015-08-09) Fixed Bootstrap UI (or any other tool) interference with Angular-Validation, in relation to issue #55. diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index 7d52401..8a94c9d 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.4.4 + * @version: 1.4.5 * @license: MIT - * @build: Fri Aug 21 2015 23:14:42 GMT-0400 (Eastern Daylight Time) + * @build: Thu Sep 03 2015 22:19:05 GMT-0400 (Eastern Daylight Time) */ angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$timeout","validationCommon",function(e,i){return{restrict:"A",require:"ngModel",link:function(a,t,n,l){function o(e){var i=c.getFormElementByName(l.$name);i.isValidationCancelled?l.$setValidity("validation",!0):d(e.target.value,10)}function d(i,n){var o="undefined"!=typeof n?n:c.typingLimit,d=c.getFormElementByName(l.$name);return c.validate(i,!1),c.isFieldRequired()||""!==i&&null!==i&&"undefined"!=typeof i?(d&&(d.isValidationCancelled=!1),(i||c.isFieldRequired())&&l.$setValidity("validation",!1),""!==i&&"undefined"!=typeof i||"NUMBER"!==t.prop("type").toUpperCase()?"SELECT"===t.prop("tagName").toUpperCase()?(l.$setValidity("validation",c.validate(i,!0)),i):("undefined"!=typeof i&&(c.updateErrorMsg(""),e.cancel(m),m=e(function(){a.$evalAsync(l.$setValidity("validation",c.validate(i,!0)))},o)),i):(e.cancel(m),l.$setValidity("validation",c.validate(i,!0)),i)):(u(),i)}function r(){l.$formatters.shift(),l.$parsers.shift(),u(),c.removeFromValidationSummary(n.name)}function u(){var i=c.getFormElementByName(l.$name);i&&(i.isValidationCancelled=!0),e.cancel(m),c.updateErrorMsg(""),l.$setValidity("validation",!0),"function"==typeof o&&t.unbind("blur",o)}function s(){var e=l.$viewValue||"";l.$setValidity("validation",c.validate(e,!1));var i=c.getFormElementByName(l.$name);i&&(i.isValidationCancelled=!1),t.bind("blur",o)}var m,o,c=new i(a,t,n,l);a.$evalAsync(function(){l.$formatters.unshift(d),l.$parsers.unshift(d)}),n.$observe("disabled",function(e){e?(u(),c.removeFromValidationSummary(n.name)):s()}),t.on("$destroy",function(){r()}),a.$watch(function(){return t.attr("validation")},function(e){"undefined"==typeof e||""===e?r():(c.defineValidation(),s())}),t.bind("blur",o)}}}]); -angular.module("ghiscoding.validation").factory("validationCommon",["$rootScope","$translate","validationRules",function(e,t,a){function r(){var e=this,t={};e.validators=[],e.typingLimit=T,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));var r=e.validatorAttrs.rules||e.validatorAttrs.validation;if(r.indexOf("pattern=/")>=0){var n=r.match(/pattern=(\/.*?\/[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},r=r.replace("pattern="+i,"pattern")}else if(r.indexOf("regex:")>=0){var n=r.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 p=n[1].split(":=");t={message:p[0],pattern:p[1]},r=r.replace(n[0],"regex:")}var m=r.split("|");if(m){e.bFieldRequired=r.indexOf("required")>=0?!0:!1;for(var u=0,d=m.length;d>u;u++){var c=m[u].split(":"),f=m[u].indexOf("alt=")>=0?!0:!1;e.validators[u]=a.getElementValidators({altText:f===!0?2===c.length?c[1]:c[2]:"",customRegEx:t,rule:c[0],ruleParams:f&&2===c.length?null:c[1]})}}return e}function n(e){return b(L,"fieldName",e)}function i(e){return e?O(L,"formName",e):L}function o(){return k}function l(e,t,a,r){this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,v(t,a,r,e),this.defineValidation()}function s(){var e=this;return e.bFieldRequired}function p(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=$(L,"fieldName",e);t>=0&&L.splice(t,1)}function u(e,t){var a=this,r=A(e,a),n=t||q,i=$(n,"field",e);if(i>=0&&n.splice(i,1),i=$(q,"field",e),i>=0&&q.splice(i,1),a.scope.$validationSummary=q,r&&(r.$validationSummary=O(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=O(q,"formName",r.$name))}return q}function d(e){k.displayOnlyLastErrorMsg=e}function c(e){var t=this;return k=p(k,e),t}function f(e,a){var r=this;a&&a.obj&&(r=a.obj,r.validatorAttrs=a.obj.attrs);var n=a&&a.elm?a.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=a&&a.translate?t.instant(e):e,s=i.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),p=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var m=r.validatorAttrs.validationErrorTo.charAt(0),u="."===m||"#"===m?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;p=angular.element(document.querySelector(u))}p&&0!==p.length||(p=angular.element(document.querySelector(".validation-"+s)));var d=a&&a.isSubmitted?a.isSubmitted:!1;a&&!a.isValid&&(d||r.ctrl.$dirty||r.ctrl.$touched)?p.length>0?p.html(l):n.after(''+l+""):p.html("")}function g(e,a){var r,i,o=this,l=!0,s=!0,p="";"undefined"==typeof e&&(e="");for(var m=o.ctrl&&o.ctrl.$name?o.ctrl.$name:o.attrs&&o.attrs.name?o.attrs.name:o.elm.attr("name"),u=n(m),d=o.validatorAttrs.rules||o.validatorAttrs.validation,c=0,f=o.validators.length;f>c;c++){if(i=o.validators[c],"autoDetect"===i.type&&(i=E(e)?{condition:i.conditionNum,message:i.messageNum,params:i.params,type:"conditionalNumber"}:{pattern:i.patternLength,message:i.messageLength,params:i.params,type:"regex"}),"conditionalDate"===i.type){var g=l=!1;if(e instanceof Date?g=!0:(r=new RegExp(i.pattern),g=(!i.pattern||"/\\S+/"===i.pattern.toString()||d&&"required"===i.pattern)&&null===e?!1:r.test(e)),g){var v=i.dateType,b=e instanceof Date?e:x(e,v).getTime();if(2==i.params.length){var O=x(i.params[0],v).getTime(),$=x(i.params[1],v).getTime(),S=R(i.condition[0],b,O),A=R(i.condition[1],b,$);l=S&&A?!0:!1}else{var N=x(i.params[0],v).getTime();l=R(i.condition,b,N)}}}else if("conditionalNumber"===i.type)if(2==i.params.length){var S=R(i.condition[0],parseFloat(e),parseFloat(i.params[0])),A=R(i.condition[1],parseFloat(e),parseFloat(i.params[1]));l=S&&A?!0:!1}else l=R(i.condition,parseFloat(e),parseFloat(i.params[0]));else if("matching"===i.type){var w=i.params[0],V=o.scope.$eval(w),F=angular.element(document.querySelector('[name="'+w+'"]'));l=R(i.condition,e,V)&&!!e,F&&F.attr("friendly-name")?i.params[1]=F.attr("friendly-name"):i.params.length>1&&(i.params[1]=i.params[1])}else if("remote"===i.type){if(e&&a){o.ctrl.$processing=!0;var T=null,L=i.params[0];if(-1===L.indexOf("."))T=o.scope[L];else{var q=L.split(".");T=o.scope;for(var C=0,G=q.length;G>C;C++)T=T[q[C]]}var M="function"==typeof T?T():null;if(U.length>1)for(;U.length>0;){var j=U.pop();"function"==typeof j.abort&&j.abort()}if(U.push(M),!M||"function"!=typeof M.then)throw"Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";o.ctrl.$setValidity("remote",!1),function(e){M.then(function(t){t=t.data||t,U.pop(),o.ctrl.$processing=!1;var r=p+" ";"boolean"==typeof t?l=t?!0:!1:"object"==typeof t&&(l=t.isValid?!0:!1),l===!1&&(u.isValid=!1,r+=t.message||e,h(o,u,r,!1,a)),l===!0&&s===!0&&(u.isValid=!0,o.ctrl.$setValidity("remote",!0),h(o,u,"",!0,a))})}(i.altText)}}else{var D=o.attrs?o.attrs.ngDisabled:o.validatorAttrs.ngDisabled;o.elm.prop("disabled")||o.scope.$eval(D)?l=!0:"string"==typeof e&&""===e&&"NUMBER"===o.elm.prop("type").toUpperCase()?l=!1:(r=new RegExp(i.pattern),l=(!i.pattern||"/\\S+/"===i.pattern.toString()||d&&"required"===i.pattern)&&null===e?!1:r.test(e))}(!o.bFieldRequired&&!e||o.elm.prop("disabled")||o.scope.$eval(D))&&(l=!0),l||(s=!1,function(e,r,n){var i=n.message;n.altText&&n.altText.length>0&&(i=n.altText.replace("alt=","")),t(i).then(function(t){p.length>0&&k.displayOnlyLastErrorMsg?p=" "+(n&&n.params?String.format(t,n.params):t):p+=" "+(n&&n.params?String.format(t,n.params):t),h(o,e,p,s,a)})["catch"](function(){n.altText&&n.altText.length>0&&(p.length>0&&k.displayOnlyLastErrorMsg?p=" "+i:p+=" "+i,h(o,e,p,s,a))})}(u,l,i))}return l&&(y(o,""),o.updateErrorMsg("",{isValid:l})),u&&(u.isValid=s,s&&(u.message="")),s}function v(e,a,r,n){var i=a.name?a.name:e.attr("name"),o=A(i,{scope:n}),l=a&&a.friendlyName?t.instant(a.friendlyName):"",s={fieldName:i,friendlyName:l,elm:e,attrs:a,ctrl:r,scope:n,isValid:!1,message:"",formName:o?o.$name:null},p=$(L,"fieldName",e.attr("name"));return p>=0?L[p]=s:L.push(s),L}function h(e,t,a,r,n){a=a.trim(),y(t,a),t&&(t.message=a),(e.validatorAttrs.preValidateFormElements||k.preValidateFormElements)&&(t&&"function"==typeof e.ctrl.$setTouched&&t.ctrl.$setTouched(),e.ctrl.$dirty===!1&&f(a,{isSubmitted:!0,isValid:r,obj:t})),n&&t&&!t.isValid?e.updateErrorMsg(a,{isValid:r}):t&&t.isValid&&y(t,"")}function y(e,a){if("undefined"!=typeof e&&null!=e){var r=e.ctrl&&e.ctrl.$name?e.ctrl.$name:e.attrs&&e.attrs.name?e.attrs.name:e.elm.attr("name"),n=A(r,e),i=$(q,"field",r);if(i>=0&&""===a)q.splice(i,1);else if(""!==a){var o=e.attrs&&e.friendlyName?t.instant(e.friendlyName):"",l={field:r,friendlyName:o,message:a,formName:n?n.$name:null};i>=0?q[i]=l:q.push(l)}if(e.scope.$validationSummary=q,n&&(n.$validationSummary=O(q,"formName",n.$name)),k&&k.controllerAs&&(k.controllerAs.$validationSummary=q,n)){var s=n.$name.indexOf(".")>=0?n.$name.split(".")[1]:n.$name,p=k.controllerAs[s]?k.controllerAs[s]:e.elm.controller()[s];p.$validationSummary=O(q,"formName",n.$name)}return q}}function b(e,t,a){if(e)for(var r=0;rr;r++)t[a[r]]&&(t=t[a[r]]);return t}function A(e,t){for(var a=document.getElementsByName(e),r=null,n=0;n=0?S(i.name,t.scope):t.scope[i.name]))return"undefined"==typeof r.$name&&(r.$name=i.name),r}if(i&&i.name){var o={$name:i.name,specialNote:"Created by Angular-Validation for Isolated Scope usage"};if(k&&k.controllerAs&&i.name.indexOf(".")>=0){var l=i.name.split(".");return t.scope[l[0]][l[1]]=o}return t.scope[i.name]=o}return null}function E(e){return!isNaN(parseFloat(e))&&isFinite(e)}function x(e,t){var a="",r="-",n=[],i=[],o="",l="",s="";switch(t.toUpperCase()){case"EURO_LONG":case"EURO-LONG":a=e.substring(0,10),r=e.substring(2,3),n=N(a,r),s=n[0],l=n[1],o=n[2],i=e.length>8?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=N(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=N(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=N(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=N(a,r),o=n[0],l=n[1],s=n[2],i=e.length>10?e.substring(11).split(":"):null}var p=i&&3===i.length?i[0]:0,m=i&&3===i.length?i[1]:0,u=i&&3===i.length?i[2]:0;return new Date(o,l-1,s,p,m,u)}function N(e,t){var a=[];switch(t){case"/":a=e.split("/");break;case".":a=e.split(".");break;case"-":default:a=e.split("-")}return a}function R(e,t,a){var r=!1;switch(e){case"<":r=a>t?!0:!1;break;case"<=":r=a>=t?!0:!1;break;case">":r=t>a?!0:!1;break;case">=":r=t>=a?!0:!1;break;case"!=":case"<>":r=t!=a?!0:!1;break;case"!==":r=t!==a?!0:!1;break;case"=":case"==":r=t==a?!0:!1;break;case"===":r=t===a?!0:!1;break;default:r=!1}return r}function w(){return this.replace(/^\s+|\s+$/g,"")}function V(){var e=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(t,a){return e[a]?e[a]:t})}function F(e){var t=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return e.replace(/{(\d+)}/g,function(e,a){return t[a]?t[a]:e})}var T=1e3,L=[],k={resetGlobalOptionsOnRouteChange:!0},U=[],q=[];e.$on("$routeChangeStart",function(){k.resetGlobalOptionsOnRouteChange&&(k={displayOnlyLastErrorMsg:!1,preValidateFormElements:!1,isolatedScope:null,scope:null,resetGlobalOptionsOnRouteChange:!0},L=[],q=[])});var C=function(e,t,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=T,this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,e&&e.$validationOptions&&(k=e.$validationOptions),e&&(k.isolatedScope||k.scope)&&(this.scope=k.isolatedScope||k.scope,k=p(e.$validationOptions,k)),"undefined"==typeof k.resetGlobalOptionsOnRouteChange&&(k.resetGlobalOptionsOnRouteChange=!0),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&(v(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return C.prototype.arrayFindObject=b,C.prototype.defineValidation=r,C.prototype.getFormElementByName=n,C.prototype.getFormElements=i,C.prototype.getGlobalOptions=o,C.prototype.isFieldRequired=s,C.prototype.initialize=l,C.prototype.mergeObjects=p,C.prototype.removeFromValidationSummary=u,C.prototype.removeFromFormElementObjectList=m,C.prototype.setDisplayOnlyLastErrorMsg=d,C.prototype.setGlobalOptions=c,C.prototype.updateErrorMsg=f,C.prototype.validate=g,String.prototype.trim=w,String.prototype.format=V,String.format=F,C}]); +angular.module("ghiscoding.validation").factory("validationCommon",["$rootScope","$translate","validationRules",function(e,t,a){function r(){var e=this,t={};e.validators=[],e.typingLimit=T,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));var r=e.validatorAttrs.rules||e.validatorAttrs.validation;if(r.indexOf("pattern=/")>=0){var n=r.match(/pattern=(\/.*\/[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},r=r.replace("pattern="+i,"pattern")}else if(r.indexOf("regex:")>=0){var n=r.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 p=n[1].split(":=");t={message:p[0],pattern:p[1]},r=r.replace(n[0],"regex:")}var m=r.split("|");if(m){e.bFieldRequired=r.indexOf("required")>=0?!0:!1;for(var u=0,d=m.length;d>u;u++){var c=m[u].split(":"),f=m[u].indexOf("alt=")>=0?!0:!1;e.validators[u]=a.getElementValidators({altText:f===!0?2===c.length?c[1]:c[2]:"",customRegEx:t,rule:c[0],ruleParams:f&&2===c.length?null:c[1]})}}return e}function n(e){return b(L,"fieldName",e)}function i(e){return e?O(L,"formName",e):L}function o(){return k}function l(e,t,a,r){this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,v(t,a,r,e),this.defineValidation()}function s(){var e=this;return e.bFieldRequired}function p(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=$(L,"fieldName",e);t>=0&&L.splice(t,1)}function u(e,t){var a=this,r=A(e,a),n=t||q,i=$(n,"field",e);if(i>=0&&n.splice(i,1),i=$(q,"field",e),i>=0&&q.splice(i,1),a.scope.$validationSummary=q,r&&(r.$validationSummary=O(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=O(q,"formName",r.$name))}return q}function d(e){k.displayOnlyLastErrorMsg=e}function c(e){var t=this;return k=p(k,e),t}function f(e,a){var r=this;a&&a.obj&&(r=a.obj,r.validatorAttrs=a.obj.attrs);var n=a&&a.elm?a.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=a&&a.translate?t.instant(e):e,s=i.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),p=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var m=r.validatorAttrs.validationErrorTo.charAt(0),u="."===m||"#"===m?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;p=angular.element(document.querySelector(u))}p&&0!==p.length||(p=angular.element(document.querySelector(".validation-"+s)));var d=a&&a.isSubmitted?a.isSubmitted:!1;a&&!a.isValid&&(d||r.ctrl.$dirty||r.ctrl.$touched)?p.length>0?p.html(l):n.after(''+l+""):p.html("")}function g(e,a){var r,i,o=this,l=!0,s=!0,p="";"undefined"==typeof e&&(e="");for(var m=o.ctrl&&o.ctrl.$name?o.ctrl.$name:o.attrs&&o.attrs.name?o.attrs.name:o.elm.attr("name"),u=n(m),d=o.validatorAttrs.rules||o.validatorAttrs.validation,c=0,f=o.validators.length;f>c;c++){if(i=o.validators[c],"autoDetect"===i.type&&(i=E(e)?{condition:i.conditionNum,message:i.messageNum,params:i.params,type:"conditionalNumber"}:{pattern:i.patternLength,message:i.messageLength,params:i.params,type:"regex"}),"conditionalDate"===i.type){var g=l=!1;if(e instanceof Date?g=!0:(r=new RegExp(i.pattern),g=(!i.pattern||"/\\S+/"===i.pattern.toString()||d&&"required"===i.pattern)&&null===e?!1:r.test(e)),g){var v=i.dateType,b=e instanceof Date?e:x(e,v).getTime();if(2==i.params.length){var O=x(i.params[0],v).getTime(),$=x(i.params[1],v).getTime(),S=R(i.condition[0],b,O),A=R(i.condition[1],b,$);l=S&&A?!0:!1}else{var N=x(i.params[0],v).getTime();l=R(i.condition,b,N)}}}else if("conditionalNumber"===i.type)if(2==i.params.length){var S=R(i.condition[0],parseFloat(e),parseFloat(i.params[0])),A=R(i.condition[1],parseFloat(e),parseFloat(i.params[1]));l=S&&A?!0:!1}else l=R(i.condition,parseFloat(e),parseFloat(i.params[0]));else if("matching"===i.type){var w=i.params[0],V=o.scope.$eval(w),F=angular.element(document.querySelector('[name="'+w+'"]'));l=R(i.condition,e,V)&&!!e,F&&F.attr("friendly-name")?i.params[1]=F.attr("friendly-name"):i.params.length>1&&(i.params[1]=i.params[1])}else if("remote"===i.type){if(e&&a){o.ctrl.$processing=!0;var T=null,L=i.params[0];if(-1===L.indexOf("."))T=o.scope[L];else{var q=L.split(".");T=o.scope;for(var C=0,G=q.length;G>C;C++)T=T[q[C]]}var M="function"==typeof T?T():null;if(U.length>1)for(;U.length>0;){var j=U.pop();"function"==typeof j.abort&&j.abort()}if(U.push(M),!M||"function"!=typeof M.then)throw"Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";o.ctrl.$setValidity("remote",!1),function(e){M.then(function(t){t=t.data||t,U.pop(),o.ctrl.$processing=!1;var r=p+" ";"boolean"==typeof t?l=t?!0:!1:"object"==typeof t&&(l=t.isValid?!0:!1),l===!1&&(u.isValid=!1,r+=t.message||e,h(o,u,r,!1,a)),l===!0&&s===!0&&(u.isValid=!0,o.ctrl.$setValidity("remote",!0),h(o,u,"",!0,a))})}(i.altText)}}else{var D=o.attrs?o.attrs.ngDisabled:o.validatorAttrs.ngDisabled;o.elm.prop("disabled")||o.scope.$eval(D)?l=!0:"string"==typeof e&&""===e&&"NUMBER"===o.elm.prop("type").toUpperCase()?l=!1:(r=new RegExp(i.pattern),l=(!i.pattern||"/\\S+/"===i.pattern.toString()||d&&"required"===i.pattern)&&null===e?!1:r.test(e))}(!o.bFieldRequired&&!e||o.elm.prop("disabled")||o.scope.$eval(D))&&(l=!0),l||(s=!1,function(e,r,n){var i=n.message;n.altText&&n.altText.length>0&&(i=n.altText.replace("alt=","")),t(i).then(function(t){p.length>0&&k.displayOnlyLastErrorMsg?p=" "+(n&&n.params?String.format(t,n.params):t):p+=" "+(n&&n.params?String.format(t,n.params):t),h(o,e,p,s,a)})["catch"](function(){n.altText&&n.altText.length>0&&(p.length>0&&k.displayOnlyLastErrorMsg?p=" "+i:p+=" "+i,h(o,e,p,s,a))})}(u,l,i))}return l&&(y(o,""),o.updateErrorMsg("",{isValid:l})),u&&(u.isValid=s,s&&(u.message="")),s}function v(e,a,r,n){var i=a.name?a.name:e.attr("name"),o=A(i,{scope:n}),l=a&&a.friendlyName?t.instant(a.friendlyName):"",s={fieldName:i,friendlyName:l,elm:e,attrs:a,ctrl:r,scope:n,isValid:!1,message:"",formName:o?o.$name:null},p=$(L,"fieldName",e.attr("name"));return p>=0?L[p]=s:L.push(s),L}function h(e,t,a,r,n){a=a.trim(),y(t,a),t&&(t.message=a),(e.validatorAttrs.preValidateFormElements||k.preValidateFormElements)&&(t&&"function"==typeof e.ctrl.$setTouched&&t.ctrl.$setTouched(),e.ctrl.$dirty===!1&&f(a,{isSubmitted:!0,isValid:r,obj:t})),n&&t&&!t.isValid?e.updateErrorMsg(a,{isValid:r}):t&&t.isValid&&y(t,"")}function y(e,a){if("undefined"!=typeof e&&null!=e){var r=e.ctrl&&e.ctrl.$name?e.ctrl.$name:e.attrs&&e.attrs.name?e.attrs.name:e.elm.attr("name"),n=A(r,e),i=$(q,"field",r);if(i>=0&&""===a)q.splice(i,1);else if(""!==a){var o=e.attrs&&e.friendlyName?t.instant(e.friendlyName):"",l={field:r,friendlyName:o,message:a,formName:n?n.$name:null};i>=0?q[i]=l:q.push(l)}if(e.scope.$validationSummary=q,n&&(n.$validationSummary=O(q,"formName",n.$name)),k&&k.controllerAs&&(k.controllerAs.$validationSummary=q,n)){var s=n.$name.indexOf(".")>=0?n.$name.split(".")[1]:n.$name,p=k.controllerAs[s]?k.controllerAs[s]:e.elm.controller()[s];p.$validationSummary=O(q,"formName",n.$name)}return q}}function b(e,t,a){if(e)for(var r=0;rr;r++)t[a[r]]&&(t=t[a[r]]);return t}function A(e,t){for(var a=document.getElementsByName(e),r=null,n=0;n=0?S(i.name,t.scope):t.scope[i.name]))return"undefined"==typeof r.$name&&(r.$name=i.name),r}if(i&&i.name){var o={$name:i.name,specialNote:"Created by Angular-Validation for Isolated Scope usage"};if(k&&k.controllerAs&&i.name.indexOf(".")>=0){var l=i.name.split(".");return t.scope[l[0]][l[1]]=o}return t.scope[i.name]=o}return null}function E(e){return!isNaN(parseFloat(e))&&isFinite(e)}function x(e,t){var a="",r="-",n=[],i=[],o="",l="",s="";switch(t.toUpperCase()){case"EURO_LONG":case"EURO-LONG":a=e.substring(0,10),r=e.substring(2,3),n=N(a,r),s=n[0],l=n[1],o=n[2],i=e.length>8?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=N(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=N(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=N(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=N(a,r),o=n[0],l=n[1],s=n[2],i=e.length>10?e.substring(11).split(":"):null}var p=i&&3===i.length?i[0]:0,m=i&&3===i.length?i[1]:0,u=i&&3===i.length?i[2]:0;return new Date(o,l-1,s,p,m,u)}function N(e,t){var a=[];switch(t){case"/":a=e.split("/");break;case".":a=e.split(".");break;case"-":default:a=e.split("-")}return a}function R(e,t,a){var r=!1;switch(e){case"<":r=a>t?!0:!1;break;case"<=":r=a>=t?!0:!1;break;case">":r=t>a?!0:!1;break;case">=":r=t>=a?!0:!1;break;case"!=":case"<>":r=t!=a?!0:!1;break;case"!==":r=t!==a?!0:!1;break;case"=":case"==":r=t==a?!0:!1;break;case"===":r=t===a?!0:!1;break;default:r=!1}return r}function w(){return this.replace(/^\s+|\s+$/g,"")}function V(){var e=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(t,a){return e[a]?e[a]:t})}function F(e){var t=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return e.replace(/{(\d+)}/g,function(e,a){return t[a]?t[a]:e})}var T=1e3,L=[],k={resetGlobalOptionsOnRouteChange:!0},U=[],q=[];e.$on("$routeChangeStart",function(){k.resetGlobalOptionsOnRouteChange&&(k={displayOnlyLastErrorMsg:!1,preValidateFormElements:!1,isolatedScope:null,scope:null,resetGlobalOptionsOnRouteChange:!0},L=[],q=[])});var C=function(e,t,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=T,this.scope=e,this.elm=t,this.ctrl=r,this.validatorAttrs=a,e&&e.$validationOptions&&(k=e.$validationOptions),e&&(k.isolatedScope||k.scope)&&(this.scope=k.isolatedScope||k.scope,k=p(e.$validationOptions,k)),"undefined"==typeof k.resetGlobalOptionsOnRouteChange&&(k.resetGlobalOptionsOnRouteChange=!0),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&(v(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return C.prototype.arrayFindObject=b,C.prototype.defineValidation=r,C.prototype.getFormElementByName=n,C.prototype.getFormElements=i,C.prototype.getGlobalOptions=o,C.prototype.isFieldRequired=s,C.prototype.initialize=l,C.prototype.mergeObjects=p,C.prototype.removeFromValidationSummary=u,C.prototype.removeFromFormElementObjectList=m,C.prototype.setDisplayOnlyLastErrorMsg=d,C.prototype.setGlobalOptions=c,C.prototype.updateErrorMsg=f,C.prototype.validate=g,String.prototype.trim=w,String.prototype.format=V,String.format=F,C}]); 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,r={};switch(s){case"accepted":r={pattern:/^(yes|on|1|true)$/i,message:"INVALID_ACCEPTED",type:"regex"};break;case"alpha":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ])+$/i,message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ\s])+$/i,message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9])+$/i,message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s])+$/i,message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9_-])+$/i,message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":r={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s_-])+$/i,message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"between":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between:1,5";r={patternLength:"^(.|[\\r\\n]){"+_[0]+","+_[1]+"}$",messageLength:"INVALID_BETWEEN_CHAR",conditionNum:[">=","<="],messageNum:"INVALID_BETWEEN_NUM",params:[_[0],_[1]],type:"autoDetect"};break;case"betweenLen":case"between_len":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";r={pattern:"^(.|[\\r\\n]){"+_[0]+","+_[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[_[0],_[1]],type:"regex"};break;case"betweenNum":case"between_num":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";r={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[_[0],_[1]],type:"conditionalNumber"};break;case"boolean":r={pattern:/^(true|false|0|1)$/i,message:"INVALID_BOOLEAN",type:"regex"};break;case"checked":r={pattern:/^true$/i,message:"INVALID_CHECKBOX_SELECTED",type:"regex"};break;case"creditCard":case"credit_card":r={pattern:/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})$/,message:"INVALID_CREDIT_CARD",type:"regex"};break;case"dateEuroLong":case"date_euro_long":r={pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_EURO_LONG",type:"regex"};break;case"dateEuroLongBetween":case"date_euro_long_between":case"betweenDateEuroLong":case"between_date_euro_long":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_long:01-01-1990,31-12-2015";r={condition:[">=","<="],dateType:"EURO_LONG",params:[_[0],_[1]],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_EURO_LONG_BETWEEN",type:"conditionalDate"};break;case"dateEuroLongMax":case"date_euro_long_max":case"maxDateEuroLong":case"max_date_euro_long":r={condition:"<=",dateType:"EURO_LONG",params:[n],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_EURO_LONG_MAX",type:"conditionalDate"};break;case"dateEuroLongMin":case"date_euro_long_min":case"minDateEuroLong":case"min_date_euro_long":r={condition:">=",dateType:"EURO_LONG",params:[n],pattern:/^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_EURO_LONG_MIN",type:"conditionalDate"};break;case"dateEuroShort":case"date_euro_short":r={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 _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_short:01-01-90,31-12-15";r={condition:[">=","<="],dateType:"EURO_SHORT",params:[_[0],_[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":r={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":r={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":r={pattern:/^(19|20)\d\d([-])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/,message:"INVALID_DATE_ISO",type:"regex"};break;case"dateIsoBetween":case"date_iso_between":case"betweenDateIso":case"between_date_iso":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_iso:1990-01-01,2000-12-31";r={condition:[">=","<="],dateType:"ISO",params:[_[0],_[1]],pattern:/^(19|20)\d\d([-])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/,message:"INVALID_DATE_ISO_BETWEEN",type:"conditionalDate"};break;case"dateIsoMax":case"date_iso_max":case"maxDateIso":case"max_date_iso":r={condition:"<=",dateType:"ISO",params:[n],pattern:/^(19|20)\d\d([-])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/,message:"INVALID_DATE_ISO_MAX",type:"conditionalDate"};break;case"dateIsoMin":case"date_iso_min":case"minDateIso":case"min_date_iso":r={condition:">=",dateType:"ISO",params:[n],pattern:/^(19|20)\d\d([-])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/,message:"INVALID_DATE_ISO_MIN",type:"conditionalDate"};break;case"dateUsLong":case"date_us_long":r={pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_US_LONG",type:"regex"};break;case"dateUsLongBetween":case"date_us_long_between":case"betweenDateUsLong":case"between_date_us_long":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_long:01/01/1990,12/31/2015";r={condition:[">=","<="],dateType:"US_LONG",params:[_[0],_[1]],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_US_LONG_BETWEEN",type:"conditionalDate"};break;case"dateUsLongMax":case"date_us_long_max":case"maxDateUsLong":case"max_date_us_long":r={condition:"<=",dateType:"US_LONG",params:[n],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_US_LONG_MAX",type:"conditionalDate"};break;case"dateUsLongMin":case"date_us_long_min":case"minDateUsLong":case"min_date_us_long":r={condition:">=",dateType:"US_LONG",params:[n],pattern:/^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.](19|20)\d\d$/,message:"INVALID_DATE_US_LONG_MIN",type:"conditionalDate"};break;case"dateUsShort":case"date_us_short":r={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 _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_short:01/01/90,12/31/15";r={condition:[">=","<="],dateType:"US_SHORT",params:[_[0],_[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":r={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":r={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(",");r={condition:"!=",message:"INVALID_INPUT_DIFFERENT",params:e,type:"matching"};break;case"digits":r={pattern:"^\\d{"+n+"}$",message:"INVALID_DIGITS",params:[n],type:"regex"};break;case"digitsBetween":case"digits_between":var _=n.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: digits_between:1,5";r={pattern:"^\\d{"+_[0]+","+_[1]+"}$",message:"INVALID_DIGITS_BETWEEN",params:[_[0],_[1]],type:"regex"};break;case"email":r={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":r={pattern:"^(.|[\\r\\n]){"+n+"}$",message:"INVALID_EXACT_LEN",params:[n],type:"regex"};break;case"float":r={pattern:/^\d*\.{1}\d+$/,message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":r={pattern:/^[-+]?\d*\.{1}\d+$/,message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":r={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"in":case"inList":case"in_list":var c=n.replace(/,/g,"|");r={pattern:"^(\\b("+c+")\\b)$",message:"INVALID_IN_LIST",params:[n],type:"regex"};break;case"int":case"integer":r={pattern:/^\d+$/,message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":r={pattern:/^[+-]?\d+$/,message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ip":case"ipv4":r={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":r={pattern:/^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/i,message:"INVALID_IPV6",type:"regex"};break;case"match":case"matchInput":case"match_input":case"same":var e=n.split(",");r={condition:"===",message:"INVALID_INPUT_MATCH",params:e,type:"matching"};break;case"max":r={patternLength:"^(.|[\\r\\n]){0,"+n+"}$",messageLength:"INVALID_MAX_CHAR",conditionNum:"<=",messageNum:"INVALID_MAX_NUM",params:[n],type:"autoDetect"};break;case"maxLen":case"max_len":r={pattern:"^(.|[\\r\\n]){0,"+n+"}$",message:"INVALID_MAX_CHAR",params:[n],type:"regex"};break;case"maxNum":case"max_num":r={condition:"<=",message:"INVALID_MAX_NUM",params:[n],type:"conditionalNumber"};break;case"min":r={patternLength:"^(.|[\\r\\n]){"+n+",}$",messageLength:"INVALID_MIN_CHAR",conditionNum:">=",messageNum:"INVALID_MIN_NUM",params:[n],type:"autoDetect"};break;case"minLen":case"min_len":r={pattern:"^(.|[\\r\\n]){"+n+",}$",message:"INVALID_MIN_CHAR",params:[n],type:"regex"};break;case"minNum":case"min_num":r={condition:">=",message:"INVALID_MIN_NUM",params:[n],type:"conditionalNumber"};break;case"notIn":case"not_in":case"notInList":case"not_in_list":var c=n.replace(/,/g,"|");r={pattern:"^((?!\\b("+c+")\\b).)+$",message:"INVALID_NOT_IN_LIST",params:[n],type:"regex"};break;case"numeric":r={pattern:/^\d*\.?\d+$/,message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":r={pattern:/^[-+]?\d*\.?\d+$/,message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"pattern":case"regex":r={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"remote":r={message:"",params:[n],type:"remote"};break;case"required":r={pattern:/\S+/,message:"INVALID_REQUIRED",type:"regex"};break;case"size":r={patternLength:"^(.|[\\r\\n]){"+n+"}$",messageLength:"INVALID_EXACT_LEN",conditionNum:"==",messageNum:"INVALID_EXACT_NUM",params:[n],type:"autoDetect"};break;case"url":r={pattern:/^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i,message:"INVALID_URL",type:"regex"};break;case"time":r={pattern:/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/,message:"INVALID_TIME",type:"regex"}}return r.altText=a,r}var a={getElementValidators:e};return a}]); angular.module("ghiscoding.validation").service("validationService",["$interpolate","$timeout","validationCommon",function(e,o,t){function n(t,n,a){var i=this,m={};if("string"==typeof t&&"string"==typeof n?(m.elmName=t,m.rules=n,m.friendlyName="string"==typeof a?a:""):m=t,"object"!=typeof m||!m.hasOwnProperty("elmName")||!m.hasOwnProperty("rules")||!m.hasOwnProperty("scope")&&"undefined"==typeof i.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";var r=m.scope?m.scope:i.validationAttrs.scope;if(m.elm=angular.element(document.querySelector('[name="'+m.elmName+'"]')),"object"!=typeof m.elm||0===m.elm.length)return i;if(new RegExp("{{(.*?)}}").test(m.elmName)&&(m.elmName=e(m.elmName)(r)),m.name=m.elmName,i.validationAttrs.isolatedScope){var l=r.$validationOptions||null;r=i.validationAttrs.isolatedScope,l&&(r.$validationOptions=l)}m.elm.bind("blur",p=function(e){var o=i.commonObj.getFormElementByName(m.elmName);o&&!o.isValidationCancelled&&(i.commonObj.initialize(r,m.elm,m,m.ctrl),d(i,e.target.value,10))}),m=i.commonObj.mergeObjects(i.validationAttrs,m),f(i,r,m),m.elm.on("$destroy",function(){var e=i.commonObj.getFormElementByName(i.commonObj.ctrl.$name);e&&(s(i,e),i.commonObj.removeFromValidationSummary(m.name))});var c=r.$watch(m.elmName,function(e,t){return void 0===e&&void 0!==t?(o.cancel(i.timer),void i.commonObj.ctrl.$setValidity("validation",i.commonObj.validate("",!0))):(m.ctrl=angular.element(m.elm).controller("ngModel"),m.value=e,i.commonObj.initialize(r,m.elm,m,m.ctrl),void d(i,e))},!0);return v.push({elmName:m.elmName,watcherHandler:c}),i}function a(e){var o=this,t="",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 a=0,i=e.$validationSummary.length;i>a;a++)if(n=!1,t=e.$validationSummary[a].field){var m=o.commonObj.getFormElementByName(t);m&&m.elm&&m.elm.length>0&&("function"==typeof m.ctrl.$setTouched&&m.ctrl.$setTouched(),o.commonObj.updateErrorMsg(e.$validationSummary[a].message,{isSubmitted:!0,isValid:m.isValid,obj:m}))}return n}function i(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=[],n=0,a=e.$validationSummary.length;a>n;n++)t.push(e.$validationSummary[n].field);for(n=0,a=t.length;a>n;n++)t[n]&&(o.commonObj.removeFromFormElementObjectList(t[n]),o.commonObj.removeFromValidationSummary(t[n],e.$validationSummary))}function m(e,o){var t,n=this;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"removeValidator() only works with Validation that were defined by the Service (not by the Directive) and 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)";if(o instanceof Array)for(var a=0,i=o.length;i>a;a++)t=n.commonObj.getFormElementByName(o[a]),t.elm.removeAttr("validation"),u(n,t,e.$validationSummary);else o instanceof Object&&o.formElmObj?(t=o.formElmObj,t.elm.removeAttr("validation"),u(o.self,t,e.$validationSummary)):(t=n.commonObj.getFormElementByName(o),t.elm.removeAttr("validation"),u(n,t,e.$validationSummary));return n}function r(e,o){var t,n=this,o=o||{},a="undefined"!=typeof o.removeAllValidators?o.removeAllValidators:!1,i="undefined"!=typeof o.emptyAllInputValues?o.emptyAllInputValues:!1;if("undefined"==typeof e||"undefined"==typeof e.$name)throw"resetForm() requires a valid Angular Form object passed as argument to work properly (ex.: $scope.form1).";var r=n.commonObj.getFormElements(e.$name);if(r instanceof Array)for(var l=0,c=r.length;c>l;l++)t=r[l],i&&t.elm.val(null),a?m(e,{self:n,formElmObj:t}):("function"==typeof t.ctrl.$setUntouched&&t.ctrl.$setUntouched(),t.ctrl.$setPristine(),n.commonObj.updateErrorMsg("",{isValid:!1,obj:t}))}function l(e){var o=this,t="boolean"==typeof e?e:!0;o.commonObj.setDisplayOnlyLastErrorMsg(t)}function c(e){var o=this;return o.validationAttrs=e,o.commonObj.setGlobalOptions(e),o}function d(e,t,n){var a="undefined"!=typeof n?n:e.commonObj.typingLimit,i=e.commonObj.getFormElementByName(e.commonObj.ctrl.$name);return e.commonObj.validate(t,!1),e.commonObj.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?(i.isValidationCancelled=!1,(e.commonObj.isFieldRequired()||t)&&e.commonObj.ctrl.$setValidity("validation",!1),""!==t&&"undefined"!=typeof t||"NUMBER"!==e.commonObj.elm.prop("type").toUpperCase()?"SELECT"===e.commonObj.elm.prop("tagName").toUpperCase()?(e.commonObj.ctrl.$setValidity("validation",e.commonObj.validate(t,!0)),t):("undefined"!=typeof t&&(e.commonObj.updateErrorMsg(""),o.cancel(e.timer),e.timer=o(function(){e.commonObj.scope.$evalAsync(e.commonObj.ctrl.$setValidity("validation",e.commonObj.validate(t,!0)))},a)),t):(o.cancel(e.timer),e.commonObj.ctrl.$setValidity("validation",e.commonObj.validate(t,!0)),t)):(s(e,i),t)}function s(e,t){var n=t&&t.ctrl?t.ctrl:e.commonObj.ctrl;if(t&&(t.isValidationCancelled=!0),o.cancel(self.timer),n.$setValidity("validation",!0),e.commonObj.updateErrorMsg("",{isValid:!0,obj:t}),"function"==typeof p){var a=t&&t.elm?t.elm:e.commonObj.elm;a.unbind("blur",p)}}function u(e,o,t){var n=e.commonObj.scope?e.commonObj.scope:o.scope?o.scope:null;if("undefined"==typeof n)throw"removeValidator() requires a valid $scope object passed but unfortunately could not find it.";var a=e.commonObj.arrayFindObject(v,"elmName",o.fieldName);a&&a.watcherHandler(),o.isValidationCancelled=!0,o.isValid=!0,o.attrs.validation="",s(e,o),"function"==typeof o.ctrl.$setUntouched&&o.ctrl.$setUntouched(),e.commonObj.scope=n,o.ctrl.$setPristine(),e.commonObj.removeFromValidationSummary(o.fieldName,t)}function f(e,t,n){t.$watch(function(){return"undefined"==typeof n.elm.attr("ng-disabled")?null:t.$eval(n.elm.attr("ng-disabled"))},function(a){if("undefined"==typeof a||null===a)return null;n.ctrl=angular.element(n.elm).controller("ngModel"),e.commonObj.initialize(t,n.elm,n,n.ctrl);var i=e.commonObj.getFormElementByName(n.name);o(function(){if(a)n.ctrl.$setValidity("validation",!0),e.commonObj.updateErrorMsg("",{isValid:!0,obj:i}),e.commonObj.removeFromValidationSummary(n.name);else{var o=n.ctrl.$viewValue||"";e.commonObj.initialize(t,n.elm,n,n.ctrl),n.ctrl.$setValidity("validation",e.commonObj.validate(o,!1)),i&&(i.isValidationCancelled=!1),n.elm.bind("blur",p=function(o){i&&!i.isValidationCancelled&&d(e,o.target.value,10)})}},0,!1),a&&("function"==typeof n.ctrl.$setUntouched&&n.ctrl.$setUntouched(),n.ctrl.$setValidity("validation",!0),e.commonObj.removeFromValidationSummary(n.name))})}var p,v=[],y=function(e){this.isValidationCancelled=!1,this.timer=null,this.validationAttrs={},this.commonObj=new t,e&&this.setGlobalOptions(e)};return y.prototype.addValidator=n,y.prototype.checkFormValidity=a,y.prototype.removeValidator=m,y.prototype.resetForm=r,y.prototype.setDisplayOnlyLastErrorMsg=l,y.prototype.setGlobalOptions=c,y.prototype.clearInvalidValidatorsInSummary=i,y}]); \ No newline at end of file diff --git a/package.json b/package.json index 8a03ae7..448d18b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-validation-ghiscoding", - "version": "1.4.4", + "version": "1.4.5", "author": "Ghislain B.", "description": "Angular-Validation Directive and Service (ghiscoding)", "main": "app.js", diff --git a/readme.md b/readme.md index 020d54a..9e6d882 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ #Angular Validation (Directive / Service) -`Version: 1.4.4` +`Version: 1.4.5` ### Form validation after user inactivity of default 1sec. (customizable timeout) Forms Validation with Angular made easy! Angular-Validation is an angular directive/service with locales (languages) with a very simple approach of defining your `validation=""` directly within your element to validate (input, textarea, etc) and...that's it!!! The directive/service will take care of the rest! @@ -8,7 +8,7 @@ The base concept is not new, it comes from the easy form input validation approa For a smoother user experience, I also added validation on inactivity (timer/debounce). So validation will not bother the user while he is still typing... though as soon as the user pauses for a certain amount of time, then validation comes into play. It's worth knowing that this inactivity timer is only available while typing, if user focuses away from his input (onBlur) it will then validate instantly. -Supporting AngularJS 1.3.x *(current code should work with 1.2.x just the same, but is no more verified)* +Supporting AngularJS 1.3/1.4 branch *(current code should work with 1.2.x just the same, but is no more verified)* Now support Service using the same functionalities as the Directive. Huge rewrite to have a better code separation and also adding support to Service functionalities. Specifically the `validation-rules` was separated to add rules without affecting the core while `validation-common` is for shared functions (shared by Directive/Service). diff --git a/src/validation-common.js b/src/validation-common.js index e4ba07e..a59cc8c 100644 --- a/src/validation-common.js +++ b/src/validation-common.js @@ -119,7 +119,7 @@ angular // 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 if(rules.indexOf("pattern=/") >= 0) { - var matches = rules.match(/pattern=(\/.*?\/[igm]*)(:alt=(.*))?/); + var matches = rules.match(/pattern=(\/.*\/[igm]*)(:alt=(.*))?/); if (!matches || matches.length < 3) { throw 'Regex validator within the validation needs to be define with an opening "/" and a closing "/", please review your validator.'; }