diff --git a/app.js b/app.js
index e5744b4..b2032ba 100644
--- a/app.js
+++ b/app.js
@@ -38,7 +38,12 @@ myApp.controller('Ctrl', ['$location', '$route', '$scope', '$translate', functio
// -- Controller to use Angular-Validation Directive
// -----------------------------------------------
myApp.controller('CtrlValidationDirective', ['$q', '$scope', 'validationService', function ($q, $scope, validationService) {
- $scope.$validationOptions = { debounce: 1500, preValidateFormElements: false }; // you can change default debounce globally
+ // you can change default debounce globally
+ $scope.$validationOptions = { debounce: 1500, preValidateFormElements: false };
+
+ // if we want to use the invalid_pattern_data locale translation as an alternateText (:alt=)
+ // then we need to supply an extra 'data' variable (as defined in the JSON locale) of what we expect the search pattern on our input4
+ $scope.translationData = { data: 'YYWW' };
// remove a single element ($scope.form1, string)
// OR you can also remove multiple elements through an array type .removeValidator($scope.form1, ['input2','input3'])
@@ -122,7 +127,7 @@ myApp.controller('CtrlValidationService', ['$q', '$scope', '$translate', 'valida
.setGlobalOptions({ debounce: 1500, scope: $scope, isolatedScope: $scope, preValidateFormElements: false, displayOnlyLastErrorMsg: false })
.addValidator({ elmName: 'input2', debounce: 3000, rules: 'numeric_signed|required'})
.addValidator('input3', 'float_signed|between_num:-0.6,99.5|required')
- .addValidator('input4', 'exact_len:4|regex:YYWW:=^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$:regex|required|integer')
+ .addValidator('input4', 'exact_len:4|pattern=/^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$/:alt=' + $translate.instant('INVALID_PATTERN_DATA', { data: 'YYWW' }) + '|required|integer')
.addValidator('input5', 'email|required|min_len:6', $translate.instant('INPUT5')) // 3rd argument being the Friendly name
.addValidator('input6', 'url|required')
.addValidator('input7', 'ipv4|required')
diff --git a/bower.json b/bower.json
index d5b670b..15556e2 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "angular-validation-ghiscoding",
- "version": "1.3.34",
+ "version": "1.3.35",
"author": "Ghislain B.",
"description": "Angular-Validation Directive and Service (ghiscoding)",
"main": [
diff --git a/changelog.txt b/changelog.txt
index f0041ef..6d50dd7 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,6 @@
Angular-Validation change logs
+1.3.35 (2015-07-15) Deprecated old implentation of `regex:...:regex` (though it still works) by a new and much better implementation of `pattern=` validator. Converted all the rules from string pattern to regex pattern (when possible) defined in `angular-validation.js`. Also fixed issue #45 on email check.
1.3.34 (2015-07-08) Merge pull request #44 - Adding support to brazilian portuguese language.
1.3.33 (2015-07-02) Reset isolatedScope on route change
1.3.32 (2015-06-24) Merged pull request #41 and fixed errors inside it, updated Protractor test as well.
diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js
index b693ff5..5e85663 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.3.34
+ * @version: 1.3.35
* @license: MIT
- * @build: Wed Jul 08 2015 18:33:00 GMT-0400 (Eastern Daylight Time)
+ * @build: Wed Jul 15 2015 19:20:38 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(t,a,n,d){function l(){var i=s.getFormElementByName(d.$name);i.isValidationCancelled=!0,e.cancel(r),s.updateErrorMsg(""),d.$setValidity("validation",!0),"function"==typeof u&&a.unbind("blur",u)}function o(i,n){var o="undefined"!=typeof n?n:s.typingLimit,u=s.getFormElementByName(d.$name);return s.validate(i,!1),s.isFieldRequired()||""!==i&&null!==i&&"undefined"!=typeof i?(u&&(u.isValidationCancelled=!1),(i||s.isFieldRequired())&&d.$setValidity("validation",!1),""!==i&&"undefined"!=typeof i||"NUMBER"!==a.prop("type").toUpperCase()?"SELECT"===a.prop("tagName").toUpperCase()?(d.$setValidity("validation",s.validate(i,!0)),i):("undefined"!=typeof i&&(s.updateErrorMsg(""),e.cancel(r),r=e(function(){t.$evalAsync(d.$setValidity("validation",s.validate(i,!0)))},o)),i):(e.cancel(r),d.$setValidity("validation",s.validate(i,!0)),i)):(l(),i)}var r,u,s=new i(t,a,n,d);d.$formatters.unshift(o),d.$parsers.unshift(o),n.$observe("disabled",function(e){if(e)l(),s.removeFromValidationSummary(n.name);else{"function"==typeof d.$setTouched&&d.$setTouched();var i=d.$viewValue||"";d.$setValidity("validation",s.validate(i,!0))}}),t.$watch(function(){return a.attr("validation")},function(e){("undefined"==typeof e||""===e)&&(d.$formatters.shift(),d.$parsers.shift(),l())}),a.bind("blur",u=function(e){var i=s.getFormElementByName(d.$name);i.isValidationCancelled?d.$setValidity("validation",!0):o(e.target.value,0)})}}}]);
-angular.module("ghiscoding.validation").factory("validationCommon",["$rootScope","$timeout","$translate","validationRules",function(t,e,a,r){function i(){var t=this,e={};t.validators=[],t.typingLimit=F,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")?t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10):U&&U.hasOwnProperty("debounce")&&(t.typingLimit=parseInt(U.debounce,10));var a=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(a.indexOf("regex:")>=0){var i=a.match("regex:(.*?):regex");if(i.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 n=i[1].split(":=");e={message:n[0],pattern:n[1]},a=a.replace(i[0],"regex:")}var s=a.split("|");if(s){t.bFieldRequired=a.indexOf("required")>=0?!0:!1;for(var o=0,l=s.length;l>o;o++){var p=s[o].split(":"),d=s[o].indexOf("alt=")>=0?!0:!1;t.validators[o]=r.getElementValidators({altText:d===!0?2===p.length?p[1]:p[2]:"",customRegEx:e,rule:p[0],ruleParams:d&&2===p.length?null:p[1]})}}return t}function n(t){return O(L,"fieldName",t)}function s(t){return t?$(L,"formName",t):L}function o(t,e,a,r){this.scope=t,this.elm=e,this.ctrl=r,this.validatorAttrs=a,h(e,a,r,t),this.defineValidation()}function l(){var t=this;return t.bFieldRequired}function p(t,e){var a={};for(var r in t)a[r]=t[r];for(var r in e)a[r]=e[r];return a}function d(t){var e=S(L,"fieldName",t);e>=0&&L.splice(e,1)}function u(t,e){var a=this,r=E(t,a),i=e?e:q,n=S(i,"field",t);return n>=0&&i.splice(n,1),n=S(q,"field",t),n>=0&&q.splice(n,1),a.scope.$validationSummary=q,r&&(r.$validationSummary=$(q,"formName",r.$name)),q}function c(t){w=t}function m(t){U.displayOnlyLastErrorMsg=t}function f(t){var e=this;return U=p(U,t),e}function g(t,e){var r=this;e&&e.obj&&(r=e.obj,r.validatorAttrs=e.obj.attrs);var i=e&&e.elm?e.elm:r.elm,n=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof n||null===n){var s=i?i.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="'+s+'"'}var o=e&&e.translate?a.instant(t):t,l=n.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),p=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),u="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;p=angular.element(document.querySelector(u))}p&&0!==p.length||(p=angular.element(document.querySelector(".validation-"+l)));var c=e&&e.isSubmitted?e.isSubmitted:!1;e&&!e.isValid&&(c||r.ctrl.$dirty||r.ctrl.$touched)?p.length>0?p.text(o):i.after(''+o+""):p.text("")}function v(t,e){var r,i,s=this,o=!0,l=!0,p="";"undefined"==typeof t&&(t="");for(var d=s.ctrl&&s.ctrl.$name?s.ctrl.$name:s.attrs&&s.attrs.name?s.attrs.name:s.elm.attr("name"),u=n(d),c=s.validatorAttrs.hasOwnProperty("rules")?s.validatorAttrs.rules:s.validatorAttrs.validation,m=0,f=s.validators.length;f>m;m++){if(i=s.validators[m],"conditionalDate"===i.type){if(r=new RegExp(i.pattern,"i"),o=("\\S+"===i.pattern||c&&"required"===i.pattern)&&null===t?!1:r.test(t)){var g=i.dateType,v=A(t,g).getTime();if(2==i.params.length){var h=A(i.params[0],g).getTime(),O=A(i.params[1],g).getTime(),$=N(i.condition[0],v,h),S=N(i.condition[1],v,O);o=$&&S?!0:!1}else{var E=A(i.params[0],g).getTime();o=N(i.condition,v,E)}}}else if("conditionalNumber"===i.type)if(2==i.params.length){var $=N(i.condition[0],parseFloat(t),parseFloat(i.params[0])),S=N(i.condition[1],parseFloat(t),parseFloat(i.params[1]));o=$&&S?!0:!1}else o=N(i.condition,parseFloat(t),parseFloat(i.params[0]));else if("match"===i.type){var x=i.params[0],R=s.scope.$eval(x);o=R===t&&!!t}else if("remote"===i.type){if(t&&e){s.ctrl.$processing=!0;var V=null,T=i.params[0];if(-1===T.indexOf("."))V=s.scope[T];else{var w=T.split(".");V=s.scope;for(var F=0,L=w.length;L>F;F++)V=V[w[F]]}var q="function"==typeof V?V():null;if(k.length>1)for(;k.length>0;){var M=k.pop();"function"==typeof M.abort&&M.abort()}if(k.push(q),!q||"function"!=typeof q.then)throw"Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";s.ctrl.$setValidity("remote",!1),function(t){q.then(function(a){a=a.data||a,k.pop(),s.ctrl.$processing=!1;var r=p+" ";"boolean"==typeof a?o=a?!0:!1:"object"==typeof a&&(o=a.isValid?!0:!1),o===!1&&(u.isValid=!1,r+=a.message?a.message:t,y(s,u,r,!1,e)),o===!0&&l===!0&&(u.isValid=!0,s.ctrl.$setValidity("remote",!0),y(s,u,"",!0,e))})}(i.altText)}}else{var P="undefined"!=typeof s.attrs?s.attrs.ngDisabled:s.validatorAttrs.ngDisabled;s.elm.prop("disabled")||s.scope.$eval(P)?o=!0:"string"==typeof t&&""===t&&"NUMBER"===s.elm.prop("type").toUpperCase()?o=!1:(r=new RegExp(i.pattern,"i"),o=("\\S+"===i.pattern||c&&"required"===i.pattern)&&null===t?!1:r.test(t))}(!s.bFieldRequired&&!t||s.elm.prop("disabled")||s.scope.$eval(P))&&(o=!0),o||(l=!1,function(t,r,i){var n=i.message;i.altText&&i.altText.length>0&&(n=i.altText.replace("alt=","")),a(n).then(function(a){p.length>0&&U.displayOnlyLastErrorMsg?p=" "+(i&&i.params?String.format(a,i.params):a):p+=" "+(i&&i.params?String.format(a,i.params):a),y(s,t,p,l,e)})["catch"](function(){i.altText&&i.altText.length>0&&(p.length>0&&U.displayOnlyLastErrorMsg?p=" "+n:p+=" "+n,y(s,t,p,l,e))})}(u,o,i))}return o&&(b(s,""),s.updateErrorMsg("",{isValid:o})),u&&(u.isValid=l,l&&(u.message="")),l}function h(t,e,r,i){var n=e.name?e.name:t.attr("name"),s=E(n,{scope:i}),o=e&&e.friendlyName?a.instant(e.friendlyName):"",l={fieldName:n,friendlyName:o,elm:t,attrs:e,ctrl:r,scope:i,isValid:!1,message:"",formName:s?s.$name:null},p=S(L,"fieldName",t.attr("name"));return p>=0?L[p]=l:L.push(l),L}function y(t,e,a,r,i){a=a.trim(),b(e,a),e&&(e.message=a),(t.validatorAttrs.preValidateFormElements||U.preValidateFormElements)&&(e&&"function"==typeof t.ctrl.$setTouched&&e.ctrl.$setTouched(),t.ctrl.$dirty===!1&&g(a,{isSubmitted:!0,isValid:r,obj:e})),i&&e&&!e.isValid?t.updateErrorMsg(a,{isValid:r}):e&&e.isValid&&b(e,"")}function b(t,e){if("undefined"!=typeof t&&null!=t){var r=t.ctrl&&t.ctrl.$name?t.ctrl.$name:t.attrs&&t.attrs.name?t.attrs.name:t.elm.attr("name"),i=E(r,t),n=S(q,"field",r);if(n>=0&&""===e)q.splice(n,1);else if(""!==e){var s=t.attrs&&t.friendlyName?a.instant(t.friendlyName):"",o={field:r,friendlyName:s,message:e,formName:i?i.$name:null};n>=0?q[n]=o:q.push(o)}return t.scope.$validationSummary=q,i&&(i.$validationSummary=$(q,"formName",i.$name)),q}}function O(t,e,a){if(t)for(var r=0;r8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":a=t.substring(0,8),r=t.substring(2,3),i=x(a,r),l=i[0],o=i[1],s=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":a=t.substring(0,10),r=t.substring(2,3),i=x(a,r),o=i[0],l=i[1],s=i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":a=t.substring(0,8),r=t.substring(2,3),i=x(a,r),o=i[0],l=i[1],s=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:a=t.substring(0,10),r=t.substring(4,5),i=x(a,r),s=i[0],o=i[1],l=i[2],n=t.length>10?t.substring(11).split(":"):null}var p=n&&3===n.length?n[0]:0,d=n&&3===n.length?n[1]:0,u=n&&3===n.length?n[2]:0;return new Date(s,o-1,l,p,d,u)}function x(t,e){var a=[];switch(e){case"/":a=t.split("/");break;case".":a=t.split(".");break;case"-":default:a=t.split("-")}return a}function N(t,e,a){var r=!1;switch(t){case"<":r=a>e?!0:!1;break;case"<=":r=a>=e?!0:!1;break;case">":r=e>a?!0:!1;break;case">=":r=e>=a?!0:!1;break;case"!=":case"<>":r=e!=a?!0:!1;break;case"=":case"==":r=e==a?!0:!1;break;default:r=!1}return r}function R(){return this.replace(/^\s+|\s+$/g,"")}function V(){var t=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(e,a){return"undefined"!=typeof t[a]?t[a]:e})}function T(t){var e=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return t.replace(/{(\d+)}/g,function(t,a){return"undefined"!=typeof e[a]?e[a]:t})}var w=!1,F=1e3,L=[],U={},k=[],q=[];t.$on("$routeChangeStart",function(){w||(U.displayOnlyLastErrorMsg=!1,U.preValidateFormElements=!1,U.isolatedScope=null,U.scope=null,L=[],q=[])});var M=function(t,e,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=F,this.scope=t,this.elm=e,this.ctrl=r,this.validatorAttrs=a,t&&t.$validationOptions&&(U=t.$validationOptions),t&&(U.isolatedScope||U.scope)&&(this.scope=U.isolatedScope?U.isolatedScope:U.scope,U=p(t.$validationOptions,U)),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&(h(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return M.prototype.arrayFindObject=O,M.prototype.defineValidation=i,M.prototype.getFormElementByName=n,M.prototype.getFormElements=s,M.prototype.isFieldRequired=l,M.prototype.initialize=o,M.prototype.mergeObjects=p,M.prototype.removeFromValidationSummary=u,M.prototype.removeFromFormElementObjectList=d,M.prototype.setBypassRootScopeReset=c,M.prototype.setDisplayOnlyLastErrorMsg=m,M.prototype.setGlobalOptions=f,M.prototype.updateErrorMsg=g,M.prototype.validate=v,String.prototype.trim=R,String.prototype.format=V,String.format=T,M}]);
-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,r=e.hasOwnProperty("ruleParams")?e.ruleParams:null,n={};switch(s){case"alpha":n={pattern:"^([a-zÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ])+$",message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":n={pattern:"^([a-zÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s])+$",message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":n={pattern:"^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ])+$",message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":n={pattern:"^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s])+$",message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":n={pattern:"^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ_-])+$",message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":n={pattern:"^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s_-])+$",message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"betweenLen":case"between_len":var _=r.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";n={pattern:"^.{"+_[0]+","+_[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[_[0],_[1]],type:"regex"};break;case"betweenNum":case"between_num":var _=r.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";n={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[_[0],_[1]],type:"conditionalNumber"};break;case"boolean":n={pattern:"^(true|True|false|False|0|1)$",message:"INVALID_BOOLEAN",type:"regex"};break;case"checked":n={pattern:"^true$",message:"INVALID_CHECKBOX_SELECTED",type:"regex"};break;case"creditCard":case"credit_card":n={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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"EURO_LONG",params:[r],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":n={condition:">=",dateType:"EURO_LONG",params:[r],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":n={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.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";n={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":n={condition:"<=",dateType:"EURO_SHORT",params:[r],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":n={condition:">=",dateType:"EURO_SHORT",params:[r],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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"ISO",params:[r],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":n={condition:">=",dateType:"ISO",params:[r],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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"US_LONG",params:[r],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":n={condition:">=",dateType:"US_LONG",params:[r],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":n={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.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";n={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":n={condition:"<=",dateType:"US_SHORT",params:[r],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":n={condition:">=",dateType:"US_SHORT",params:[r],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"email":n={pattern:"(?:[\\wа-я0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.?[\\wа-я0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\wа-я0-9](?:[\\wа-я0-9-]*[\\wа-я0-9])?\\.?)+[\\wа-я0-9](?:[\\wа-я0-9-]*[\\wа-я0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.?){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[\\wа-я0-9-]*[\\wа-я0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])",message:"INVALID_EMAIL",type:"regex"};break;case"exactLen":case"exact_len":n={pattern:"^.{"+r+"}$",message:"INVALID_EXACT_LEN",params:[r],type:"regex"};break;case"float":n={pattern:"^\\d*\\.{1}\\d+$",message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":n={pattern:"^[-+]?\\d*\\.{1}\\d+$",message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":n={pattern:"^[a-zA-Z]{2}\\d{2}\\s?([0-9a-zA-Z]{4}\\s?){4}[0-9a-zA-Z]{2}$",message:"INVALID_IBAN",type:"regex"};break;case"int":case"integer":n={pattern:"^\\d+$",message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":n={pattern:"^[+-]?\\d+$",message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ipv4":n={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":n={pattern:"^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",message:"INVALID_IPV6",type:"regex"};break;case"match":var e=r.split(",");n={message:"INVALID_INPUT_MATCH",params:e,type:"match"};break;case"maxLen":case"max_len":n={pattern:"^.{0,"+r+"}$",message:"INVALID_MAX_CHAR",params:[r],type:"regex"};break;case"maxNum":case"max_num":n={condition:"<=",message:"INVALID_MAX_NUM",params:[r],type:"conditionalNumber"};break;case"minLen":case"min_len":n={pattern:"^.{"+r+",}$",message:"INVALID_MIN_CHAR",params:[r],type:"regex"};break;case"minNum":case"min_num":n={condition:">=",message:"INVALID_MIN_NUM",params:[r],type:"conditionalNumber"};break;case"numeric":n={pattern:"^\\d*\\.?\\d+$",message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":n={pattern:"^[-+]?\\d*\\.?\\d+$",message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"regex":n={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"remote":n={message:"",params:[r],type:"remote"};break;case"required":n={pattern:"\\S+",message:"INVALID_REQUIRED",type:"regex"};break;case"url":n={pattern:"(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?",message:"INVALID_URL",type:"regex"};break;case"time":n={pattern:"^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$",message:"INVALID_TIME",type:"regex"}}return n.altText=a,n}var a={getElementValidators:e};return a}]);
+angular.module("ghiscoding.validation").factory("validationCommon",["$rootScope","$timeout","$translate","validationRules",function(t,e,a,r){function i(){var t=this,e={};t.validators=[],t.typingLimit=F,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")?t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10):U&&U.hasOwnProperty("debounce")&&(t.typingLimit=parseInt(U.debounce,10));var a=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(a.indexOf("pattern=/")>=0){var i=a.match(/pattern=(\/.*?\/[igm]*)(:alt=(.*))?/);if(!i||i.length<3)throw'Regex validator within the validation needs to be define with an opening "/" and a closing "/", please review your validator.';var n=i[1],s=i[2]?i[2].replace(/\|(.*)/,""):"",o=n.match(new RegExp("^/(.*?)/([gimy]*)$")),l=new RegExp(o[1],o[2]);e={altMsg:s,message:s.replace(/:alt=/,""),pattern:l},a=a.replace("pattern="+n,"pattern")}else if(a.indexOf("regex:")>=0){var i=a.match("regex:(.*?):regex");if(i.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=i[1].split(":=");e={message:p[0],pattern:p[1]},a=a.replace(i[0],"regex:")}var d=a.split("|");if(d){t.bFieldRequired=a.indexOf("required")>=0?!0:!1;for(var u=0,c=d.length;c>u;u++){var m=d[u].split(":"),f=d[u].indexOf("alt=")>=0?!0:!1;t.validators[u]=r.getElementValidators({altText:f===!0?2===m.length?m[1]:m[2]:"",customRegEx:e,rule:m[0],ruleParams:f&&2===m.length?null:m[1]})}}return t}function n(t){return O(L,"fieldName",t)}function s(t){return t?S(L,"formName",t):L}function o(t,e,a,r){this.scope=t,this.elm=e,this.ctrl=r,this.validatorAttrs=a,h(e,a,r,t),this.defineValidation()}function l(){var t=this;return t.bFieldRequired}function p(t,e){var a={};for(var r in t)a[r]=t[r];for(var r in e)a[r]=e[r];return a}function d(t){var e=$(L,"fieldName",t);e>=0&&L.splice(e,1)}function u(t,e){var a=this,r=E(t,a),i=e?e:q,n=$(i,"field",t);return n>=0&&i.splice(n,1),n=$(q,"field",t),n>=0&&q.splice(n,1),a.scope.$validationSummary=q,r&&(r.$validationSummary=S(q,"formName",r.$name)),q}function c(t){T=t}function m(t){U.displayOnlyLastErrorMsg=t}function f(t){var e=this;return U=p(U,t),e}function g(t,e){var r=this;e&&e.obj&&(r=e.obj,r.validatorAttrs=e.obj.attrs);var i=e&&e.elm?e.elm:r.elm,n=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof n||null===n){var s=i?i.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="'+s+'"'}var o=e&&e.translate?a.instant(t):t,l=n.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),p=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),u="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;p=angular.element(document.querySelector(u))}p&&0!==p.length||(p=angular.element(document.querySelector(".validation-"+l)));var c=e&&e.isSubmitted?e.isSubmitted:!1;e&&!e.isValid&&(c||r.ctrl.$dirty||r.ctrl.$touched)?p.length>0?p.text(o):i.after(''+o+""):p.text("")}function v(t,e){var r,i,s=this,o=!0,l=!0,p="";"undefined"==typeof t&&(t="");for(var d=s.ctrl&&s.ctrl.$name?s.ctrl.$name:s.attrs&&s.attrs.name?s.attrs.name:s.elm.attr("name"),u=n(d),c=s.validatorAttrs.hasOwnProperty("rules")?s.validatorAttrs.rules:s.validatorAttrs.validation,m=0,f=s.validators.length;f>m;m++){if(i=s.validators[m],"conditionalDate"===i.type){if(r=new RegExp(i.pattern),o=(!i.pattern||"/\\S+/"===i.pattern.toString()||c&&"required"===i.pattern)&&null===t?!1:r.test(t)){var g=i.dateType,v=A(t,g).getTime();if(2==i.params.length){var h=A(i.params[0],g).getTime(),O=A(i.params[1],g).getTime(),S=w(i.condition[0],v,h),$=w(i.condition[1],v,O);o=S&&$?!0:!1}else{var E=A(i.params[0],g).getTime();o=w(i.condition,v,E)}}}else if("conditionalNumber"===i.type)if(2==i.params.length){var S=w(i.condition[0],parseFloat(t),parseFloat(i.params[0])),$=w(i.condition[1],parseFloat(t),parseFloat(i.params[1]));o=S&&$?!0:!1}else o=w(i.condition,parseFloat(t),parseFloat(i.params[0]));else if("match"===i.type){var x=i.params[0],R=s.scope.$eval(x);o=R===t&&!!t}else if("remote"===i.type){if(t&&e){s.ctrl.$processing=!0;var N=null,V=i.params[0];if(-1===V.indexOf("."))N=s.scope[V];else{var T=V.split(".");N=s.scope;for(var F=0,L=T.length;L>F;F++)N=N[T[F]]}var q="function"==typeof N?N():null;if(k.length>1)for(;k.length>0;){var M=k.pop();"function"==typeof M.abort&&M.abort()}if(k.push(q),!q||"function"!=typeof q.then)throw"Remote Validation requires a declared function (in your Controller) which also needs to return a Promise, please review your code.";s.ctrl.$setValidity("remote",!1),function(t){q.then(function(a){a=a.data||a,k.pop(),s.ctrl.$processing=!1;var r=p+" ";"boolean"==typeof a?o=a?!0:!1:"object"==typeof a&&(o=a.isValid?!0:!1),o===!1&&(u.isValid=!1,r+=a.message?a.message:t,y(s,u,r,!1,e)),o===!0&&l===!0&&(u.isValid=!0,s.ctrl.$setValidity("remote",!0),y(s,u,"",!0,e))})}(i.altText)}}else{var P="undefined"!=typeof s.attrs?s.attrs.ngDisabled:s.validatorAttrs.ngDisabled;s.elm.prop("disabled")||s.scope.$eval(P)?o=!0:"string"==typeof t&&""===t&&"NUMBER"===s.elm.prop("type").toUpperCase()?o=!1:(r=new RegExp(i.pattern),o=(!i.pattern||"/\\S+/"===i.pattern.toString()||c&&"required"===i.pattern)&&null===t?!1:r.test(t))}(!s.bFieldRequired&&!t||s.elm.prop("disabled")||s.scope.$eval(P))&&(o=!0),o||(l=!1,function(t,r,i){var n=i.message;i.altText&&i.altText.length>0&&(n=i.altText.replace("alt=","")),a(n).then(function(a){p.length>0&&U.displayOnlyLastErrorMsg?p=" "+(i&&i.params?String.format(a,i.params):a):p+=" "+(i&&i.params?String.format(a,i.params):a),y(s,t,p,l,e)})["catch"](function(){i.altText&&i.altText.length>0&&(p.length>0&&U.displayOnlyLastErrorMsg?p=" "+n:p+=" "+n,y(s,t,p,l,e))})}(u,o,i))}return o&&(b(s,""),s.updateErrorMsg("",{isValid:o})),u&&(u.isValid=l,l&&(u.message="")),l}function h(t,e,r,i){var n=e.name?e.name:t.attr("name"),s=E(n,{scope:i}),o=e&&e.friendlyName?a.instant(e.friendlyName):"",l={fieldName:n,friendlyName:o,elm:t,attrs:e,ctrl:r,scope:i,isValid:!1,message:"",formName:s?s.$name:null},p=$(L,"fieldName",t.attr("name"));return p>=0?L[p]=l:L.push(l),L}function y(t,e,a,r,i){a=a.trim(),b(e,a),e&&(e.message=a),(t.validatorAttrs.preValidateFormElements||U.preValidateFormElements)&&(e&&"function"==typeof t.ctrl.$setTouched&&e.ctrl.$setTouched(),t.ctrl.$dirty===!1&&g(a,{isSubmitted:!0,isValid:r,obj:e})),i&&e&&!e.isValid?t.updateErrorMsg(a,{isValid:r}):e&&e.isValid&&b(e,"")}function b(t,e){if("undefined"!=typeof t&&null!=t){var r=t.ctrl&&t.ctrl.$name?t.ctrl.$name:t.attrs&&t.attrs.name?t.attrs.name:t.elm.attr("name"),i=E(r,t),n=$(q,"field",r);if(n>=0&&""===e)q.splice(n,1);else if(""!==e){var s=t.attrs&&t.friendlyName?a.instant(t.friendlyName):"",o={field:r,friendlyName:s,message:e,formName:i?i.$name:null};n>=0?q[n]=o:q.push(o)}return t.scope.$validationSummary=q,i&&(i.$validationSummary=S(q,"formName",i.$name)),q}}function O(t,e,a){if(t)for(var r=0;r8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":a=t.substring(0,8),r=t.substring(2,3),i=x(a,r),l=i[0],o=i[1],s=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":a=t.substring(0,10),r=t.substring(2,3),i=x(a,r),o=i[0],l=i[1],s=i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":a=t.substring(0,8),r=t.substring(2,3),i=x(a,r),o=i[0],l=i[1],s=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],n=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:a=t.substring(0,10),r=t.substring(4,5),i=x(a,r),s=i[0],o=i[1],l=i[2],n=t.length>10?t.substring(11).split(":"):null}var p=n&&3===n.length?n[0]:0,d=n&&3===n.length?n[1]:0,u=n&&3===n.length?n[2]:0;return new Date(s,o-1,l,p,d,u)}function x(t,e){var a=[];switch(e){case"/":a=t.split("/");break;case".":a=t.split(".");break;case"-":default:a=t.split("-")}return a}function w(t,e,a){var r=!1;switch(t){case"<":r=a>e?!0:!1;break;case"<=":r=a>=e?!0:!1;break;case">":r=e>a?!0:!1;break;case">=":r=e>=a?!0:!1;break;case"!=":case"<>":r=e!=a?!0:!1;break;case"=":case"==":r=e==a?!0:!1;break;default:r=!1}return r}function R(){return this.replace(/^\s+|\s+$/g,"")}function N(){var t=Array.isArray(arguments[0])?arguments[0]:arguments;return this.replace(/{(\d+)}/g,function(e,a){return"undefined"!=typeof t[a]?t[a]:e})}function V(t){var e=Array.isArray(arguments[1])?arguments[1]:Array.prototype.slice.call(arguments,1);return t.replace(/{(\d+)}/g,function(t,a){return"undefined"!=typeof e[a]?e[a]:t})}var T=!1,F=1e3,L=[],U={},k=[],q=[];t.$on("$routeChangeStart",function(){T||(U.displayOnlyLastErrorMsg=!1,U.preValidateFormElements=!1,U.isolatedScope=null,U.scope=null,L=[],q=[])});var M=function(t,e,a,r){this.bFieldRequired=!1,this.validators=[],this.typingLimit=F,this.scope=t,this.elm=e,this.ctrl=r,this.validatorAttrs=a,t&&t.$validationOptions&&(U=t.$validationOptions),t&&(U.isolatedScope||U.scope)&&(this.scope=U.isolatedScope?U.isolatedScope:U.scope,U=p(t.$validationOptions,U)),this.elm&&this.validatorAttrs&&this.ctrl&&this.scope&&(h(this.elm,this.validatorAttrs,this.ctrl,this.scope),this.defineValidation())};return M.prototype.arrayFindObject=O,M.prototype.defineValidation=i,M.prototype.getFormElementByName=n,M.prototype.getFormElements=s,M.prototype.isFieldRequired=l,M.prototype.initialize=o,M.prototype.mergeObjects=p,M.prototype.removeFromValidationSummary=u,M.prototype.removeFromFormElementObjectList=d,M.prototype.setBypassRootScopeReset=c,M.prototype.setDisplayOnlyLastErrorMsg=m,M.prototype.setGlobalOptions=f,M.prototype.updateErrorMsg=g,M.prototype.validate=v,String.prototype.trim=R,String.prototype.format=N,String.format=V,M}]);
+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,r=e.hasOwnProperty("ruleParams")?e.ruleParams:null,n={};switch(s){case"alpha":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ])+$/i,message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ\s])+$/i,message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9])+$/i,message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s])+$/i,message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9_-])+$/i,message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":n={pattern:/^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s_-])+$/i,message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"betweenLen":case"between_len":var _=r.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";n={pattern:"^.{"+_[0]+","+_[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[_[0],_[1]],type:"regex"};break;case"betweenNum":case"between_num":var _=r.split(",");if(2!==_.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";n={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[_[0],_[1]],type:"conditionalNumber"};break;case"boolean":n={pattern:/^(true|false|0|1)$/i,message:"INVALID_BOOLEAN",type:"regex"};break;case"checked":n={pattern:/^true$/i,message:"INVALID_CHECKBOX_SELECTED",type:"regex"};break;case"creditCard":case"credit_card":n={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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"EURO_LONG",params:[r],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":n={condition:">=",dateType:"EURO_LONG",params:[r],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":n={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.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";n={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":n={condition:"<=",dateType:"EURO_SHORT",params:[r],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":n={condition:">=",dateType:"EURO_SHORT",params:[r],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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"ISO",params:[r],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":n={condition:">=",dateType:"ISO",params:[r],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":n={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 _=r.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";n={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":n={condition:"<=",dateType:"US_LONG",params:[r],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":n={condition:">=",dateType:"US_LONG",params:[r],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":n={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.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";n={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":n={condition:"<=",dateType:"US_SHORT",params:[r],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":n={condition:">=",dateType:"US_SHORT",params:[r],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"email":n={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":n={pattern:"^.{"+r+"}$",message:"INVALID_EXACT_LEN",params:[r],type:"regex"};break;case"float":n={pattern:/^\d*\.{1}\d+$/,message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":n={pattern:/^[-+]?\d*\.{1}\d+$/,message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":n={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"int":case"integer":n={pattern:/^\d+$/,message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":n={pattern:/^[+-]?\d+$/,message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ipv4":n={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":n={pattern:/^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/i,message:"INVALID_IPV6",type:"regex"};break;case"match":var e=r.split(",");n={message:"INVALID_INPUT_MATCH",params:e,type:"match"};break;case"maxLen":case"max_len":n={pattern:"^.{0,"+r+"}$",message:"INVALID_MAX_CHAR",params:[r],type:"regex"};break;case"maxNum":case"max_num":n={condition:"<=",message:"INVALID_MAX_NUM",params:[r],type:"conditionalNumber"};break;case"minLen":case"min_len":n={pattern:"^.{"+r+",}$",message:"INVALID_MIN_CHAR",params:[r],type:"regex"};break;case"minNum":case"min_num":n={condition:">=",message:"INVALID_MIN_NUM",params:[r],type:"conditionalNumber"};break;case"numeric":n={pattern:/^\d*\.?\d+$/,message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":n={pattern:/^[-+]?\d*\.?\d+$/,message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"pattern":case"regex":n={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"remote":n={message:"",params:[r],type:"remote"};break;case"required":n={pattern:/\S+/,message:"INVALID_REQUIRED",type:"regex"};break;case"url":n={pattern:/^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i,message:"INVALID_URL",type:"regex"};break;case"time":n={pattern:/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/,message:"INVALID_TIME",type:"regex"}}return n.altText=a,n}var a={getElementValidators:e};return a}]);
angular.module("ghiscoding.validation").service("validationService",["$interpolate","$timeout","validationCommon",function(e,o,t){function a(t,a,n){var i=this,r={};if("string"==typeof t&&"string"==typeof a?(r.elmName=t,r.rules=a,r.friendlyName="string"==typeof n?n:""):r=t,"object"!=typeof r||!r.hasOwnProperty("elmName")||!r.hasOwnProperty("rules")||!r.hasOwnProperty("scope")&&"undefined"==typeof i.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";var l=r.scope?r.scope:i.validationAttrs.scope;if(r.elm=angular.element(document.querySelector('[name="'+r.elmName+'"]')),"object"!=typeof r.elm||0===r.elm.length)return i;if(new RegExp("{{(.*?)}}").test(r.elmName)&&(r.elmName=e(r.elmName)(l)),r.name=r.elmName,i.validationAttrs.isolatedScope){var m=l.$validationOptions||null;l=i.validationAttrs.isolatedScope,m&&(l.$validationOptions=m)}r.elm.bind("blur",v=function(e){var o=i.commonObj.getFormElementByName(r.elmName);o.isValidationCancelled||(i.commonObj.initialize(l,r.elm,r,r.ctrl),s(i,e.target.value,0))}),r=i.commonObj.mergeObjects(i.validationAttrs,r),f(i,l,r);var c=l.$watch(r.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))):(r.ctrl=angular.element(r.elm).controller("ngModel"),r.value=e,i.commonObj.initialize(l,r.elm,r,r.ctrl),void s(i,e))},!0);return y.push({elmName:r.elmName,watcherHandler:c}),i}function n(e){var o=this,t="",a=!0;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"checkFormValidity() requires a valid Angular Form or $scope object passed as argument to work properly (ex.: $scope.form1 OR $scope).";for(var n=0,i=e.$validationSummary.length;i>n;n++)if(a=!1,t=e.$validationSummary[n].field){var r=o.commonObj.getFormElementByName(t);r.elm&&r.elm.length>0&&("function"==typeof r.ctrl.$setTouched&&r.ctrl.$setTouched(),o.commonObj.updateErrorMsg(e.$validationSummary[n].message,{isSubmitted:!0,isValid:r.isValid,obj:r}))}return a}function i(e){var o=this;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"clearInvalidValidatorsInSummary() requires a valid Angular Form or $scope object passed as argument to work properly (ex.: $scope.form1 OR $scope).";for(var t=[],a=0,n=e.$validationSummary.length;n>a;a++)t.push(e.$validationSummary[a].field);for(a=0,n=t.length;n>a;a++)t[a]&&(o.commonObj.removeFromFormElementObjectList(t[a]),o.commonObj.removeFromValidationSummary(t[a],e.$validationSummary))}function r(e,o){var t,a=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 object passed as argument to work properly (ex.: $scope.form1 OR $scope).";if(o instanceof Array)for(var n=0,i=o.length;i>n;n++)t=a.commonObj.getFormElementByName(o[n]),t.elm.removeAttr("validation"),p(a,t,e.$validationSummary);else o instanceof Object&&o.formElmObj?(t=o.formElmObj,t.elm.removeAttr("validation"),p(o.self,t,e.$validationSummary)):(t=a.commonObj.getFormElementByName(o),t.elm.removeAttr("validation"),p(a,t,e.$validationSummary));return a}function l(e,o){var t,a=this,o=o||{},n="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 l=a.commonObj.getFormElements(e.$name);if(l instanceof Array)for(var m=0,c=l.length;c>m;m++)t=l[m],i&&t.elm.val(null),n?r(e,{self:a,formElmObj:t}):("function"==typeof t.ctrl.$setUntouched&&t.ctrl.$setUntouched(),t.ctrl.$setPristine(),a.commonObj.updateErrorMsg("",{isValid:!1,obj:t}))}function m(e){var o=this,t="boolean"==typeof e?e:!0;o.commonObj.setBypassRootScopeReset(t)}function c(e){var o=this,t="boolean"==typeof e?e:!0;o.commonObj.setDisplayOnlyLastErrorMsg(t)}function d(e){var o=this;return o.validationAttrs=e,o.commonObj.setGlobalOptions(e),o}function s(e,t,a){var n="undefined"!=typeof a?a: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)))},n)),t):(o.cancel(e.timer),e.commonObj.ctrl.$setValidity("validation",e.commonObj.validate(t,!0)),t)):(u(e,i),t)}function u(e,t){var a=t.ctrl?t.ctrl:e.commonObj.ctrl;if(o.cancel(self.timer),t.isValidationCancelled=!0,a.$setValidity("validation",!0),e.commonObj.updateErrorMsg("",{isValid:!0,obj:t}),"function"==typeof v){var n=t.elm?t.elm:e.commonObj.elm;n.unbind("blur",v)}}function p(e,o,t){var a=e.commonObj.scope?e.commonObj.scope:o.scope?o.scope:null;if("undefined"==typeof a)throw"removeValidator() requires a valid $scope object passed but unfortunately could not find it.";var n=e.commonObj.arrayFindObject(y,"elmName",o.fieldName);n&&n.watcherHandler(),o.isValidationCancelled=!0,o.isValid=!0,o.attrs.validation="",u(e,o),"function"==typeof o.ctrl.$setUntouched&&o.ctrl.$setUntouched(),e.commonObj.scope=a,o.ctrl.$setPristine(),e.commonObj.removeFromValidationSummary(o.fieldName,t)}function f(e,t,a){t.$watch(function(){return"undefined"==typeof a.elm.attr("ng-disabled")?null:t.$eval(a.elm.attr("ng-disabled"))},function(n){if("undefined"==typeof n||null===n)return null;a.ctrl=angular.element(a.elm).controller("ngModel"),e.commonObj.initialize(t,a.elm,a,a.ctrl);var i=e.commonObj.getFormElementByName(a.name);o(function(){if(n)a.ctrl.$setValidity("validation",!0),e.commonObj.updateErrorMsg("",{isValid:!0,obj:i}),e.commonObj.removeFromValidationSummary(a.name);else{"function"==typeof a.ctrl.$setTouched&&a.ctrl.$setTouched();var o=a.ctrl.$viewValue||"";e.commonObj.initialize(t,a.elm,a,a.ctrl),a.ctrl.$setValidity("validation",e.commonObj.validate(o,!0))}},0,!1),n&&("function"==typeof a.ctrl.$setUntouched&&a.ctrl.$setUntouched(),a.ctrl.$setValidity("validation",!0),e.commonObj.removeFromValidationSummary(a.name))})}var v,y=[],b=function(){this.isValidationCancelled=!1,this.timer=null,this.validationAttrs={},this.commonObj=new t};return b.prototype.addValidator=a,b.prototype.checkFormValidity=n,b.prototype.removeValidator=r,b.prototype.resetForm=l,b.prototype.setBypassRootScopeReset=m,b.prototype.setDisplayOnlyLastErrorMsg=c,b.prototype.setGlobalOptions=d,b.prototype.clearInvalidValidatorsInSummary=i,b}]);
\ No newline at end of file
diff --git a/locales/validation/en.json b/locales/validation/en.json
index b63f7ba..5de26ae 100644
--- a/locales/validation/en.json
+++ b/locales/validation/en.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Must be a positive number. ",
"INVALID_NUMERIC_SIGNED": "Must be a positive or negative number. ",
"INVALID_PATTERN": "Must be following this format: {0}. ",
+ "INVALID_PATTERN_DATA": "Must be following this format \"{{data}}\". ",
"INVALID_REQUIRED": "Field is required. ",
"INVALID_URL": "Must be a valid URL. ",
"INVALID_TIME": "Must be a valid time format (hh:mm) OR (hh:mm:ss). ",
diff --git a/locales/validation/fr.json b/locales/validation/fr.json
index 5fbb95b..679992b 100644
--- a/locales/validation/fr.json
+++ b/locales/validation/fr.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Doit être un nombre positif. ",
"INVALID_NUMERIC_SIGNED": "Doit être un nombre positif ou négatif. ",
"INVALID_PATTERN": "Doit suivre le format: {0}. ",
+ "INVALID_PATTERN_DATA": "Doit suivre le format \"{{data}}\". ",
"INVALID_REQUIRED": "Le champ est requis. ",
"INVALID_URL": "Doit être un URL valide. ",
"INVALID_TIME": "Doit être un format de temps valide (hh:mm) OU (hh:mm:ss). ",
diff --git a/locales/validation/no.json b/locales/validation/no.json
index bcb31eb..d0986ce 100644
--- a/locales/validation/no.json
+++ b/locales/validation/no.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Må være et positivt tall. ",
"INVALID_NUMERIC_SIGNED": "Må være et positivt eller negativt tall. ",
"INVALID_PATTERN": "Må være på følgende format: {0}. ",
+ "INVALID_PATTERN_DATA": "Må være på følgende format \"{{data}}\". ",
"INVALID_REQUIRED": "Feltet er påkrevd. ",
"INVALID_URL": "Må være en gyldig URL. ",
"INVALID_TIME": "Må være et gyldig tidsformat (tt:mm) OR (tt:mm:ss). ",
diff --git a/locales/validation/pl.json b/locales/validation/pl.json
index 690dc10..4152a38 100644
--- a/locales/validation/pl.json
+++ b/locales/validation/pl.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Musi być liczbą dodatnią. ",
"INVALID_NUMERIC_SIGNED": "Musi być liczbą dodatnią lub ujemną. ",
"INVALID_PATTERN": "Musi być zgodne z formatem: {0}. ",
+ "INVALID_PATTERN_DATA": "Musi być zgodne z formatem \"{{data}}\". ",
"INVALID_REQUIRED": "Pole jest wymagane. ",
"INVALID_URL": "Musi być poprawnym adresem URL. ",
"INVALID_TIME": "Musi być poprawną godziną w formacie (gg:mm) OR (gg:mm:ss). ",
diff --git a/locales/validation/pt-br.json b/locales/validation/pt-br.json
index 8fea91b..b89a975 100644
--- a/locales/validation/pt-br.json
+++ b/locales/validation/pt-br.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Deve ser um número positivo. ",
"INVALID_NUMERIC_SIGNED": "Deve ser um número positivo ou negativo. ",
"INVALID_PATTERN": "Deve seguir o seguinte formato: {0}. ",
+ "INVALID_PATTERN_DATA": "Deve seguir o seguinte formato \"{{data}}\". ",
"INVALID_REQUIRED": "Campo obrigatório. ",
"INVALID_URL": "Deve ser uma URL válida. ",
"INVALID_TIME": "Deve ser um formato de hora válido (hh:mm) ou (hh:mm:ss). ",
diff --git a/locales/validation/ru.json b/locales/validation/ru.json
index e420318..58468df 100644
--- a/locales/validation/ru.json
+++ b/locales/validation/ru.json
@@ -48,6 +48,7 @@
"INVALID_NUMERIC": "Должно быть положительным числом. ",
"INVALID_NUMERIC_SIGNED": "Должно быть положительным или отрицательным числом. ",
"INVALID_PATTERN": "Должно соответствовать этому формату: {0}. ",
+ "INVALID_PATTERN_DATA": "Должно соответствовать этому формату \"{{data}}\". ",
"INVALID_REQUIRED": "Поле обязательно для заполнения. ",
"INVALID_URL": "Должно быть действительным URL адресом. ",
"INVALID_TIME": "Должно быть допустимым форматом времени (hh:mm) или (hh:mm:ss). ",
diff --git a/package.json b/package.json
index 2ae2386..2eef60f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "angular-validation-ghiscoding",
- "version": "1.3.34",
+ "version": "1.3.35",
"author": "Ghislain B.",
"description": "Angular-Validation Directive and Service (ghiscoding)",
"main": "app.js",
diff --git a/protractor/full_tests_spec.js b/protractor/full_tests_spec.js
index c304673..c02da4a 100644
--- a/protractor/full_tests_spec.js
+++ b/protractor/full_tests_spec.js
@@ -558,8 +558,8 @@ function loadData() {
},
{
'validator': 'email',
- 'invalid_data': ['g$g.com', 'g@g,com', 'g@g.'],
- 'valid_data': ['someone@hotmail.com', 'nickname@zone', 'other.email-with-dash@some-company.com', 'кокер@спаниель.рф'],
+ 'invalid_data': ['g$g.com', 'g@g,com', '.my@email.com.', 'some space@hotmail.com'],
+ 'valid_data': ['nickname@domain', 'other.email-with-dash@some-company.com', 'кокер@спаниель.рф', 'hola.àáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿ@español.com'],
'error_message': {
'en': "Must be a valid email address.",
'es': "Debe contener una dirección de correo electronico valida.",
diff --git a/protractor/mixed_validation_spec.js b/protractor/mixed_validation_spec.js
index acc21f4..7a2baad 100644
--- a/protractor/mixed_validation_spec.js
+++ b/protractor/mixed_validation_spec.js
@@ -28,7 +28,7 @@
var errorMessages = [
'Must be a positive or negative number. Field is required.',
'May only contain a positive or negative float value (integer excluded). Needs to be a numeric value, between -0.6 and 99.5. Field is required.',
- 'Must have a length of exactly 4 characters. Must be following this format: YYWW. Field is required. Must be a positive integer.',
+ 'Must have a length of exactly 4 characters. Field is required. Must be a positive integer. Must be following this format "YYWW".',
'Must be a valid email address. Field is required. Must be at least 6 characters.',
'Must be a valid URL. Field is required.',
'Must be a valid IP (IPV4). Field is required.',
diff --git a/readme.md b/readme.md
index 7e157d1..af37948 100644
--- a/readme.md
+++ b/readme.md
@@ -1,5 +1,5 @@
#Angular Validation (Directive / Service)
-`Version: 1.3.34`
+`Version: 1.3.35`
### 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!
@@ -13,18 +13,18 @@ Supporting AngularJS 1.3.x *(current code should work with 1.2.x just the same,
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).
-[Validation Summary](/ghiscoding/angular-validation/wiki/Validation-Summary) was also recently added to easily show all validation errors that are still active on the form and you can also use 2 ways of dealing with the [Submit and Validation](/ghiscoding/angular-validation/wiki/Form-Submit-and-Validation) button.
+[Validation Summary](https://github.com/ghiscoding/angular-validation/wiki/Validation-Summary) was also recently added to easily show all validation errors that are still active on the form and you can also use 2 ways of dealing with the [Submit and Validation](https://github.com/ghiscoding/angular-validation/wiki/Form-Submit-and-Validation) button.
For more reasons to use it, see the answered question of: [Why Use It?](#whyuseit)
-If you like the Angular-Validation project and you use it, please click on the **Star** and add it as a favourite. The more star ratings there is, the more chances it could be found by other users inside the popular trend section. That is the only support I ask you... thanks ;)
+If you like the Angular-Validation project and you use it, please click on the **Star** and add it as a favorite. The more star ratings there is, the more chances it could be found by other users inside the popular trend section. That is the only support I ask you... thanks and enjoy it ;)
## Live Demo
[Plunker](http://plnkr.co/jADq7H)
## Tested with Protractor
-Angular-validation now has a full set of End-to-End tests with Protractor, there is over 1600+ assertions, it starts by testing the original live demo page and then goes on with a complete test suite of All Validators in both the Angular-Validation Directive and Service.
+Angular-validation now has a full set of **End-to-End tests** with **Protractor**, there is over 1600+ assertions, it starts by testing the original live demo page and then goes on with a complete test suite of All Validators in both the Angular-Validation Directive and Service.
Why use angular-validation?
@@ -56,7 +56,7 @@ into the following (errors will automatically be displayed in your chosen locale
```
The Angular-Validation will create, by itself, the necessary error message. Now imagine your form having 10 inputs, using the documented Angular way will end up being 30 lines of code, while on the other hand `Angular-Validation` will stay with 10 lines of code, no more... so what are you waiting for? Use Angular-Validation!!! Don't forget to add it to your favorite, click on the **Star** on top :)
-Let's not forget the [Validation Summary](/ghiscoding/angular-validation/wiki/Validation-Summary) which is also a great and useful way of displaying your errors to the user.
+Let's not forget the [Validation Summary](https://github.com/ghiscoding/angular-validation/wiki/Validation-Summary) which is also a great and useful way of displaying your errors to the user.
Another awesome feature recently added is the [Remote Validation (AJAX)](https://github.com/ghiscoding/angular-validation/wiki/Remote-Validation-(AJAX)) which is so convenient.
@@ -87,7 +87,7 @@ All the documentation has been moved to the Wiki section, see the [github wiki](
* [Global Options](https://github.com/ghiscoding/angular-validation/wiki/Global-Options)
* Validators
* [Available Validator Rules](https://github.com/ghiscoding/angular-validation/wiki/Available-Validators-(rules))
- * [Regular Expression](https://github.com/ghiscoding/angular-validation/wiki/Regular-Expressions-(Regex))
+ * [Regular Expression Pattern](https://github.com/ghiscoding/angular-validation/wiki/Regular-Expression-Pattern)
* Misc
* [Changelog](https://github.com/ghiscoding/angular-validation/wiki/CHANGELOG)
* [License](https://github.com/ghiscoding/angular-validation/wiki/License)
@@ -170,7 +170,7 @@ All validators are written as `snake_case` but it's up to the user's taste and c
* `ipv4` Check for valid IP (IPv4)
* `ipv6` Check for valid IP (IPv6)
* `match:n` Match another input field(n), where (n) must be the exact ngModel attribute of input field to compare to.
-* `match:n,t` Match another input field(n), same as (match:n) but also include (t) for alternate input name to be displayed in the error message (it still uses default translated text, if you really wish to replace the complete text error, then use [:alt](#alternate))
+* `match:n,t` Match another input field(n), same as (match:n) but also include (t) for alternate input name to be displayed in the error message (it still uses default translated text, if you really wish to replace the complete text error, then use [:alt](https://github.com/ghiscoding/angular-validation/wiki/Alternate-Text-on-Validators))
* `max_date_iso` alias of `date_iso_max`.
* `max_date_euro_long` alias of `date_euro_long_max`.
* `max_date_euro_short` alias of `date_euro_short_max`.
@@ -187,7 +187,7 @@ All validators are written as `snake_case` but it's up to the user's taste and c
* `min_num:n` Checks numeric value to be higher or equal than the number (n).
* `numeric` Only positive numeric value (float, integer).
* `numeric_signed` Only numeric value (float, integer) can also be signed (-/+).
-* `regex` Ensure it follows a regular expression pattern... please see [Regex](#regex) section
+* `pattern` Ensure it follows a regular expression pattern... please see [Regular Expression Pattern](https://github.com/ghiscoding/angular-validation/wiki/Regular-Expression-Pattern)
* `required` Ensures the specified key value exists and is not empty
* `time` Ensure time follows the format of (hh:mm) or (hh:mm:ss)
* `url` Check for valid URL or subdomain
\ No newline at end of file
diff --git a/src/validation-common.js b/src/validation-common.js
index 52b03b4..38cd0ca 100644
--- a/src/validation-common.js
+++ b/src/validation-common.js
@@ -106,11 +106,37 @@ angular
self.typingLimit = parseInt(_globalOptions.debounce, 10);
}
- // We first need to see if the validation holds a custom user regex, if it does treat it first
- // So why treat it separately? Because a Regex might hold pipe '|' and so we don't want to mix it with our regular validation pipe
+ // get the rules(or validation), inside directive it's named (validation), inside service(rules)
+ var rules = (self.validatorAttrs.hasOwnProperty('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
+ if(rules.indexOf("pattern=/") >= 0) {
+ 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.';
+ }
+ var pattern = matches[1];
+ var altMsg = (!!matches[2]) ? matches[2].replace(/\|(.*)/, '') : '';
+
+ // convert the string into a real RegExp pattern
+ var match = pattern.match(new RegExp('^/(.*?)/([gimy]*)$'));
+ var regex = new RegExp(match[1], match[2]);
+
+ customUserRegEx = {
+ altMsg: altMsg,
+ message: altMsg.replace(/:alt=/, ''),
+ pattern: regex
+ };
+
+ // rewrite the rules so that it doesn't contain any regular expression
+ // we simply remove the pattern so that it won't break the Angular-Validation since it also use the pipe |
+ rules = rules.replace('pattern=' + pattern, 'pattern');
+ }
+ // DEPRECATED, in prior version of 1.3.34 and less, the way of writing a regular expression was through regex:/.../:regex
+ // this is no longer supported but is still part of the code so that it won't break for anyone using previous way of validating
// Return string will have the complete regex pattern removed but we will keep ':regex' so that we can still loop over it
- var rules = (self.validatorAttrs.hasOwnProperty('rules')) ? self.validatorAttrs.rules : self.validatorAttrs.validation; // inside directive(validation), inside service(rules)
- if (rules.indexOf("regex:") >= 0) {
+ else if (rules.indexOf("regex:") >= 0) {
var matches = rules.match("regex:(.*?):regex");
if (matches.length < 2) {
throw 'Regex validator within the validation needs to be define with an opening "regex:" and a closing ":regex", please review your validator.';
@@ -119,7 +145,7 @@ angular
customUserRegEx = {
message: regAttrs[0],
pattern: regAttrs[1]
- }
+ };
// rewrite the rules so that it doesn't contain the regex: ... :regex ending
// we simply remove it so that it won't break if there's a pipe | inside the actual regex
@@ -373,8 +399,8 @@ angular
if (validator.type === "conditionalDate") {
// 1- we first need to validate that the Date input is well formed through regex
// run the Regex test through each iteration, if required (\S+) and is null then it's invalid automatically
- regex = new RegExp(validator.pattern, 'i');
- isValid = ((validator.pattern === "\\S+" || (!!rules && validator.pattern === "required")) && strValue === null) ? false : regex.test(strValue);
+ regex = new RegExp(validator.pattern);
+ isValid = ((!validator.pattern || validator.pattern.toString() === "/\\S+/" || (!!rules && validator.pattern === "required")) && strValue === null) ? false : regex.test(strValue);
// 2- date is valid, then we can do our conditional date check
if (isValid) {
@@ -398,7 +424,7 @@ angular
}
}
}
- // it might be a conditional number checking
+ // it might be a conditional number checking
else if (validator.type === "conditionalNumber") {
// if 2 params, then it's a between condition
if (validator.params.length == 2) {
@@ -411,14 +437,14 @@ angular
isValid = testCondition(validator.condition, parseFloat(strValue), parseFloat(validator.params[0]));
}
}
- // it might be a match input checking
+ // it might be a match input checking
else if (validator.type === "match") {
// get the element 'value' ngModel to compare to (passed as params[0], via an $eval('ng-model="modelToCompareName"')
var otherNgModel = validator.params[0];
var otherNgModelVal = self.scope.$eval(otherNgModel);
isValid = (otherNgModelVal === strValue && !!strValue);
}
- // it might be a remote validation, this should return a promise with the result as a boolean or a { isValid: bool, message: msg }
+ // it might be a remote validation, this should return a promise with the result as a boolean or a { isValid: bool, message: msg }
else if (validator.type === "remote") {
if (!!strValue && !!showError) {
self.ctrl.$processing = true; // $processing can be use in the DOM to display a remote processing message to the user
@@ -488,7 +514,7 @@ angular
}
}
}
- // or finally it might be a regular regex pattern checking
+ // or finally it might be a regular regex pattern checking
else {
// get the ngDisabled attribute if found
var elmAttrNgDisabled = (typeof self.attrs !== "undefined") ? self.attrs.ngDisabled : self.validatorAttrs.ngDisabled;
@@ -503,8 +529,8 @@ angular
//message = $translate.instant("INVALID_KEY_CHAR");
} else {
// run the Regex test through each iteration, if required (\S+) and is null then it's invalid automatically
- regex = new RegExp(validator.pattern, 'i');
- isValid = ((validator.pattern === "\\S+" || (!!rules && validator.pattern === "required")) && strValue === null) ? false : regex.test(strValue);
+ regex = new RegExp(validator.pattern);
+ isValid = ((!validator.pattern || validator.pattern.toString() === "/\\S+/" || (!!rules && validator.pattern === "required")) && strValue === null) ? false : regex.test(strValue);
}
}
}
diff --git a/src/validation-rules.js b/src/validation-rules.js
index 42bb335..6b6039e 100644
--- a/src/validation-rules.js
+++ b/src/validation-rules.js
@@ -39,7 +39,7 @@ angular
switch(rule) {
case "alpha" :
validator = {
- pattern: "^([a-zÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ])+$/i,
message: "INVALID_ALPHA",
type: "regex"
};
@@ -47,7 +47,7 @@ angular
case "alphaSpaces" :
case "alpha_spaces" :
validator = {
- pattern: "^([a-zÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ\s])+$/i,
message: "INVALID_ALPHA_SPACE",
type: "regex"
};
@@ -55,7 +55,7 @@ angular
case "alphaNum" :
case "alpha_num" :
validator = {
- pattern: "^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9])+$/i,
message: "INVALID_ALPHA_NUM",
type: "regex"
};
@@ -63,7 +63,7 @@ angular
case "alphaNumSpaces" :
case "alpha_num_spaces" :
validator = {
- pattern: "^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s])+$/i,
message: "INVALID_ALPHA_NUM_SPACE",
type: "regex"
};
@@ -71,7 +71,7 @@ angular
case "alphaDash" :
case "alpha_dash" :
validator = {
- pattern: "^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ_-])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9_-])+$/i,
message: "INVALID_ALPHA_DASH",
type: "regex"
};
@@ -79,7 +79,7 @@ angular
case "alphaDashSpaces" :
case "alpha_dash_spaces" :
validator = {
- pattern: "^([a-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðòóôõöøùúûüýÿ\\s_-])+$",
+ pattern: /^([a-zа-яàáâãäåæçèéêëœìíïîðòóôõöøùúûñüýÿßÞďđ0-9\s_-])+$/i,
message: "INVALID_ALPHA_DASH_SPACE",
type: "regex"
};
@@ -112,14 +112,14 @@ angular
break;
case "boolean":
validator = {
- pattern: "^(true|True|false|False|0|1)$",
+ pattern: /^(true|false|0|1)$/i,
message: "INVALID_BOOLEAN",
type: "regex"
};
break;
case "checked":
validator = {
- pattern: "^true$",
+ pattern: /^true$/i,
message: "INVALID_CHECKBOX_SELECTED",
type: "regex"
};
@@ -127,7 +127,7 @@ angular
case "creditCard" :
case "credit_card" :
validator = {
- 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})$",
+ 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"
};
@@ -135,7 +135,7 @@ angular
case "dateEuroLong" :
case "date_euro_long" :
validator = {
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -152,7 +152,7 @@ angular
condition: [">=","<="],
dateType: "EURO_LONG",
params: [ranges[0], ranges[1]],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -165,7 +165,7 @@ angular
condition: "<=",
dateType: "EURO_LONG",
params: [ruleParams],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -178,7 +178,7 @@ angular
condition: ">=",
dateType: "EURO_LONG",
params: [ruleParams],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -186,7 +186,7 @@ angular
case "dateEuroShort" :
case "date_euro_short" :
validator = {
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,
message: "INVALID_DATE_EURO_SHORT",
type: "regex"
};
@@ -203,7 +203,7 @@ angular
condition: [">=","<="],
dateType: "EURO_SHORT",
params: [ranges[0], ranges[1]],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,
message: "INVALID_DATE_EURO_SHORT_BETWEEN",
type: "conditionalDate"
};
@@ -216,7 +216,7 @@ angular
condition: "<=",
dateType: "EURO_SHORT",
params: [ruleParams],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,
message: "INVALID_DATE_EURO_SHORT_MAX",
type: "conditionalDate"
};
@@ -229,7 +229,7 @@ angular
condition: ">=",
dateType: "EURO_SHORT",
params: [ruleParams],
- pattern: "^(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|[12][0-9]|3[01])[-\/\.](0[1-9]|1[012])[-\/\.]\d\d$/,
message: "INVALID_DATE_EURO_SHORT_MIN",
type: "conditionalDate"
};
@@ -237,7 +237,7 @@ angular
case "dateIso" :
case "date_iso" :
validator = {
- pattern: "^(19|20)\\d\\d([-])(0[1-9]|1[012])\\2(0[1-9]|[12][0-9]|3[01])$",
+ 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"
};
@@ -254,7 +254,7 @@ angular
condition: [">=","<="],
dateType: "ISO",
params: [ranges[0], ranges[1]],
- pattern: "^(19|20)\\d\\d([-])(0[1-9]|1[012])\\2(0[1-9]|[12][0-9]|3[01])$",
+ 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"
};
@@ -267,7 +267,7 @@ angular
condition: "<=",
dateType: "ISO",
params: [ruleParams],
- pattern: "^(19|20)\\d\\d([-])(0[1-9]|1[012])\\2(0[1-9]|[12][0-9]|3[01])$",
+ 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"
};
@@ -280,7 +280,7 @@ angular
condition: ">=",
dateType: "ISO",
params: [ruleParams],
- pattern: "^(19|20)\\d\\d([-])(0[1-9]|1[012])\\2(0[1-9]|[12][0-9]|3[01])$",
+ 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"
};
@@ -288,7 +288,7 @@ angular
case "dateUsLong" :
case "date_us_long" :
validator = {
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -305,7 +305,7 @@ angular
condition: [">=","<="],
dateType: "US_LONG",
params: [ranges[0], ranges[1]],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -318,7 +318,7 @@ angular
condition: "<=",
dateType: "US_LONG",
params: [ruleParams],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -331,7 +331,7 @@ angular
condition: ">=",
dateType: "US_LONG",
params: [ruleParams],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\\d\\d$",
+ 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"
};
@@ -339,7 +339,7 @@ angular
case "dateUsShort" :
case "date_us_short" :
validator = {
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,
message: "INVALID_DATE_US_SHORT",
type: "regex"
};
@@ -356,7 +356,7 @@ angular
condition: [">=","<="],
dateType: "US_SHORT",
params: [ranges[0], ranges[1]],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,
message: "INVALID_DATE_US_SHORT_BETWEEN",
type: "conditionalDate"
};
@@ -369,7 +369,7 @@ angular
condition: "<=",
dateType: "US_SHORT",
params: [ruleParams],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,
message: "INVALID_DATE_US_SHORT_MAX",
type: "conditionalDate"
};
@@ -382,7 +382,7 @@ angular
condition: ">=",
dateType: "US_SHORT",
params: [ruleParams],
- pattern: "^(0[1-9]|1[012])[-/.](0[1-9]|[12][0-9]|3[01])[-/.]\\d\\d$",
+ pattern: /^(0[1-9]|1[012])[-\/\.](0[1-9]|[12][0-9]|3[01])[-\/\.]\d\d$/,
message: "INVALID_DATE_US_SHORT_MIN",
type: "conditionalDate"
};
@@ -391,7 +391,7 @@ angular
validator = {
// Email RFC 5322, pattern pulled from http://www.regular-expressions.info/email.html
// but removed necessity of a TLD (Top Level Domain) which makes this email valid: admin@mailserver1
- pattern: "(?:[\\wа-я0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.?[\\wа-я0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\wа-я0-9](?:[\\wа-я0-9-]*[\\wа-я0-9])?\\.?)+[\\wа-я0-9](?:[\\wа-я0-9-]*[\\wа-я0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.?){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[\\wа-я0-9-]*[\\wа-я0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])",
+ 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"
};
@@ -407,7 +407,7 @@ angular
break;
case "float" :
validator = {
- pattern: "^\\d*\\.{1}\\d+$",
+ pattern: /^\d*\.{1}\d+$/,
message: "INVALID_FLOAT",
type: "regex"
};
@@ -415,14 +415,14 @@ angular
case "floatSigned" :
case "float_signed" :
validator = {
- pattern: "^[-+]?\\d*\\.{1}\\d+$",
+ pattern: /^[-+]?\d*\.{1}\d+$/,
message: "INVALID_FLOAT_SIGNED",
type: "regex"
};
break;
case "iban" :
validator = {
- pattern: "^[a-zA-Z]{2}\\d{2}\\s?([0-9a-zA-Z]{4}\\s?){4}[0-9a-zA-Z]{2}$",
+ 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"
};
@@ -430,7 +430,7 @@ angular
case "int" :
case "integer" :
validator = {
- pattern: "^\\d+$",
+ pattern: /^\d+$/,
message: "INVALID_INTEGER",
type: "regex"
};
@@ -440,21 +440,21 @@ angular
case "int_signed" :
case "integer_signed" :
validator = {
- pattern: "^[+-]?\\d+$",
+ pattern: /^[+-]?\d+$/,
message: "INVALID_INTEGER_SIGNED",
type: "regex"
};
break;
case "ipv4" :
validator = {
- pattern: "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$",
+ 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" :
validator = {
- pattern: "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",
+ pattern: /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/i,
message: "INVALID_IPV6",
type: "regex"
};
@@ -505,7 +505,7 @@ angular
break;
case "numeric" :
validator = {
- pattern: "^\\d*\\.?\\d+$",
+ pattern: /^\d*\.?\d+$/,
message: "INVALID_NUMERIC",
type: "regex"
};
@@ -513,11 +513,12 @@ angular
case "numericSigned" :
case "numeric_signed" :
validator = {
- pattern: "^[-+]?\\d*\\.?\\d+$",
+ pattern: /^[-+]?\d*\.?\d+$/,
message: "INVALID_NUMERIC_SIGNED",
type: "regex"
};
break;
+ case "pattern" :
case "regex" :
// Custom User Regex is a special case, the properties (message, pattern) were created and dealt separately prior to the for loop
validator = {
@@ -536,21 +537,21 @@ angular
break;
case "required" :
validator = {
- pattern: "\\S+",
+ pattern: /\S+/,
message: "INVALID_REQUIRED",
type: "regex"
};
break;
case "url" :
validator = {
- pattern: "(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?",
+ pattern: /^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i,
message: "INVALID_URL",
type: "regex"
};
break;
case "time" :
validator = {
- pattern: "^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$",
+ pattern: /^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/,
message: "INVALID_TIME",
type: "regex"
};
diff --git a/templates/testingFormDirective.html b/templates/testingFormDirective.html
index 1c7b429..0d88f39 100644
--- a/templates/testingFormDirective.html
+++ b/templates/testingFormDirective.html
@@ -51,7 +51,7 @@