From e87bb5e38e26521d78b3b98131aa2bd5caee4613 Mon Sep 17 00:00:00 2001 From: jcchavez Date: Mon, 30 Mar 2015 11:44:17 -0600 Subject: [PATCH 1/9] Integration of string resources for the es-ES culture. Translations by @juanchavezlive --- locales/validation/es.json | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 locales/validation/es.json diff --git a/locales/validation/es.json b/locales/validation/es.json new file mode 100644 index 0000000..9d62490 --- /dev/null +++ b/locales/validation/es.json @@ -0,0 +1,78 @@ +{ + "INVALID_ALPHA": "Unicamente puede contener letras. ", + "INVALID_ALPHA_SPACE": "Unicamente puede contener letras y espacios. ", + "INVALID_ALPHA_NUM": "Unicamente puede contener letras y números. ", + "INVALID_ALPHA_NUM_SPACE": "Unicamente puede contener letras, números y espacios. ", + "INVALID_ALPHA_DASH": "Unicamente puede contener letras, números y guiones. ", + "INVALID_ALPHA_DASH_SPACE": "Unicamente puede contener letras, números, guiones y espacios. ", + "INVALID_BETWEEN_CHAR": "El número de caracteres debe de estar entre :param y :param. ", + "INVALID_BETWEEN_NUM": "El valor debe ser númerico y estar entre :param y :param. ", + "INVALID_BOOLEAN": "Unicamente puede contener el texto "verdadero" ó "falso". ", + "INVALID_CREDIT_CARD": "Debe contener un número de tarjeta de crédito valido. ", + "INVALID_DATE_EURO_LONG": "Debe contener una fecha valida con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", + "INVALID_DATE_EURO_SHORT": "Debe contener una fecha valida con formato (dd-mm-yy) o (dd/mm/yy). ", + "INVALID_DATE_EURO_SHORT_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (dd-mm-yy) o (dd/mm/yy). ", + "INVALID_DATE_EURO_SHORT_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (dd-mm-yy) ó (dd/mm/yy). ", + "INVALID_DATE_EURO_SHORT_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (dd-mm-yy) ó (dd/mm/yy). ", + "INVALID_DATE_ISO": "Debe contener una fecha valida con formato (yyyy-mm-dd). ", + "INVALID_DATE_ISO_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (yyyy-mm-dd). ", + "INVALID_DATE_ISO_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (yyyy-mm-dd). ", + "INVALID_DATE_ISO_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (yyyy-mm-dd). ", + "INVALID_DATE_US_LONG": "Debe contener una fecha valida con formato (mm/dd/yyyy) ó (mm-dd-yyyy). ", + "INVALID_DATE_US_LONG_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", + "INVALID_DATE_US_LONG_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", + "INVALID_DATE_US_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", + "INVALID_DATE_US_SHORT": "Debe contener una fecha valida con formato (mm/dd/yy) ó (mm-dd-yy). ", + "INVALID_DATE_US_SHORT_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (mm/dd/yy) ó (mm/dd/yy). ", + "INVALID_DATE_US_SHORT_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (mm/dd/yy) ó (mm/dd/yy). ", + "INVALID_DATE_US_SHORT_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yy) ó (mm/dd/yy). ", + "INVALID_EMAIL": "Debe contener una dirección de correo electronico valida. ", + "INVALID_EXACT_LEN": "Debe contener exactamente :param caracteres. ", + "INVALID_FLOAT": "Debe contener un número decimal positivo (Los números enteros no son validos). ", + "INVALID_FLOAT_SIGNED": "Debe contener un número decimal positivo ó negativo (Los números enteros no son validos). ", + "INVALID_IBAN": "Debe contener un IBAN valido. ", + "INVALID_INPUT_MATCH": "El campo de confirnmación no coincide con el texto especificado \":param\". ", + "INVALID_INTEGER": "Debe contener un número entero positivo. ", + "INVALID_INTEGER_SIGNED": "Debe contener un número entero positivo ó negativo. ", + "INVALID_IPV4": "Debe contener una dirección IP valida (IPV4). ", + "INVALID_IPV6": "Debe contener una dirección IP valida (IPV6). ", + "INVALID_IPV6_HEX": "Debe contener una dirección IP valida (IPV6 Hex). ", + "INVALID_KEY_CHAR": "Entrada de teclado no valida en un campo de tipo \"number\". ", + "INVALID_MAX_CHAR": "No puede contener mas de :param caracteres. ", + "INVALID_MAX_NUM": "Debe contener un valor númerico igual o menor que :param. ", + "INVALID_MIN_CHAR": "Debe contener almenos :param caracteres. ", + "INVALID_MIN_NUM": "Debe contener un valor númerico igual o mayor que :param. ", + "INVALID_NUMERIC": "Debe contener un valor númerico positivo. ", + "INVALID_NUMERIC_SIGNED": "Debe contener un valor númerico positivo ó negativo. ", + "INVALID_PATTERN": "Debe contener un texto con el formato: :param. ", + "INVALID_REQUIRED": "El campo es requerido. ", + "INVALID_URL": "Debe contener una dirección URL valida. ", + "INVALID_TIME": "Debe contener un formato de tiempo valido (hh:mm) ó (hh:mm:ss). ", + "AREA1": "Area de texto: Alfanúmerica + Minimo(15) + Requerido", + "ERRORS": "Errores", + "CHANGE_LANGUAGE": "Cambiar idioma.", + "INPUT2": "Número positivo o negativo -- input type=\"number\" -- Error o caracteres no númericos ", + "INPUT3": "Rango decimal (Los números enteros no son validos) -- between_num:x,y ó min_num:x|max_num:y ", + "INPUT4": "Multiples validaciones + Código de fecha personalizado (YYWW)", + "INPUT5": "Email", + "INPUT6": "URL", + "INPUT7": "IP (IPV4)", + "INPUT8": "Tarjeta de cédito", + "INPUT9": "Entre(2,6) caracteres", + "INPUT10": "Fecha formato ISO (yyyy-mm-dd)", + "INPUT11": "Fecha formato US largo (mm/dd/yyyy)", + "INPUT12": "Tiempo (hh:mm ó hh:mm:ss) -- No Requerido", + "INPUT13": "AlphaDashSpaces + Requerido + Minimo(5) Caracteres -- Deben ser: validation-error-to=\" \"", + "INPUT14": "Alfanúmerico + Requerido -- NG-DISABLED", + "INPUT15": "Contraseña", + "INPUT16": "Confirmación de contraseña", + "INPUT17": "Alfanúmerico + Exactamente(3) + Requerido -- debounce(5sec)", + "INPUT18": "Fecha formato ISO (yyyy-mm-dd) -- Condición minima >= 2001-01-01 ", + "INPUT19": "Fecha formato US corto (mm/dd/yy) -- entre las fechas 12/01/99 and 12/31/15", + "SAVE": "Guardar", + "SELECT1": "Requerido (select) -- validación con (blur) EVENT", + "SHOW_VALIDATION_SUMMARY": "Mostar el resumén de validación" +} \ No newline at end of file From 5496cbd1e98f80d14eaf31066b4310cf7525970e Mon Sep 17 00:00:00 2001 From: jcchavez Date: Mon, 30 Mar 2015 11:47:55 -0600 Subject: [PATCH 2/9] Correction of invalid quotes. --- locales/validation/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/validation/es.json b/locales/validation/es.json index 9d62490..456e4e5 100644 --- a/locales/validation/es.json +++ b/locales/validation/es.json @@ -7,7 +7,7 @@ "INVALID_ALPHA_DASH_SPACE": "Unicamente puede contener letras, números, guiones y espacios. ", "INVALID_BETWEEN_CHAR": "El número de caracteres debe de estar entre :param y :param. ", "INVALID_BETWEEN_NUM": "El valor debe ser númerico y estar entre :param y :param. ", - "INVALID_BOOLEAN": "Unicamente puede contener el texto "verdadero" ó "falso". ", + "INVALID_BOOLEAN": "Unicamente puede contener el texto verdadero ó falso. ", "INVALID_CREDIT_CARD": "Debe contener un número de tarjeta de crédito valido. ", "INVALID_DATE_EURO_LONG": "Debe contener una fecha valida con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", "INVALID_DATE_EURO_LONG_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", From 050f9e5832dff8d1aa2297008deddd46f96e7231 Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 18:48:36 -0400 Subject: [PATCH 3/9] Added Spanish option on main page - Added Spanish option on main page - Fixed couple of typos - Fixed a delay problem on the validation summary display --- app.js | 8 ++++++-- index.html | 1 + locales/validation/en.json | 3 +-- locales/validation/es.json | 11 ++++++----- locales/validation/fr.json | 3 +-- readme.md | 12 ++++++------ 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app.js b/app.js index d4851c8..ab4ebb3 100644 --- a/app.js +++ b/app.js @@ -50,7 +50,9 @@ myApp.controller('CtrlValidationDirective', ['$scope', 'validationService', func } } $scope.showValidationSummary = function () { - $scope.displayValidationSummary = true; + $translate.then(function() { + $scope.displayValidationSummary = true; + }); } }]); @@ -104,7 +106,9 @@ myApp.controller('CtrlValidationService', ['$scope', '$translate', 'validationSe }; $scope.showValidationSummary = function () { - $scope.displayValidationSummary = true; + $translate.then(function() { + $scope.displayValidationSummary = true; + }); } $scope.submitForm = function() { diff --git a/index.html b/index.html index 0ac2849..b254ec9 100644 --- a/index.html +++ b/index.html @@ -19,6 +19,7 @@

Angular-Validation Directive|Service (ghiscoding)

+
Type: diff --git a/locales/validation/en.json b/locales/validation/en.json index 619b43f..35c8e10 100644 --- a/locales/validation/en.json +++ b/locales/validation/en.json @@ -52,10 +52,9 @@ "INVALID_URL": "Must be a valid URL. ", "INVALID_TIME": "Must be a valid time format (hh:mm) OR (hh:mm:ss). ", - "AREA1": "TextArea: Alphanumeric + Minimum(15) + Required", "ERRORS": "Errors", - "CHANGE_LANGUAGE": "Change language.", + "CHANGE_LANGUAGE": "Change language", "INPUT2": "Number positive or negative -- input type=\"number\" -- Error on non-numeric characters ", "INPUT3": "Floating number range (integer excluded) -- between_num:x,y OR min_num:x|max_num:y ", "INPUT4": "Multiple Validations + Custom Regex of Date Code (YYWW)", diff --git a/locales/validation/es.json b/locales/validation/es.json index 456e4e5..34a9927 100644 --- a/locales/validation/es.json +++ b/locales/validation/es.json @@ -12,7 +12,7 @@ "INVALID_DATE_EURO_LONG": "Debe contener una fecha valida con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", "INVALID_DATE_EURO_LONG_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", "INVALID_DATE_EURO_LONG_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", - "INVALID_DATE_EURO_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (dd-mm-yyyy) ó (dd/mm/yyyy). ", "INVALID_DATE_EURO_SHORT": "Debe contener una fecha valida con formato (dd-mm-yy) o (dd/mm/yy). ", "INVALID_DATE_EURO_SHORT_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (dd-mm-yy) o (dd/mm/yy). ", "INVALID_DATE_EURO_SHORT_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (dd-mm-yy) ó (dd/mm/yy). ", @@ -20,15 +20,15 @@ "INVALID_DATE_ISO": "Debe contener una fecha valida con formato (yyyy-mm-dd). ", "INVALID_DATE_ISO_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (yyyy-mm-dd). ", "INVALID_DATE_ISO_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (yyyy-mm-dd). ", - "INVALID_DATE_ISO_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (yyyy-mm-dd). ", + "INVALID_DATE_ISO_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (yyyy-mm-dd). ", "INVALID_DATE_US_LONG": "Debe contener una fecha valida con formato (mm/dd/yyyy) ó (mm-dd-yyyy). ", "INVALID_DATE_US_LONG_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", "INVALID_DATE_US_LONG_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", - "INVALID_DATE_US_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", + "INVALID_DATE_US_LONG_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yyyy) ó (mm/dd/yyyy). ", "INVALID_DATE_US_SHORT": "Debe contener una fecha valida con formato (mm/dd/yy) ó (mm-dd-yy). ", "INVALID_DATE_US_SHORT_BETWEEN": "Debe contener una fecha valida entre :param y :param con formato (mm/dd/yy) ó (mm/dd/yy). ", "INVALID_DATE_US_SHORT_MAX": "Debe contener una fecha valida igual ó menor que :param con formato (mm/dd/yy) ó (mm/dd/yy). ", - "INVALID_DATE_US_SHORT_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yy) ó (mm/dd/yy). ", + "INVALID_DATE_US_SHORT_MIN": "Debe contener una fecha valida igual ó mayor que :param con formato (mm/dd/yy) ó (mm/dd/yy). ", "INVALID_EMAIL": "Debe contener una dirección de correo electronico valida. ", "INVALID_EXACT_LEN": "Debe contener exactamente :param caracteres. ", "INVALID_FLOAT": "Debe contener un número decimal positivo (Los números enteros no son validos). ", @@ -51,9 +51,10 @@ "INVALID_REQUIRED": "El campo es requerido. ", "INVALID_URL": "Debe contener una dirección URL valida. ", "INVALID_TIME": "Debe contener un formato de tiempo valido (hh:mm) ó (hh:mm:ss). ", + "AREA1": "Area de texto: Alfanúmerica + Minimo(15) + Requerido", "ERRORS": "Errores", - "CHANGE_LANGUAGE": "Cambiar idioma.", + "CHANGE_LANGUAGE": "Cambiar idioma", "INPUT2": "Número positivo o negativo -- input type=\"number\" -- Error o caracteres no númericos ", "INPUT3": "Rango decimal (Los números enteros no son validos) -- between_num:x,y ó min_num:x|max_num:y ", "INPUT4": "Multiples validaciones + Código de fecha personalizado (YYWW)", diff --git a/locales/validation/fr.json b/locales/validation/fr.json index 11b68e4..dc4d574 100644 --- a/locales/validation/fr.json +++ b/locales/validation/fr.json @@ -52,10 +52,9 @@ "INVALID_URL": "Doit être un URL valide. ", "INVALID_TIME": "Doit être un format de date valide (hh:mm) OU (hh:mm:ss). ", - "AREA1": "TextArea: Alphanumérique + Minimum(15) + Required", "ERRORS": "Erreurs", - "CHANGE_LANGUAGE": "Changer de langue.", + "CHANGE_LANGUAGE": "Changer de langue", "INPUT2": "Nombre positif ou négatif -- input type=\"number\" -- Erreur sur caractères non-numérique", "INPUT3": "Intervalle de Nombre Flottant (entier exclu) -- between_num:x,y OU min_num:x|max_num:y", "INPUT4": "Multiple Validations + Regex Personnalisé d'un Code Date (AASS)", diff --git a/readme.md b/readme.md index 5364f30..ec98298 100644 --- a/readme.md +++ b/readme.md @@ -54,10 +54,10 @@ myApp.config(function ($translateProvider) { ``` ```html - + - + @@ -162,7 +162,7 @@ P.S. For real live sample, see the [live demo](#plunker) or download the Github ``` -## Form Submitting and Validation +## Form Submit and Validation The Angular-Validation concept was first introduced with the use `ngDisabled` on the submit button, but this might not always be the best option so as a another feature we could simply leave the submit button available but run an extra function to check the form validation before proceeding with our submit (that function is available through the ValidationService). *You could also use the [Validation summary](#validation-summary) for displaying all errors as a header or even a footer* @@ -266,9 +266,9 @@ Final code (without spaces): `regex:YYWW:=^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0 Locales (languages) -------------------- -Locales are simply sets of language defined in external JSON files, we can easily add any new language as extra files without affecting the behaviour of the angular directive. You could even change displayed language on the fly, well of course the error message will be reflected only after field value is re-evaluated. You of course have to include the `angular-translate` library and configure it, see section [Include it in your Project](#project) +Locales are simple sets of language defined in external JSON files, we can easily add any new language as extra files without affecting the behaviour of the angular directive. You could even change displayed language on the fly (note that the error message will be reflected only after field value is re-evaluated). Make sure to include the `angular-translate` library and configure it, see section [Include it in your Project](#project) -NOTE: To be fully localized, I should add the country code at the end of my JSON filename and then change the suffix on the `angular-translate` `loader` method, but then this would add an overhead and I prefer to keep it simple as validation messages often looks the same anyway. If you do want to be fully localized, then see the example in [Include it in your Project](#project) +NOTE: To be fully localized, I should add the country code at the end of my JSON filename and then change the suffix on the `angular-translate` `loader` method, but this would add an overhead and I prefer to keep it simple as validation messages often looks the same anyway (for example English from UK or US would most probably give similar error messages). If you really do want to be fully localized, then see the example in [Include it in your Project](#project) ```javascript // define a key, could be on the fly with a button or a menu link @@ -383,6 +383,6 @@ License * [1.3.5](https://github.com/ghiscoding/angular-validation/commit/679b24ca4daee8419731c45d1d65d63cb5ca74a5) `2015-01-26` Throw an error message when user did not provide a `name=""` property inside the element to validate. * [1.3.6](https://github.com/ghiscoding/angular-validation/commit/e47e91f45f93a3f191ab6849d06163563674e9e2) `2015-02-09` Added `ng-strict-di` for minification, renamed some files and folder lib to `/vendors`, moved directive into new `/src` folder for better separation. * [1.3.7](https://github.com/ghiscoding/angular-validation/commit/86c16f720d6687d3b5ca93e49a0a37824027e583) `2015-03-08` Complete rewrite (but same functionality) so that I could add an Angular-Validation Service which is similar implementation as the Directive. Also added `debounce` attribute which is an alias to `typingLimit`, validation rules are now defined as an external service for better maintainability and also created a common file for shared functions by both Validation Directive and Service. -* [1.3.8](https://github.com/ghiscoding/angular-validation/commit/492d1060a91fb8b49fc70a0c7a1a581d904e0db0) `2015-03-15` Added between/min/max conditional validators on all Date types (ISO, EURO_LONG, EURO_SHORT, US_LONG, US_SHORT) +* [1.3.8](https://github.com/ghiscoding/angular-validation/commit/492d1060a91fb8b49fc70a0c7a1a581d904e0db0) `2015-03-15` Added between/min/max conditional validators on all Date types (iso, euro_long, euro_short, us_long, us_short) * [1.3.9](https://github.com/ghiscoding/angular-validation/commit/931d3b04a00f0583612aefe28ad0bfcac326a38c) `2015-03-21` Added validation summary through 2 new and equivalent properties `$scope.$validationSummary` and `$scope.formName.$validationSummary`. Also added `bower` and `gulp` support, the Gulp script gives minified files. * [1.3.10](https://github.com/ghiscoding/angular-validation/commit/18765a8dd986856a9fa176fc4835d90d25f663b2) `2015-03-29` Added new function of `checkFormValidity()` before submitting the form. Now use only 1 minified script instead of multiples. \ No newline at end of file From a73505b994ad845fd937d13edd3cc856c9b48cbc Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 20:26:31 -0400 Subject: [PATCH 4/9] checkFormValidatity() work with $scope & form obj - Make the checkFormValidatity() work with both options of $scope alone or a form object $scope.form1 - Added index to readme --- readme.md | 31 +++++++++++++++++++++++++++---- src/validation-service.js | 14 +++++++------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/readme.md b/readme.md index ec98298..cff20c9 100644 --- a/readme.md +++ b/readme.md @@ -20,6 +20,23 @@ Huge rewrite to have a better code separation and also adding support to Service ## Live Demo [Plunker](http://plnkr.co/jADq7H) + +## Index +* [Plunker Demo](#plunker) +* [Dependency](#dependencies) +* [Install](#install) +* [Include it in your app project](#project) +* [Requirements](#requirements) +* [Some Working Examples (Directive)](#examples-directive) +* [Some Working Examples (Service)](#examples-service) +* [Form Submit](#submit) +* [Validation summary](#validation-summary) +* [Bootstrap Input Groups Wrapping - HOWTO](#input-groups-wrapping) +* [Regular Expressions (Regex)](#regex) +* [Locales (languages)](#locales) +* [Available Validators](#validators) +* [Changelog](#changelog) + Install ----- @@ -65,12 +82,13 @@ myApp.config(function ($translateProvider) { ``` + ## Requirements Angular-Validation requires the element which will use validation to have an html `name=""` attribute, so that in the background it can use this name to create and show an error into a `` which will directly follow your form input. For example: ``. *The necessity of `name=""` attribute is new since version 1.3.4+, prior to this change we were asking the user to create his own `` for error displaying. In other words, the `` is now optional, but the `name=""` attribute becomes mandatory and will throw an error if omitted* - + ## Some Working Examples (Directive) Let's start with a simple example and then let's get down to real business. @@ -175,6 +193,9 @@ The Angular-Validation concept was first introduced with the use `ngDisabled` on ``` ```javascript // Option #2 will need to call the `checkFormValidity()` function checking the form before doing a real submit +// $validationSummary can be found in 2 variables (depending if your form as a name or not) +// you can use `checkFormValidity($scope.form1)` or this `checkFormValidity($scope)` +// If your form does not have a name attribute, your only choice is `checkFormValidity($scope)` $scope.submitForm = function() { var myValidation = new validationService(); if(myValidation.checkFormValidity($scope.form1)) { @@ -211,6 +232,7 @@ Display a validation summary of all the current form errors. Validation summary ``` + Bootstrap Input Groups Wrapping - HOWTO -------------------- Well let's face it, having the `` for error display right after the element to be validated is not always ideal and I encounter the problem myself when using Bootstrap on inputs with `input-group`, it had so much wrapping around the input that the next available element might not be the one we want. In these special occasions, we will add a `` or a `
` for displaying the possible error and give the this element an `id="someId"` or a `class="className"` and then reference it inside our input. We could actually move the error element anywhere we want with this method, just don't forget to name it with an `id` or a `className` and call the `validation-error-to` attribute. This attribute could be called in 3 different ways: with `'.'` (element error className) or with/without `'#'` (element error id) We could even do a validation summary with this...just saying hehe. @@ -250,7 +272,7 @@ From the example displayed, I introduce the custom regular expression, there is Regex validation is divided in 4 specific parts (Step #1-4). -Let's use the previous [Examples #5](#examples-directives) and extract the information out of it to see how it works. +Let's use the previous [Examples #5](#examples-directive) and extract the information out of it to see how it works. Step #1-4 are for explanation only, at the end we show the full regex (make sure there is no spaces). 1. Start & end the filter with the following `regex: :regex` which tells the directive where to extract it. @@ -263,7 +285,7 @@ Step #1-4 are for explanation only, at the end we show the full regex (make sure Final code (without spaces): `regex:YYWW:=^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$:regex` - + Locales (languages) -------------------- Locales are simple sets of language defined in external JSON files, we can easily add any new language as extra files without affecting the behaviour of the angular directive. You could even change displayed language on the fly (note that the error message will be reflected only after field value is re-evaluated). Make sure to include the `angular-translate` library and configure it, see section [Include it in your Project](#project) @@ -281,9 +303,9 @@ $scope.switchLanguage = function (key) { }); }; ``` - *P.S. If you define a new Language set, please make a pull request and I would be happy to add them in current project... It would be nice to have Spanish, German or even Chinese :) Thank you.* + Available Validators -------------------- All validators are written as `snake_case` but it's up to the user's taste and could also be written as `camelCase`. So for example `alpha_dash_spaces` and `alphaDashSpaces` are both equivalent. @@ -374,6 +396,7 @@ License * Add more validators... * Add more locale languages... I need your help on that one!!! + ## CHANGELOG * [1.3.0](https://github.com/ghiscoding/angular-validation/commit/d106996926bef86a0457c90fbb65fe6233f3928d) `2014-12-01` Added support to AngularJS 1.3 * [1.3.1](https://github.com/ghiscoding/angular-validation/commit/44fe9de050504a46bb0eb975c31bc4b0f3b6f516) `2015-01-02` Added Input Match/Confirmation Validator, ex: password confirmation. diff --git a/src/validation-service.js b/src/validation-service.js index 722c814..f2df333 100644 --- a/src/validation-service.js +++ b/src/validation-service.js @@ -90,26 +90,26 @@ angular } // addValidator() /** Is the Form all valid? Loop through Validation Summary to get the answer, if any errors are there then display them and return false - * @param object Angular Form Object + * @param object Angular Form or Scope Object * @return bool isFormValid */ - function checkFormValidity(form) { + function checkFormValidity(obj) { var self = this; var ctrl, elm, elmName = '', isValid = true; - if(typeof form === "undefined") { - throw 'Form validaty checking requires a valid form object passed as argument'; + if(typeof obj === "undefined" || typeof obj.$validationSummary === "undefined") { + throw 'Form validaty checking requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).'; } // loop through $validationSummary and display errors when found on each field - for(var i = 0, ln = form.$validationSummary.length; i < ln; i++) { + for(var i = 0, ln = obj.$validationSummary.length; i < ln; i++) { isValid = false; - elmName = form.$validationSummary[i].field; + elmName = obj.$validationSummary[i].field; elm = angular.element(document.querySelector('[name="'+elmName+'"]:not([disabled]):not([ng-disabled]')); ctrl = angular.element(elm).controller('ngModel'); if(!!elm && elm.length > 0) { ctrl.$setTouched(); // make the element as it was touched for CSS - self.commonObj.updateErrorMsg(form.$validationSummary[i].message, {valid: false, elm: elm, submitted: true}); + self.commonObj.updateErrorMsg(obj.$validationSummary[i].message, {valid: false, elm: elm, submitted: true}); } } return isValid; From 700b3d25d3e797e3c9de59dc2b2348756519e2fa Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 20:31:22 -0400 Subject: [PATCH 5/9] recompiled minification with checkFormValidity() --- dist/angular-validation.min.js | 6 +++--- readme.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index c39ae59..1283edf 100644 --- a/dist/angular-validation.min.js +++ b/dist/angular-validation.min.js @@ -4,9 +4,9 @@ * @author: Ghislain B. * @version: 1.3.10 * @license: MIT - * @build: Sun Mar 29 2015 00:27:23 GMT-0400 (Eastern Daylight Time) + * @build: Mon Mar 30 2015 20:29:03 GMT-0400 (Eastern Daylight Time) */ angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$timeout","validationCommon","validationRules",function(i,t){return{restrict:"A",require:"ngModel",link:function(a,e,n,l){function d(){i.cancel(r),u.updateErrorMsg(""),l.$setValidity("validation",!0),e.unbind("blur")}function o(t){return u.validate(t,!1),u.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((u.isFieldRequired()||t)&&l.$setValidity("validation",!1),e.bind("blur",function(){return a.$evalAsync(l.$setValidity("validation",u.validate(t,!0))),t}),"SELECT"===e.prop("tagName").toUpperCase()?(l.$setValidity("validation",u.validate(t,!0)),t):("undefined"!=typeof t&&(u.updateErrorMsg(""),i.cancel(r),r=i(function(){a.$evalAsync(l.$setValidity("validation",u.validate(t,!0)))},u.typingLimit)),t)):(d(),t)}var r,u=new t(a,e,n,l);l.$parsers.unshift(o),l.$formatters.unshift(o),n.$observe("disabled",function(i){i?l.$setValidity("validation",!0):l.$setValidity("validation",u.validate(l.$viewValue,!0))})}}}]); -angular.module("ghiscoding.validation").factory("validationCommon",["$timeout","$translate","validationRules",function(t,a,e){function r(){var t=this,a={};t.validators=[],t.typingLimit=c,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")&&(t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10));var r=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(r.indexOf("regex:")>=0){var i=r.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 s=i[1].split(":=");a={message:s[0],pattern:s[1]},r=r.replace(i[0],"regex:")}var n=r.split("|");if(n){t.bFieldRequired=n.indexOf("required")>=0?!0:!1;for(var l=0,o=n.length;o>l;l++){var d=n[l].split(":");t.validators[l]=e.getElementValidators(d[0],d[1],a)}}return t}function i(t,a,e,r){this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,this.defineValidation()}function s(){var t=this;return t.bFieldRequired}function n(t,e){var r=this,i=e&&e.elm?e.elm:r.elm,s=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof s||null===s)throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+i.attr("ng-model")+'"';var n=e&&e.translate?a.instant(t):t,l=s.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),o=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),v="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;o=angular.element(document.querySelector(v))}else o=angular.element(document.querySelector(".validation-"+l));var p=e&&e.submitted?e.submitted:!1;e&&!e.valid&&(p||r.ctrl.$dirty||r.ctrl.$touched)?o.length>0?o.text(n):i.after(''+n+""):o.text("")}function l(t,e){for(var r,i=this,s=!0,n=!0,l="",d=0,p=i.validators.length;p>d;d++){if("conditionalDate"===i.validators[d].type){if(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1){var c=i.validators[d].dateType,g=v(t,c).getTime();if(2==i.validators[d].params.length){var m=v(i.validators[d].params[0],c).getTime(),h=v(i.validators[d].params[1],c).getTime(),f=u(i.validators[d].condition[0],g,m),b=u(i.validators[d].condition[1],g,h);n=f&&b?!0:!1}else{var y=v(i.validators[d].params[0],c).getTime();n=u(i.validators[d].condition,g,y)}}}else if("conditionalNumber"===i.validators[d].type)if(2==i.validators[d].params.length){var f=u(i.validators[d].condition[0],parseFloat(t),parseFloat(i.validators[d].params[0])),b=u(i.validators[d].condition[1],parseFloat(t),parseFloat(i.validators[d].params[1]));n=f&&b?!0:!1}else n=u(i.validators[d].condition,parseFloat(t),parseFloat(i.validators[d].params[0]));else if("match"===i.validators[d].type){var O=i.validators[d].params[0],R=i.scope.$eval(O);n=R===t}else i.elm.prop("disabled")?n=!0:"string"==typeof t&&""===t&&"NUMBER"===i.elm.prop("type").toUpperCase()?(l=a.instant("INVALID_KEY_CHAR"),n=!1):(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1);if(!n&&(s=!1,l+=a.instant(i.validators[d].message),"undefined"!=typeof i.validators[d].params))for(var A=0,E=i.validators[d].params.length;E>A;A++)"match"===i.validators[d].type&&E>1&&0===A||(l=l.replace(":param",i.validators[d].params[A]))}return o(i,a.instant(l)),e&&i.updateErrorMsg(l,{valid:s}),s}function o(t,a){var e=t.elm.attr("name"),r=d(g,"field",e);if(r>=0&&""===a)g.splice(r,1);else if(""!==a){var i={field:e,message:a};r>=0?g[r]=i:g.push(i)}t.scope.$validationSummary=g;var s=angular.element(document.querySelector("form")).attr("name");s&&(t.scope[s].$validationSummary=g)}function d(t,a,e){for(var r=0;r8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":e=t.substring(0,8),r=t.substring(2,3),i=p(e,r),o=i[0],l=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":e=t.substring(0,10),r=t.substring(2,3),i=p(e,r),l=i[0],o=i[1],n=i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":e=t.substring(0,8),r=t.substring(2,3),i=p(e,r),l=i[0],o=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:e=t.substring(0,10),r=t.substring(4,5),i=p(e,r),n=i[0],l=i[1],o=i[2],s=t.length>10?t.substring(11).split(":"):null}var d=s&&3===s.length?s[0]:0,v=s&&3===s.length?s[1]:0,u=s&&3===s.length?s[2]:0;return new Date(n,l-1,o,d,v,u)}function p(t,a){var e=[];switch(a){case"/":e=t.split("/");break;case".":e=t.split(".");break;case"-":default:e=t.split("-")}return e}function u(t,a,e){var r=!1;switch(t){case"<":r=e>a?!0:!1;break;case"<=":r=e>=a?!0:!1;break;case">":r=a>e?!0:!1;break;case">=":r=a>=e?!0:!1;break;case"!=":case"<>":r=a!=e?!0:!1;break;case"=":case"==":r=a==e?!0:!1;break;default:r=!1}return r}var c=1e3,g=[],m=function(t,a,e,r){this.timer=null,this.bFieldRequired=!1,this.validators=[],this.typingLimit=c,this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,t&&a&&e&&r&&this.defineValidation()};return m.prototype.defineValidation=r,m.prototype.isFieldRequired=s,m.prototype.initialize=i,m.prototype.updateErrorMsg=n,m.prototype.validate=l,m}]); +angular.module("ghiscoding.validation").factory("validationCommon",["$timeout","$translate","validationRules",function(t,a,e){function r(){var t=this,a={};t.validators=[],t.typingLimit=m,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")&&(t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10));var r=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(r.indexOf("regex:")>=0){var i=r.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 s=i[1].split(":=");a={message:s[0],pattern:s[1]},r=r.replace(i[0],"regex:")}var n=r.split("|");if(n){t.bFieldRequired=n.indexOf("required")>=0?!0:!1;for(var l=0,o=n.length;o>l;l++){var d=n[l].split(":");t.validators[l]=e.getElementValidators(d[0],d[1],a)}}return t}function i(t,a,e,r){this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,this.defineValidation()}function s(){var t=this;return t.bFieldRequired}function n(t,e){var r=this,i=e&&e.elm?e.elm:r.elm,s=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof s||null===s)throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+i.attr("ng-model")+'"';var n=e&&e.translate?a.instant(t):t,l=s.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),o=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),v="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;o=angular.element(document.querySelector(v))}else o=angular.element(document.querySelector(".validation-"+l));var u=e&&e.submitted?e.submitted:!1;e&&!e.valid&&(u||r.ctrl.$dirty||r.ctrl.$touched)?o.length>0?o.text(n):i.after(''+n+""):o.text("")}function l(t,e){for(var r,i=this,s=!0,n=!0,l="",o=0,d=i.validators.length;d>o;o++){if("conditionalDate"===i.validators[o].type){if(r=new RegExp(i.validators[o].pattern,"i"),n="\\S+"!==i.validators[o].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1){var u=i.validators[o].dateType,c=p(t,u).getTime();if(2==i.validators[o].params.length){var m=p(i.validators[o].params[0],u).getTime(),f=p(i.validators[o].params[1],u).getTime(),h=g(i.validators[o].condition[0],c,m),b=g(i.validators[o].condition[1],c,f);n=h&&b?!0:!1}else{var y=p(i.validators[o].params[0],u).getTime();n=g(i.validators[o].condition,c,y)}}}else if("conditionalNumber"===i.validators[o].type)if(2==i.validators[o].params.length){var h=g(i.validators[o].condition[0],parseFloat(t),parseFloat(i.validators[o].params[0])),b=g(i.validators[o].condition[1],parseFloat(t),parseFloat(i.validators[o].params[1]));n=h&&b?!0:!1}else n=g(i.validators[o].condition,parseFloat(t),parseFloat(i.validators[o].params[0]));else if("match"===i.validators[o].type){var A=i.validators[o].params[0],O=i.scope.$eval(A);n=O===t}else i.elm.prop("disabled")?n=!0:"string"==typeof t&&""===t&&"NUMBER"===i.elm.prop("type").toUpperCase()?(l=a.instant("INVALID_KEY_CHAR"),n=!1):(r=new RegExp(i.validators[o].pattern,"i"),n="\\S+"!==i.validators[o].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1);if(!n&&(s=!1,l+=a.instant(i.validators[o].message),"undefined"!=typeof i.validators[o].params))for(var R=0,S=i.validators[o].params.length;S>R;R++)"match"===i.validators[o].type&&S>1&&0===R||(l=l.replace(":param",i.validators[o].params[R]))}return v(i,a.instant(l)),e&&i.updateErrorMsg(l,{valid:s}),s}function o(t){for(var a=document.querySelectorAll("form"),e=0;ea;a++)if(t.elements[a].getAttribute("validation"))return!0;return!1}function v(t,a){var e=t.elm.attr("name"),r=u(f,"field",e);if(r>=0&&""===a)f.splice(r,1);else if(""!==a){var i={field:e,message:a};r>=0?f[r]=i:f.push(i)}t.scope.$validationSummary=f;var s=o(t);s&&(s.$validationSummary=f)}function u(t,a,e){for(var r=0;r8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":e=t.substring(0,8),r=t.substring(2,3),i=c(e,r),o=i[0],l=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":e=t.substring(0,10),r=t.substring(2,3),i=c(e,r),l=i[0],o=i[1],n=i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":e=t.substring(0,8),r=t.substring(2,3),i=c(e,r),l=i[0],o=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:e=t.substring(0,10),r=t.substring(4,5),i=c(e,r),n=i[0],l=i[1],o=i[2],s=t.length>10?t.substring(11).split(":"):null}var d=s&&3===s.length?s[0]:0,v=s&&3===s.length?s[1]:0,u=s&&3===s.length?s[2]:0;return new Date(n,l-1,o,d,v,u)}function c(t,a){var e=[];switch(a){case"/":e=t.split("/");break;case".":e=t.split(".");break;case"-":default:e=t.split("-")}return e}function g(t,a,e){var r=!1;switch(t){case"<":r=e>a?!0:!1;break;case"<=":r=e>=a?!0:!1;break;case">":r=a>e?!0:!1;break;case">=":r=a>=e?!0:!1;break;case"!=":case"<>":r=a!=e?!0:!1;break;case"=":case"==":r=a==e?!0:!1;break;default:r=!1}return r}var m=1e3,f=[],h=function(t,a,e,r){this.timer=null,this.bFieldRequired=!1,this.validators=[],this.typingLimit=m,this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,t&&a&&e&&r&&this.defineValidation()};return h.prototype.defineValidation=r,h.prototype.isFieldRequired=s,h.prototype.initialize=i,h.prototype.updateErrorMsg=n,h.prototype.validate=l,h}]); angular.module("ghiscoding.validation").factory("validationRules",[function(){function e(e,a,t){var s={};switch(e){case"alpha":s={pattern:"^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$",message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":s={pattern:"^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s])+$",message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$",message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s])+$",message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ_-])+$",message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s_-])+$",message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"betweenLen":case"between_len":var n=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";s={pattern:"^.{"+n[0]+","+n[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[n[0],n[1]],type:"regex"};break;case"betweenNum":case"between_num":var n=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";s={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[n[0],n[1]],type:"conditionalNumber"};break;case"creditCard":case"credit_card":s={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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_long:01-01-1990,31-12-2015";s={condition:[">=","<="],dateType:"EURO_LONG",params:[n[0],n[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":s={condition:"<=",dateType:"EURO_LONG",params:[a],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":s={condition:">=",dateType:"EURO_LONG",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_short:01-01-90,31-12-15";s={condition:[">=","<="],dateType:"EURO_SHORT",params:[n[0],n[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":s={condition:"<=",dateType:"EURO_SHORT",params:[a],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":s={condition:">=",dateType:"EURO_SHORT",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_iso:1990-01-01,2000-12-31";s={condition:[">=","<="],dateType:"ISO",params:[n[0],n[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":s={condition:"<=",dateType:"ISO",params:[a],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":s={condition:">=",dateType:"ISO",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_long:01/01/1990,12/31/2015";s={condition:[">=","<="],dateType:"US_LONG",params:[n[0],n[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":s={condition:"<=",dateType:"US_LONG",params:[a],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":s={condition:">=",dateType:"US_LONG",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_short:01/01/90,12/31/15";s={condition:[">=","<="],dateType:"US_SHORT",params:[n[0],n[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":s={condition:"<=",dateType:"US_SHORT",params:[a],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":s={condition:">=",dateType:"US_SHORT",params:[a],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":s={pattern:"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",message:"INVALID_EMAIL",type:"regex"};break;case"exactLen":case"exact_len":s={pattern:"^.{"+a+"}$",message:"INVALID_EXACT_LEN",params:[a],type:"regex"};break;case"float":s={pattern:"^\\d*\\.{1}\\d+$",message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":s={pattern:"^[-+]?\\d*\\.{1}\\d+$",message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":s={pattern:"[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}",message:"INVALID_IBAN",type:"regex"};break;case"int":case"integer":s={pattern:"^\\d+$",message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":s={pattern:"^[+-]?\\d+$",message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ipv4":s={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":s={pattern:"^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",message:"INVALID_IPV6",type:"regex"};break;case"ipv6_hex":s={pattern:"^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$",message:"INVALID_IPV6_HEX",type:"regex"};break;case"match":var _=a.split(",");s={message:"INVALID_INPUT_MATCH",params:_,type:"match"};break;case"maxLen":case"max_len":s={pattern:"^.{0,"+a+"}$",message:"INVALID_MAX_CHAR",params:[a],type:"regex"};break;case"maxNum":case"max_num":s={condition:"<=",message:"INVALID_MAX_NUM",params:[a],type:"conditionalNumber"};break;case"minLen":case"min_len":s={pattern:"^.{"+a+",}$",message:"INVALID_MIN_CHAR",params:[a],type:"regex"};break;case"minNum":case"min_num":s={condition:">=",message:"INVALID_MIN_NUM",params:[a],type:"conditionalNumber"};break;case"numeric":s={pattern:"^\\d*\\.?\\d+$",message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":s={pattern:"^[-+]?\\d*\\.?\\d+$",message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"regex":s={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"required":s={pattern:"\\S+",message:"INVALID_REQUIRED",type:"regex"};break;case"url":s={pattern:"(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?",message:"INVALID_URL",type:"regex"};break;case"time":s={pattern:"^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$",message:"INVALID_TIME",type:"regex"}}return s}var a={getElementValidators:e};return a}]); -angular.module("ghiscoding.validation").service("validationService",["$timeout","validationCommon",function(e,o){function t(e,o){var t=this,n={};if("string"==typeof e&&"string"==typeof o?(n.elmName=e,n.rules=o):n=e,"object"!=typeof n||!n.hasOwnProperty("elmName")||!n.hasOwnProperty("rules")||!n.hasOwnProperty("scope")&&"undefined"==typeof t.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";return n.elm=angular.element(document.querySelector('[name="'+n.elmName+'"]:not([disabled]):not([ng-disabled]')),"object"!=typeof n.elm||0===n.elm.length?t:(n.elm.bind("blur",function(e){t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),t.commonObj.typingLimit=0,r(t,e.target.value)}),n=m(t.validationAttrs,n),n.scope.$watch(n.elmName,function(e,o){return void 0===e&&void 0!==o?void t.commonObj.updateErrorMsg("INVALID_KEY_CHAR",{valid:!1,translate:!0}):(n.ctrl=angular.element(n.elm).controller("ngModel"),n.value=e,t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),void r(t,e))},!0),t)}function n(e){var o,t,n=this,i="",a=!0;if("undefined"==typeof e)throw"Form validaty checking requires a valid form object passed as argument";for(var r=0,l=e.$validationSummary.length;l>r;r++)a=!1,i=e.$validationSummary[r].field,t=angular.element(document.querySelector('[name="'+i+'"]:not([disabled]):not([ng-disabled]')),o=angular.element(t).controller("ngModel"),t&&t.length>0&&(o.$setTouched(),n.commonObj.updateErrorMsg(e.$validationSummary[r].message,{valid:!1,elm:t,submitted:!0}));return a}function i(e){var o=this;if(e instanceof Array)for(var t=0,n=e.length;n>t;t++)c(o,e[t]);else c(o,e)}function a(e){var o=this;return o.validationAttrs=e,o}function r(o,t){return o.commonObj.validate(t,!1),o.commonObj.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((o.commonObj.isFieldRequired()||t)&&o.commonObj.ctrl.$setValidity("validation",!1),"SELECT"===o.commonObj.elm.prop("tagName").toUpperCase()?(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)),t):("undefined"!=typeof t&&(o.commonObj.updateErrorMsg(""),e.cancel(o.timer),o.timer=e(function(){o.commonObj.scope.$evalAsync(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)))},o.commonObj.typingLimit)),t)):(l(o),t)}function l(o){e.cancel(self.timer),o.commonObj.updateErrorMsg(""),o.commonObj.ctrl.$setValidity("validation",!0),o.commonObj.elm.unbind("blur")}function m(e,o){var t={};for(var n in e)t[n]=e[n];for(var n in o)t[n]=o[n];return t}function c(e,o){if("undefined"!=typeof e.commonObj.scope){var t=e.commonObj.scope.$watch(o,function(){});t();var n=angular.element(document.querySelector('[name="'+o+'"]'));n.unbind("blur")}}var d=function(){this.validationAttrs={},this.commonObj=new o};return d.prototype.addValidator=t,d.prototype.checkFormValidity=n,d.prototype.removeValidator=i,d.prototype.setGlobalOptions=a,d}]); \ No newline at end of file +angular.module("ghiscoding.validation").service("validationService",["$timeout","validationCommon",function(e,o){function t(e,o){var t=this,n={};if("string"==typeof e&&"string"==typeof o?(n.elmName=e,n.rules=o):n=e,"object"!=typeof n||!n.hasOwnProperty("elmName")||!n.hasOwnProperty("rules")||!n.hasOwnProperty("scope")&&"undefined"==typeof t.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";return n.elm=angular.element(document.querySelector('[name="'+n.elmName+'"]:not([disabled]):not([ng-disabled]')),"object"!=typeof n.elm||0===n.elm.length?t:(n.elm.bind("blur",function(e){t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),t.commonObj.typingLimit=0,r(t,e.target.value)}),n=m(t.validationAttrs,n),n.scope.$watch(n.elmName,function(e,o){return void 0===e&&void 0!==o?void t.commonObj.updateErrorMsg("INVALID_KEY_CHAR",{valid:!1,translate:!0}):(n.ctrl=angular.element(n.elm).controller("ngModel"),n.value=e,t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),void r(t,e))},!0),t)}function n(e){var o,t,n=this,i="",a=!0;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"Form validaty checking requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).";for(var r=0,l=e.$validationSummary.length;l>r;r++)a=!1,i=e.$validationSummary[r].field,t=angular.element(document.querySelector('[name="'+i+'"]:not([disabled]):not([ng-disabled]')),o=angular.element(t).controller("ngModel"),t&&t.length>0&&(o.$setTouched(),n.commonObj.updateErrorMsg(e.$validationSummary[r].message,{valid:!1,elm:t,submitted:!0}));return a}function i(e){var o=this;if(e instanceof Array)for(var t=0,n=e.length;n>t;t++)c(o,e[t]);else c(o,e)}function a(e){var o=this;return o.validationAttrs=e,o}function r(o,t){return o.commonObj.validate(t,!1),o.commonObj.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((o.commonObj.isFieldRequired()||t)&&o.commonObj.ctrl.$setValidity("validation",!1),"SELECT"===o.commonObj.elm.prop("tagName").toUpperCase()?(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)),t):("undefined"!=typeof t&&(o.commonObj.updateErrorMsg(""),e.cancel(o.timer),o.timer=e(function(){o.commonObj.scope.$evalAsync(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)))},o.commonObj.typingLimit)),t)):(l(o),t)}function l(o){e.cancel(self.timer),o.commonObj.updateErrorMsg(""),o.commonObj.ctrl.$setValidity("validation",!0),o.commonObj.elm.unbind("blur")}function m(e,o){var t={};for(var n in e)t[n]=e[n];for(var n in o)t[n]=o[n];return t}function c(e,o){if("undefined"!=typeof e.commonObj.scope){var t=e.commonObj.scope.$watch(o,function(){});t();var n=angular.element(document.querySelector('[name="'+o+'"]'));n.unbind("blur")}}var d=function(){this.validationAttrs={},this.commonObj=new o};return d.prototype.addValidator=t,d.prototype.checkFormValidity=n,d.prototype.removeValidator=i,d.prototype.setGlobalOptions=a,d}]); \ No newline at end of file diff --git a/readme.md b/readme.md index cff20c9..1485167 100644 --- a/readme.md +++ b/readme.md @@ -24,12 +24,12 @@ Huge rewrite to have a better code separation and also adding support to Service ## Index * [Plunker Demo](#plunker) * [Dependency](#dependencies) -* [Install](#install) +* [Install (bower)](#install) * [Include it in your app project](#project) * [Requirements](#requirements) * [Some Working Examples (Directive)](#examples-directive) * [Some Working Examples (Service)](#examples-service) -* [Form Submit](#submit) +* [Form Submit and Validation](#submit) * [Validation summary](#validation-summary) * [Bootstrap Input Groups Wrapping - HOWTO](#input-groups-wrapping) * [Regular Expressions (Regex)](#regex) From 7fb51b513033f0d76a815c8cd9953bf2ac7a3e62 Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 21:13:41 -0400 Subject: [PATCH 6/9] Changed Bower name --- readme.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1485167..e55bef1 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,11 @@ Install ----- Install with Bower -``` +```javascript +// You can install with +bower install angular-validation-ghiscoding + +// or as another name bower install ghiscoding.angular-validation ``` From e807584f0bcdf0f28ef2ef905b6bc4e890926ac1 Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 22:19:57 -0400 Subject: [PATCH 7/9] Recompiled minified version - Recompiled minified script after pull request #15 --- dist/angular-validation.min.js | 6 +++--- src/validation-common.js | 30 +++++++++++++++--------------- src/validation-service.js | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index 1283edf..8d53464 100644 --- a/dist/angular-validation.min.js +++ b/dist/angular-validation.min.js @@ -4,9 +4,9 @@ * @author: Ghislain B. * @version: 1.3.10 * @license: MIT - * @build: Mon Mar 30 2015 20:29:03 GMT-0400 (Eastern Daylight Time) + * @build: Mon Mar 30 2015 22:17:52 GMT-0400 (Eastern Daylight Time) */ angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$timeout","validationCommon","validationRules",function(i,t){return{restrict:"A",require:"ngModel",link:function(a,e,n,l){function d(){i.cancel(r),u.updateErrorMsg(""),l.$setValidity("validation",!0),e.unbind("blur")}function o(t){return u.validate(t,!1),u.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((u.isFieldRequired()||t)&&l.$setValidity("validation",!1),e.bind("blur",function(){return a.$evalAsync(l.$setValidity("validation",u.validate(t,!0))),t}),"SELECT"===e.prop("tagName").toUpperCase()?(l.$setValidity("validation",u.validate(t,!0)),t):("undefined"!=typeof t&&(u.updateErrorMsg(""),i.cancel(r),r=i(function(){a.$evalAsync(l.$setValidity("validation",u.validate(t,!0)))},u.typingLimit)),t)):(d(),t)}var r,u=new t(a,e,n,l);l.$parsers.unshift(o),l.$formatters.unshift(o),n.$observe("disabled",function(i){i?l.$setValidity("validation",!0):l.$setValidity("validation",u.validate(l.$viewValue,!0))})}}}]); -angular.module("ghiscoding.validation").factory("validationCommon",["$timeout","$translate","validationRules",function(t,a,e){function r(){var t=this,a={};t.validators=[],t.typingLimit=m,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")&&(t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10));var r=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(r.indexOf("regex:")>=0){var i=r.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 s=i[1].split(":=");a={message:s[0],pattern:s[1]},r=r.replace(i[0],"regex:")}var n=r.split("|");if(n){t.bFieldRequired=n.indexOf("required")>=0?!0:!1;for(var l=0,o=n.length;o>l;l++){var d=n[l].split(":");t.validators[l]=e.getElementValidators(d[0],d[1],a)}}return t}function i(t,a,e,r){this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,this.defineValidation()}function s(){var t=this;return t.bFieldRequired}function n(t,e){var r=this,i=e&&e.elm?e.elm:r.elm,s=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof s||null===s)throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+i.attr("ng-model")+'"';var n=e&&e.translate?a.instant(t):t,l=s.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),o=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),v="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;o=angular.element(document.querySelector(v))}else o=angular.element(document.querySelector(".validation-"+l));var u=e&&e.submitted?e.submitted:!1;e&&!e.valid&&(u||r.ctrl.$dirty||r.ctrl.$touched)?o.length>0?o.text(n):i.after(''+n+""):o.text("")}function l(t,e){for(var r,i=this,s=!0,n=!0,l="",o=0,d=i.validators.length;d>o;o++){if("conditionalDate"===i.validators[o].type){if(r=new RegExp(i.validators[o].pattern,"i"),n="\\S+"!==i.validators[o].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1){var u=i.validators[o].dateType,c=p(t,u).getTime();if(2==i.validators[o].params.length){var m=p(i.validators[o].params[0],u).getTime(),f=p(i.validators[o].params[1],u).getTime(),h=g(i.validators[o].condition[0],c,m),b=g(i.validators[o].condition[1],c,f);n=h&&b?!0:!1}else{var y=p(i.validators[o].params[0],u).getTime();n=g(i.validators[o].condition,c,y)}}}else if("conditionalNumber"===i.validators[o].type)if(2==i.validators[o].params.length){var h=g(i.validators[o].condition[0],parseFloat(t),parseFloat(i.validators[o].params[0])),b=g(i.validators[o].condition[1],parseFloat(t),parseFloat(i.validators[o].params[1]));n=h&&b?!0:!1}else n=g(i.validators[o].condition,parseFloat(t),parseFloat(i.validators[o].params[0]));else if("match"===i.validators[o].type){var A=i.validators[o].params[0],O=i.scope.$eval(A);n=O===t}else i.elm.prop("disabled")?n=!0:"string"==typeof t&&""===t&&"NUMBER"===i.elm.prop("type").toUpperCase()?(l=a.instant("INVALID_KEY_CHAR"),n=!1):(r=new RegExp(i.validators[o].pattern,"i"),n="\\S+"!==i.validators[o].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1);if(!n&&(s=!1,l+=a.instant(i.validators[o].message),"undefined"!=typeof i.validators[o].params))for(var R=0,S=i.validators[o].params.length;S>R;R++)"match"===i.validators[o].type&&S>1&&0===R||(l=l.replace(":param",i.validators[o].params[R]))}return v(i,a.instant(l)),e&&i.updateErrorMsg(l,{valid:s}),s}function o(t){for(var a=document.querySelectorAll("form"),e=0;ea;a++)if(t.elements[a].getAttribute("validation"))return!0;return!1}function v(t,a){var e=t.elm.attr("name"),r=u(f,"field",e);if(r>=0&&""===a)f.splice(r,1);else if(""!==a){var i={field:e,message:a};r>=0?f[r]=i:f.push(i)}t.scope.$validationSummary=f;var s=o(t);s&&(s.$validationSummary=f)}function u(t,a,e){for(var r=0;r8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":e=t.substring(0,8),r=t.substring(2,3),i=c(e,r),o=i[0],l=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":e=t.substring(0,10),r=t.substring(2,3),i=c(e,r),l=i[0],o=i[1],n=i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":e=t.substring(0,8),r=t.substring(2,3),i=c(e,r),l=i[0],o=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:e=t.substring(0,10),r=t.substring(4,5),i=c(e,r),n=i[0],l=i[1],o=i[2],s=t.length>10?t.substring(11).split(":"):null}var d=s&&3===s.length?s[0]:0,v=s&&3===s.length?s[1]:0,u=s&&3===s.length?s[2]:0;return new Date(n,l-1,o,d,v,u)}function c(t,a){var e=[];switch(a){case"/":e=t.split("/");break;case".":e=t.split(".");break;case"-":default:e=t.split("-")}return e}function g(t,a,e){var r=!1;switch(t){case"<":r=e>a?!0:!1;break;case"<=":r=e>=a?!0:!1;break;case">":r=a>e?!0:!1;break;case">=":r=a>=e?!0:!1;break;case"!=":case"<>":r=a!=e?!0:!1;break;case"=":case"==":r=a==e?!0:!1;break;default:r=!1}return r}var m=1e3,f=[],h=function(t,a,e,r){this.timer=null,this.bFieldRequired=!1,this.validators=[],this.typingLimit=m,this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,t&&a&&e&&r&&this.defineValidation()};return h.prototype.defineValidation=r,h.prototype.isFieldRequired=s,h.prototype.initialize=i,h.prototype.updateErrorMsg=n,h.prototype.validate=l,h}]); +angular.module("ghiscoding.validation").factory("validationCommon",["$timeout","$translate","validationRules",function(t,a,e){function r(){var t=this,a={};t.validators=[],t.typingLimit=g,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")&&(t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10));var r=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(r.indexOf("regex:")>=0){var i=r.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 s=i[1].split(":=");a={message:s[0],pattern:s[1]},r=r.replace(i[0],"regex:")}var n=r.split("|");if(n){t.bFieldRequired=n.indexOf("required")>=0?!0:!1;for(var l=0,o=n.length;o>l;l++){var d=n[l].split(":");t.validators[l]=e.getElementValidators(d[0],d[1],a)}}return t}function i(t,a,e,r){this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,this.defineValidation()}function s(){var t=this;return t.bFieldRequired}function n(t,e){var r=this,i=e&&e.elm?e.elm:r.elm,s=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof s||null===s)throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+i.attr("ng-model")+'"';var n=e&&e.translate?a.instant(t):t,l=s.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),o=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),v="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;o=angular.element(document.querySelector(v))}else o=angular.element(document.querySelector(".validation-"+l));var p=e&&e.submitted?e.submitted:!1;e&&!e.valid&&(p||r.ctrl.$dirty||r.ctrl.$touched)?o.length>0?o.text(n):i.after(''+n+""):o.text("")}function l(t,e){for(var r,i=this,s=!0,n=!0,l="",d=0,v=i.validators.length;v>d;d++){if("conditionalDate"===i.validators[d].type){if(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1){var u=i.validators[d].dateType,g=p(t,u).getTime();if(2==i.validators[d].params.length){var m=p(i.validators[d].params[0],u).getTime(),f=p(i.validators[d].params[1],u).getTime(),h=c(i.validators[d].condition[0],g,m),b=c(i.validators[d].condition[1],g,f);n=h&&b?!0:!1}else{var y=p(i.validators[d].params[0],u).getTime();n=c(i.validators[d].condition,g,y)}}}else if("conditionalNumber"===i.validators[d].type)if(2==i.validators[d].params.length){var h=c(i.validators[d].condition[0],parseFloat(t),parseFloat(i.validators[d].params[0])),b=c(i.validators[d].condition[1],parseFloat(t),parseFloat(i.validators[d].params[1]));n=h&&b?!0:!1}else n=c(i.validators[d].condition,parseFloat(t),parseFloat(i.validators[d].params[0]));else if("match"===i.validators[d].type){var O=i.validators[d].params[0],A=i.scope.$eval(O);n=A===t}else i.elm.prop("disabled")?n=!0:"string"==typeof t&&""===t&&"NUMBER"===i.elm.prop("type").toUpperCase()?(l=a.instant("INVALID_KEY_CHAR"),n=!1):(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1);if(!n&&(s=!1,l+=a.instant(i.validators[d].message),"undefined"!=typeof i.validators[d].params))for(var R=0,S=i.validators[d].params.length;S>R;R++)"match"===i.validators[d].type&&S>1&&0===R||(l=l.replace(":param",i.validators[d].params[R]))}return o(i,a.instant(l)),e&&i.updateErrorMsg(l,{valid:s}),s}function o(t,a){var e=t.elm.attr("name"),r=v(m,"field",e);if(r>=0&&""===a)m.splice(r,1);else if(""!==a){var i={field:e,message:a};r>=0?m[r]=i:m.push(i)}t.scope.$validationSummary=m;var s=d(t);s&&(s.$validationSummary=m)}function d(t){for(var a=document.querySelectorAll("form"),e=0;e8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":e=t.substring(0,8),r=t.substring(2,3),i=u(e,r),o=i[0],l=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":e=t.substring(0,10),r=t.substring(2,3),i=u(e,r),l=i[0],o=i[1],n=i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":e=t.substring(0,8),r=t.substring(2,3),i=u(e,r),l=i[0],o=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:e=t.substring(0,10),r=t.substring(4,5),i=u(e,r),n=i[0],l=i[1],o=i[2],s=t.length>10?t.substring(11).split(":"):null}var d=s&&3===s.length?s[0]:0,v=s&&3===s.length?s[1]:0,p=s&&3===s.length?s[2]:0;return new Date(n,l-1,o,d,v,p)}function u(t,a){var e=[];switch(a){case"/":e=t.split("/");break;case".":e=t.split(".");break;case"-":default:e=t.split("-")}return e}function c(t,a,e){var r=!1;switch(t){case"<":r=e>a?!0:!1;break;case"<=":r=e>=a?!0:!1;break;case">":r=a>e?!0:!1;break;case">=":r=a>=e?!0:!1;break;case"!=":case"<>":r=a!=e?!0:!1;break;case"=":case"==":r=a==e?!0:!1;break;default:r=!1}return r}var g=1e3,m=[],f=function(t,a,e,r){this.timer=null,this.bFieldRequired=!1,this.validators=[],this.typingLimit=g,this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,t&&a&&e&&r&&this.defineValidation()};return f.prototype.defineValidation=r,f.prototype.isFieldRequired=s,f.prototype.initialize=i,f.prototype.updateErrorMsg=n,f.prototype.validate=l,f}]); angular.module("ghiscoding.validation").factory("validationRules",[function(){function e(e,a,t){var s={};switch(e){case"alpha":s={pattern:"^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$",message:"INVALID_ALPHA",type:"regex"};break;case"alphaSpaces":case"alpha_spaces":s={pattern:"^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s])+$",message:"INVALID_ALPHA_SPACE",type:"regex"};break;case"alphaNum":case"alpha_num":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$",message:"INVALID_ALPHA_NUM",type:"regex"};break;case"alphaNumSpaces":case"alpha_num_spaces":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s])+$",message:"INVALID_ALPHA_NUM_SPACE",type:"regex"};break;case"alphaDash":case"alpha_dash":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ_-])+$",message:"INVALID_ALPHA_DASH",type:"regex"};break;case"alphaDashSpaces":case"alpha_dash_spaces":s={pattern:"^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\\s_-])+$",message:"INVALID_ALPHA_DASH_SPACE",type:"regex"};break;case"betweenLen":case"between_len":var n=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_len:1,5";s={pattern:"^.{"+n[0]+","+n[1]+"}$",message:"INVALID_BETWEEN_CHAR",params:[n[0],n[1]],type:"regex"};break;case"betweenNum":case"between_num":var n=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_num:1,5";s={condition:[">=","<="],message:"INVALID_BETWEEN_NUM",params:[n[0],n[1]],type:"conditionalNumber"};break;case"creditCard":case"credit_card":s={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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_long:01-01-1990,31-12-2015";s={condition:[">=","<="],dateType:"EURO_LONG",params:[n[0],n[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":s={condition:"<=",dateType:"EURO_LONG",params:[a],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":s={condition:">=",dateType:"EURO_LONG",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_short:01-01-90,31-12-15";s={condition:[">=","<="],dateType:"EURO_SHORT",params:[n[0],n[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":s={condition:"<=",dateType:"EURO_SHORT",params:[a],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":s={condition:">=",dateType:"EURO_SHORT",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_iso:1990-01-01,2000-12-31";s={condition:[">=","<="],dateType:"ISO",params:[n[0],n[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":s={condition:"<=",dateType:"ISO",params:[a],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":s={condition:">=",dateType:"ISO",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_long:01/01/1990,12/31/2015";s={condition:[">=","<="],dateType:"US_LONG",params:[n[0],n[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":s={condition:"<=",dateType:"US_LONG",params:[a],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":s={condition:">=",dateType:"US_LONG",params:[a],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":s={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=a.split(",");if(2!==n.length)throw"This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_short:01/01/90,12/31/15";s={condition:[">=","<="],dateType:"US_SHORT",params:[n[0],n[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":s={condition:"<=",dateType:"US_SHORT",params:[a],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":s={condition:">=",dateType:"US_SHORT",params:[a],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":s={pattern:"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",message:"INVALID_EMAIL",type:"regex"};break;case"exactLen":case"exact_len":s={pattern:"^.{"+a+"}$",message:"INVALID_EXACT_LEN",params:[a],type:"regex"};break;case"float":s={pattern:"^\\d*\\.{1}\\d+$",message:"INVALID_FLOAT",type:"regex"};break;case"floatSigned":case"float_signed":s={pattern:"^[-+]?\\d*\\.{1}\\d+$",message:"INVALID_FLOAT_SIGNED",type:"regex"};break;case"iban":s={pattern:"[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}",message:"INVALID_IBAN",type:"regex"};break;case"int":case"integer":s={pattern:"^\\d+$",message:"INVALID_INTEGER",type:"regex"};break;case"intSigned":case"integerSigned":case"int_signed":case"integer_signed":s={pattern:"^[+-]?\\d+$",message:"INVALID_INTEGER_SIGNED",type:"regex"};break;case"ipv4":s={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":s={pattern:"^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",message:"INVALID_IPV6",type:"regex"};break;case"ipv6_hex":s={pattern:"^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$",message:"INVALID_IPV6_HEX",type:"regex"};break;case"match":var _=a.split(",");s={message:"INVALID_INPUT_MATCH",params:_,type:"match"};break;case"maxLen":case"max_len":s={pattern:"^.{0,"+a+"}$",message:"INVALID_MAX_CHAR",params:[a],type:"regex"};break;case"maxNum":case"max_num":s={condition:"<=",message:"INVALID_MAX_NUM",params:[a],type:"conditionalNumber"};break;case"minLen":case"min_len":s={pattern:"^.{"+a+",}$",message:"INVALID_MIN_CHAR",params:[a],type:"regex"};break;case"minNum":case"min_num":s={condition:">=",message:"INVALID_MIN_NUM",params:[a],type:"conditionalNumber"};break;case"numeric":s={pattern:"^\\d*\\.?\\d+$",message:"INVALID_NUMERIC",type:"regex"};break;case"numericSigned":case"numeric_signed":s={pattern:"^[-+]?\\d*\\.?\\d+$",message:"INVALID_NUMERIC_SIGNED",type:"regex"};break;case"regex":s={pattern:t.pattern,message:"INVALID_PATTERN",params:[t.message],type:"regex"};break;case"required":s={pattern:"\\S+",message:"INVALID_REQUIRED",type:"regex"};break;case"url":s={pattern:"(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?",message:"INVALID_URL",type:"regex"};break;case"time":s={pattern:"^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$",message:"INVALID_TIME",type:"regex"}}return s}var a={getElementValidators:e};return a}]); -angular.module("ghiscoding.validation").service("validationService",["$timeout","validationCommon",function(e,o){function t(e,o){var t=this,n={};if("string"==typeof e&&"string"==typeof o?(n.elmName=e,n.rules=o):n=e,"object"!=typeof n||!n.hasOwnProperty("elmName")||!n.hasOwnProperty("rules")||!n.hasOwnProperty("scope")&&"undefined"==typeof t.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";return n.elm=angular.element(document.querySelector('[name="'+n.elmName+'"]:not([disabled]):not([ng-disabled]')),"object"!=typeof n.elm||0===n.elm.length?t:(n.elm.bind("blur",function(e){t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),t.commonObj.typingLimit=0,r(t,e.target.value)}),n=m(t.validationAttrs,n),n.scope.$watch(n.elmName,function(e,o){return void 0===e&&void 0!==o?void t.commonObj.updateErrorMsg("INVALID_KEY_CHAR",{valid:!1,translate:!0}):(n.ctrl=angular.element(n.elm).controller("ngModel"),n.value=e,t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),void r(t,e))},!0),t)}function n(e){var o,t,n=this,i="",a=!0;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"Form validaty checking requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).";for(var r=0,l=e.$validationSummary.length;l>r;r++)a=!1,i=e.$validationSummary[r].field,t=angular.element(document.querySelector('[name="'+i+'"]:not([disabled]):not([ng-disabled]')),o=angular.element(t).controller("ngModel"),t&&t.length>0&&(o.$setTouched(),n.commonObj.updateErrorMsg(e.$validationSummary[r].message,{valid:!1,elm:t,submitted:!0}));return a}function i(e){var o=this;if(e instanceof Array)for(var t=0,n=e.length;n>t;t++)c(o,e[t]);else c(o,e)}function a(e){var o=this;return o.validationAttrs=e,o}function r(o,t){return o.commonObj.validate(t,!1),o.commonObj.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((o.commonObj.isFieldRequired()||t)&&o.commonObj.ctrl.$setValidity("validation",!1),"SELECT"===o.commonObj.elm.prop("tagName").toUpperCase()?(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)),t):("undefined"!=typeof t&&(o.commonObj.updateErrorMsg(""),e.cancel(o.timer),o.timer=e(function(){o.commonObj.scope.$evalAsync(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)))},o.commonObj.typingLimit)),t)):(l(o),t)}function l(o){e.cancel(self.timer),o.commonObj.updateErrorMsg(""),o.commonObj.ctrl.$setValidity("validation",!0),o.commonObj.elm.unbind("blur")}function m(e,o){var t={};for(var n in e)t[n]=e[n];for(var n in o)t[n]=o[n];return t}function c(e,o){if("undefined"!=typeof e.commonObj.scope){var t=e.commonObj.scope.$watch(o,function(){});t();var n=angular.element(document.querySelector('[name="'+o+'"]'));n.unbind("blur")}}var d=function(){this.validationAttrs={},this.commonObj=new o};return d.prototype.addValidator=t,d.prototype.checkFormValidity=n,d.prototype.removeValidator=i,d.prototype.setGlobalOptions=a,d}]); \ No newline at end of file +angular.module("ghiscoding.validation").service("validationService",["$timeout","validationCommon",function(e,o){function t(e,o){var t=this,n={};if("string"==typeof e&&"string"==typeof o?(n.elmName=e,n.rules=o):n=e,"object"!=typeof n||!n.hasOwnProperty("elmName")||!n.hasOwnProperty("rules")||!n.hasOwnProperty("scope")&&"undefined"==typeof t.validationAttrs.scope)throw"Angular-Validation-Service requires at least the following 3 attributes: {elmName, rules, scope}";return n.elm=angular.element(document.querySelector('[name="'+n.elmName+'"]:not([disabled]):not([ng-disabled]')),"object"!=typeof n.elm||0===n.elm.length?t:(n.elm.bind("blur",function(e){t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),t.commonObj.typingLimit=0,r(t,e.target.value)}),n=m(t.validationAttrs,n),n.scope.$watch(n.elmName,function(e,o){return void 0===e&&void 0!==o?void t.commonObj.updateErrorMsg("INVALID_KEY_CHAR",{valid:!1,translate:!0}):(n.ctrl=angular.element(n.elm).controller("ngModel"),n.value=e,t.commonObj.initialize(n.scope,n.elm,n,n.ctrl),void r(t,e))},!0),t)}function n(e){var o,t,n=this,i="",a=!0;if("undefined"==typeof e||"undefined"==typeof e.$validationSummary)throw"checkFormValidity() requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).";for(var r=0,l=e.$validationSummary.length;l>r;r++)a=!1,i=e.$validationSummary[r].field,t=angular.element(document.querySelector('[name="'+i+'"]:not([disabled]):not([ng-disabled]')),o=angular.element(t).controller("ngModel"),t&&t.length>0&&(o.$setTouched(),n.commonObj.updateErrorMsg(e.$validationSummary[r].message,{valid:!1,elm:t,submitted:!0}));return a}function i(e){var o=this;if(e instanceof Array)for(var t=0,n=e.length;n>t;t++)c(o,e[t]);else c(o,e)}function a(e){var o=this;return o.validationAttrs=e,o}function r(o,t){return o.commonObj.validate(t,!1),o.commonObj.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((o.commonObj.isFieldRequired()||t)&&o.commonObj.ctrl.$setValidity("validation",!1),"SELECT"===o.commonObj.elm.prop("tagName").toUpperCase()?(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)),t):("undefined"!=typeof t&&(o.commonObj.updateErrorMsg(""),e.cancel(o.timer),o.timer=e(function(){o.commonObj.scope.$evalAsync(o.commonObj.ctrl.$setValidity("validation",o.commonObj.validate(t,!0)))},o.commonObj.typingLimit)),t)):(l(o),t)}function l(o){e.cancel(self.timer),o.commonObj.updateErrorMsg(""),o.commonObj.ctrl.$setValidity("validation",!0),o.commonObj.elm.unbind("blur")}function m(e,o){var t={};for(var n in e)t[n]=e[n];for(var n in o)t[n]=o[n];return t}function c(e,o){if("undefined"!=typeof e.commonObj.scope){var t=e.commonObj.scope.$watch(o,function(){});t();var n=angular.element(document.querySelector('[name="'+o+'"]'));n.unbind("blur")}}var d=function(){this.validationAttrs={},this.commonObj=new o};return d.prototype.addValidator=t,d.prototype.checkFormValidity=n,d.prototype.removeValidator=i,d.prototype.setGlobalOptions=a,d}]); \ No newline at end of file diff --git a/src/validation-common.js b/src/validation-common.js index 74422cb..8877b3d 100644 --- a/src/validation-common.js +++ b/src/validation-common.js @@ -283,21 +283,7 @@ angular //---- // Private functions declaration //---------------------------------- - - /** Get form within scope (if found) - * @param self - */ - function getScopeForm(self) { - var forms = document.querySelectorAll('form'); - for (var i = 0; i < forms.length; i++) { - var form = document.querySelectorAll('form')[i]; - if (form && form.name && self.scope[form.name]) { - return self.scope[form.name]; - } - } - return null; - } - + /** Add the error to the validation summary * @param self * @param string elmName: element name (name attribute) @@ -329,6 +315,20 @@ angular } } + /** Get form within scope (if found) + * @param self + */ + function getScopeForm(self) { + var forms = document.querySelectorAll('form'); + for (var i = 0; i < forms.length; i++) { + var form = document.querySelectorAll('form')[i]; + if (form && form.name && self.scope[form.name]) { + return self.scope[form.name]; + } + } + return null; + } + /** Quick function to find an object inside an array by it's given field name and value, return the index found or -1 * @param Array sourceArray * @param string searchId: search property id diff --git a/src/validation-service.js b/src/validation-service.js index f2df333..4b1511a 100644 --- a/src/validation-service.js +++ b/src/validation-service.js @@ -97,7 +97,7 @@ angular var self = this; var ctrl, elm, elmName = '', isValid = true; if(typeof obj === "undefined" || typeof obj.$validationSummary === "undefined") { - throw 'Form validaty checking requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).'; + throw 'checkFormValidity() requires a valid Angular Form or $scope object passed as argument to function properly (ex.: $scope.form1 OR $scope).'; } // loop through $validationSummary and display errors when found on each field From fd7fe57e0555b2294c2202c9fb5135f44c0fb58d Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 22:24:51 -0400 Subject: [PATCH 8/9] Updated version after pull requests --- bower.json | 2 +- changelog.txt | 3 ++- dist/angular-validation.min.js | 4 ++-- package.json | 2 +- readme.md | 5 +++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index 571a849..581ebd2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ghiscoding.angular-validation", - "version": "1.3.10", + "version": "1.3.11", "authors": [ "Ghislain B." ], diff --git a/changelog.txt b/changelog.txt index ffa3fa9..af185d2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -11,4 +11,5 @@ Angular-Validation change logs 1.3.7 (2015-03-08): Complete rewrite (but same functionality) so that I could add an Angular-Validation Service which is similar implementation as the Directive. Also added `debounce` attribute which is an alias to `typingLimit`, validation rules are now defined as an external service for better maintainability and also created a common file for shared functions by both Validation Directive and Service. 1.3.8 (2015-03-15): Added between/min/max conditional validators on all Date types (ISO, EURO_LONG, EURO_SHORT, US_LONG, US_SHORT) 1.3.9 (2015-03-21): Added validation summary through 2 new and equivalent properties `$scope.$validationSummary` and `$scope.formName.$validationSummary`. Also added `bower` and `gulp` support, the Gulp script gives minified files. -1.3.10 (2015-03-28); Added new function of `checkFormValidity()` before submitting the form. Now use only 1 minified script instead of multiples. \ No newline at end of file +1.3.10 (2015-03-28): Added new function of `checkFormValidity()` before submitting the form. Now use only 1 minified script instead of multiples. +1.3.11 (2015-03-30): Accepted pull request #15 to fix form without name attribute. Also accepted pull request #18 to add Spanish locales. \ No newline at end of file diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index 8d53464..7d1af78 100644 --- a/dist/angular-validation.min.js +++ b/dist/angular-validation.min.js @@ -2,9 +2,9 @@ * Angular-Validation Directive and Service (ghiscoding) * http://github.com/ghiscoding/angular-validation * @author: Ghislain B. - * @version: 1.3.10 + * @version: 1.3.11 * @license: MIT - * @build: Mon Mar 30 2015 22:17:52 GMT-0400 (Eastern Daylight Time) + * @build: Mon Mar 30 2015 22:23:43 GMT-0400 (Eastern Daylight Time) */ angular.module("ghiscoding.validation",["pascalprecht.translate"]).directive("validation",["$timeout","validationCommon","validationRules",function(i,t){return{restrict:"A",require:"ngModel",link:function(a,e,n,l){function d(){i.cancel(r),u.updateErrorMsg(""),l.$setValidity("validation",!0),e.unbind("blur")}function o(t){return u.validate(t,!1),u.isFieldRequired()||""!==t&&null!==t&&"undefined"!=typeof t?((u.isFieldRequired()||t)&&l.$setValidity("validation",!1),e.bind("blur",function(){return a.$evalAsync(l.$setValidity("validation",u.validate(t,!0))),t}),"SELECT"===e.prop("tagName").toUpperCase()?(l.$setValidity("validation",u.validate(t,!0)),t):("undefined"!=typeof t&&(u.updateErrorMsg(""),i.cancel(r),r=i(function(){a.$evalAsync(l.$setValidity("validation",u.validate(t,!0)))},u.typingLimit)),t)):(d(),t)}var r,u=new t(a,e,n,l);l.$parsers.unshift(o),l.$formatters.unshift(o),n.$observe("disabled",function(i){i?l.$setValidity("validation",!0):l.$setValidity("validation",u.validate(l.$viewValue,!0))})}}}]); angular.module("ghiscoding.validation").factory("validationCommon",["$timeout","$translate","validationRules",function(t,a,e){function r(){var t=this,a={};t.validators=[],t.typingLimit=g,t.validatorAttrs.hasOwnProperty("debounce")?t.typingLimit=parseInt(t.validatorAttrs.debounce,10):t.validatorAttrs.hasOwnProperty("typingLimit")&&(t.typingLimit=parseInt(t.validatorAttrs.typingLimit,10));var r=t.validatorAttrs.hasOwnProperty("rules")?t.validatorAttrs.rules:t.validatorAttrs.validation;if(r.indexOf("regex:")>=0){var i=r.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 s=i[1].split(":=");a={message:s[0],pattern:s[1]},r=r.replace(i[0],"regex:")}var n=r.split("|");if(n){t.bFieldRequired=n.indexOf("required")>=0?!0:!1;for(var l=0,o=n.length;o>l;l++){var d=n[l].split(":");t.validators[l]=e.getElementValidators(d[0],d[1],a)}}return t}function i(t,a,e,r){this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,this.defineValidation()}function s(){var t=this;return t.bFieldRequired}function n(t,e){var r=this,i=e&&e.elm?e.elm:r.elm,s=i&&i.attr("name")?i.attr("name"):null;if("undefined"==typeof s||null===s)throw'Angular-Validation Service requires you to have a (name="") attribute on the element to validate... Your element is: ng-model="'+i.attr("ng-model")+'"';var n=e&&e.translate?a.instant(t):t,l=s.replace(/[|&;$%@"<>()+,\[\]\{\}]/g,""),o=null;if(r.validatorAttrs&&r.validatorAttrs.hasOwnProperty("validationErrorTo")){var d=r.validatorAttrs.validationErrorTo.charAt(0),v="."===d||"#"===d?r.validatorAttrs.validationErrorTo:"#"+r.validatorAttrs.validationErrorTo;o=angular.element(document.querySelector(v))}else o=angular.element(document.querySelector(".validation-"+l));var p=e&&e.submitted?e.submitted:!1;e&&!e.valid&&(p||r.ctrl.$dirty||r.ctrl.$touched)?o.length>0?o.text(n):i.after(''+n+""):o.text("")}function l(t,e){for(var r,i=this,s=!0,n=!0,l="",d=0,v=i.validators.length;v>d;d++){if("conditionalDate"===i.validators[d].type){if(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1){var u=i.validators[d].dateType,g=p(t,u).getTime();if(2==i.validators[d].params.length){var m=p(i.validators[d].params[0],u).getTime(),f=p(i.validators[d].params[1],u).getTime(),h=c(i.validators[d].condition[0],g,m),b=c(i.validators[d].condition[1],g,f);n=h&&b?!0:!1}else{var y=p(i.validators[d].params[0],u).getTime();n=c(i.validators[d].condition,g,y)}}}else if("conditionalNumber"===i.validators[d].type)if(2==i.validators[d].params.length){var h=c(i.validators[d].condition[0],parseFloat(t),parseFloat(i.validators[d].params[0])),b=c(i.validators[d].condition[1],parseFloat(t),parseFloat(i.validators[d].params[1]));n=h&&b?!0:!1}else n=c(i.validators[d].condition,parseFloat(t),parseFloat(i.validators[d].params[0]));else if("match"===i.validators[d].type){var O=i.validators[d].params[0],A=i.scope.$eval(O);n=A===t}else i.elm.prop("disabled")?n=!0:"string"==typeof t&&""===t&&"NUMBER"===i.elm.prop("type").toUpperCase()?(l=a.instant("INVALID_KEY_CHAR"),n=!1):(r=new RegExp(i.validators[d].pattern,"i"),n="\\S+"!==i.validators[d].pattern||"undefined"!=typeof t&&null!==t?r.test(t):!1);if(!n&&(s=!1,l+=a.instant(i.validators[d].message),"undefined"!=typeof i.validators[d].params))for(var R=0,S=i.validators[d].params.length;S>R;R++)"match"===i.validators[d].type&&S>1&&0===R||(l=l.replace(":param",i.validators[d].params[R]))}return o(i,a.instant(l)),e&&i.updateErrorMsg(l,{valid:s}),s}function o(t,a){var e=t.elm.attr("name"),r=v(m,"field",e);if(r>=0&&""===a)m.splice(r,1);else if(""!==a){var i={field:e,message:a};r>=0?m[r]=i:m.push(i)}t.scope.$validationSummary=m;var s=d(t);s&&(s.$validationSummary=m)}function d(t){for(var a=document.querySelectorAll("form"),e=0;e8?t.substring(9).split(":"):null;break;case"UK":case"EURO":case"EURO_SHORT":case"EURO-SHORT":case"EUROPE":e=t.substring(0,8),r=t.substring(2,3),i=u(e,r),o=i[0],l=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US_LONG":case"US-LONG":e=t.substring(0,10),r=t.substring(2,3),i=u(e,r),l=i[0],o=i[1],n=i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"US":case"US_SHORT":case"US-SHORT":e=t.substring(0,8),r=t.substring(2,3),i=u(e,r),l=i[0],o=i[1],n=parseInt(i[2])<50?"20"+i[2]:"19"+i[2],s=t.length>8?t.substring(9).split(":"):null;break;case"ISO":default:e=t.substring(0,10),r=t.substring(4,5),i=u(e,r),n=i[0],l=i[1],o=i[2],s=t.length>10?t.substring(11).split(":"):null}var d=s&&3===s.length?s[0]:0,v=s&&3===s.length?s[1]:0,p=s&&3===s.length?s[2]:0;return new Date(n,l-1,o,d,v,p)}function u(t,a){var e=[];switch(a){case"/":e=t.split("/");break;case".":e=t.split(".");break;case"-":default:e=t.split("-")}return e}function c(t,a,e){var r=!1;switch(t){case"<":r=e>a?!0:!1;break;case"<=":r=e>=a?!0:!1;break;case">":r=a>e?!0:!1;break;case">=":r=a>=e?!0:!1;break;case"!=":case"<>":r=a!=e?!0:!1;break;case"=":case"==":r=a==e?!0:!1;break;default:r=!1}return r}var g=1e3,m=[],f=function(t,a,e,r){this.timer=null,this.bFieldRequired=!1,this.validators=[],this.typingLimit=g,this.scope=t,this.elm=a,this.ctrl=r,this.validatorAttrs=e,t&&a&&e&&r&&this.defineValidation()};return f.prototype.defineValidation=r,f.prototype.isFieldRequired=s,f.prototype.initialize=i,f.prototype.updateErrorMsg=n,f.prototype.validate=l,f}]); diff --git a/package.json b/package.json index 111ed51..8a63e08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghiscoding.angular-validation", - "version": "1.3.10", + "version": "1.3.11", "author": "Ghislain B.", "description": "Angular-Validation Directive and Service (ghiscoding)", "main": "app.js", diff --git a/readme.md b/readme.md index e55bef1..c534d8d 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ #Angular Validation (Directive / Service) -`Version: 1.3.10` +`Version: 1.3.11` ### 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! @@ -412,4 +412,5 @@ License * [1.3.7](https://github.com/ghiscoding/angular-validation/commit/86c16f720d6687d3b5ca93e49a0a37824027e583) `2015-03-08` Complete rewrite (but same functionality) so that I could add an Angular-Validation Service which is similar implementation as the Directive. Also added `debounce` attribute which is an alias to `typingLimit`, validation rules are now defined as an external service for better maintainability and also created a common file for shared functions by both Validation Directive and Service. * [1.3.8](https://github.com/ghiscoding/angular-validation/commit/492d1060a91fb8b49fc70a0c7a1a581d904e0db0) `2015-03-15` Added between/min/max conditional validators on all Date types (iso, euro_long, euro_short, us_long, us_short) * [1.3.9](https://github.com/ghiscoding/angular-validation/commit/931d3b04a00f0583612aefe28ad0bfcac326a38c) `2015-03-21` Added validation summary through 2 new and equivalent properties `$scope.$validationSummary` and `$scope.formName.$validationSummary`. Also added `bower` and `gulp` support, the Gulp script gives minified files. -* [1.3.10](https://github.com/ghiscoding/angular-validation/commit/18765a8dd986856a9fa176fc4835d90d25f663b2) `2015-03-29` Added new function of `checkFormValidity()` before submitting the form. Now use only 1 minified script instead of multiples. \ No newline at end of file +* [1.3.10](https://github.com/ghiscoding/angular-validation/commit/18765a8dd986856a9fa176fc4835d90d25f663b2) `2015-03-29` Added new function of `checkFormValidity()` before submitting the form. Now use only 1 minified script instead of multiples. +* [1.3.11](https://github.com/ghiscoding/angular-validation/commit/e807584f0bcdf0f28ef2ef905b6bc4e890926ac1) `2015-03-30` Accepted pull request #15 to fix form without name attribute. Also accepted pull request #18 to add Spanish locales. \ No newline at end of file From 10b6b286461518cf6f5878aef164a5e716b54a73 Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Mon, 30 Mar 2015 23:30:18 -0400 Subject: [PATCH 9/9] typo --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index c534d8d..2a5b3cd 100644 --- a/readme.md +++ b/readme.md @@ -205,6 +205,11 @@ $scope.submitForm = function() { if(myValidation.checkFormValidity($scope.form1)) { // proceed with submit } + + // or without a form name, use the $scope alone + if(myValidation.checkFormValidity($scope)) { + // proceed with submit + } } // Option #3 - You could also use the $validationSummary to be displayed after a Submit