diff --git a/app.js b/app.js index 1297412..f44df92 100644 --- a/app.js +++ b/app.js @@ -73,12 +73,13 @@ myApp.controller('CtrlValidationService', ['$scope', '$translate', 'validationSe .addValidator('input11', 'date_us_long|required') .addValidator('input12', 'time') .addValidator('select1', 'required') - .addValidator('select2', 'required') .addValidator({elmName: 'input13', rules: 'min_len:5|max_len:10|alpha_dash_spaces|required', validationErrorTo: ".validation-input13"}) .addValidator('input14', 'alpha|required') .addValidator('input15', 'alpha|min_len:3|required') .addValidator('input16', 'match:input15,Password|required') .addValidator({elmName: 'input17', rules: 'alpha_spaces|exact_len:3|required', debounce: 5000}) + .addValidator('input18', 'date_iso_min:1999-12-31|required') + .addValidator('input19', 'date_us_short_between:11/28/99,12/31/15|required') .addValidator('area1', 'alpha_dash_spaces|min_len:15|required'); diff --git a/change-log.txt b/change-log.txt deleted file mode 100644 index 1293f22..0000000 --- a/change-log.txt +++ /dev/null @@ -1,11 +0,0 @@ -Angular-Validation change logs - -1.1.0: only start validating after user inactivity, it could also be passed as an argument for more customization of the inactivity timeout (typing-limit). -1.3.0: support to Angular 1.3.x -1.3.1: Added Input Match (confirmation) Validator -1.3.2: Float number validator to also permit dot (.) as first char. Also removed keyboard blocking of invalid character on input type="number" instead display error message. -1.3.3: Updated Bootstrap(3.3.1) and AngularJS(1.3.7) to latest versions -1.3.4: Removed the necessity of creating a for displaying the error message, the directive now handles it by itself. -1.3.5: Throw an error message when user did not provide a name="" property inside the element to validate. -1.3.6: 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: 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. \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..f073e49 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,12 @@ +Angular-Validation change logs + +1.1.0 (2014-05-02): only start validating after user inactivity, it could also be passed as an argument for more customization of the inactivity timeout (typing-limit). +1.3.0 (2014-12-01): support to Angular 1.3.x +1.3.1 (2015-01-02): Added Input Match (confirmation) Validator +1.3.2 (2015-01-03): Float number validator to also permit dot (.) as first char. Also removed keyboard blocking of invalid character on input type="number" instead display error message. +1.3.3 (2015-01-04): Updated Bootstrap(3.3.1) and AngularJS(1.3.7) to latest versions +1.3.4 (2015-01-06): Removed the necessity of creating a for displaying the error message, the directive now handles it by itself. +1.3.5 (2015-01-26): Throw an error message when user did not provide a name="" property inside the element to validate. +1.3.6 (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 (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) \ No newline at end of file diff --git a/locales/validation/en.json b/locales/validation/en.json index 3fb1d09..fb910d7 100644 --- a/locales/validation/en.json +++ b/locales/validation/en.json @@ -1,41 +1,56 @@ { - "INVALID_ALPHA": "May only contain letters. ", - "INVALID_ALPHA_SPACE": "May only contain letters and spaces. ", - "INVALID_ALPHA_NUM": "May only contain letters and numbers. ", - "INVALID_ALPHA_NUM_SPACE": "May only contain letters, numbers and spaces. ", - "INVALID_ALPHA_DASH": "May only contain letters, numbers and dashes. ", - "INVALID_ALPHA_DASH_SPACE": "May only contain letters, numbers, dashes and spaces. ", - "INVALID_BETWEEN_CHAR": "Text must be between :param and :param characters in length. ", - "INVALID_BETWEEN_NUM": "Needs to be a numeric value, between :param and :param. ", - "INVALID_BOOLEAN": "May only contain a true or false value. ", - "INVALID_CREDIT_CARD": "Must be a valid credit card number. ", - "INVALID_DATE_EURO_LONG": "Must be a valid date format (dd-mm-yyyy) OR (dd/mm/yyyy). ", - "INVALID_DATE_EURO_SHORT": "Must be a valid date format (dd-mm-yy) OR (dd/mm/yy). ", - "INVALID_DATE_ISO": "Must be a valid date format (yyyy-mm-dd). ", - "INVALID_DATE_US_LONG": "Must be a valid date format (mm/dd/yyyy) OR (mm-dd-yyyy). ", - "INVALID_DATE_US_SHORT": "Must be a valid date format (mm/dd/yy) OR (mm-dd-yy). ", - "INVALID_EMAIL": "Must be a valid email address. ", - "INVALID_EXACT_LEN": "Must have a length of exactly :param characters. ", - "INVALID_FLOAT": "May only contain a positive float value (integer excluded). ", - "INVALID_FLOAT_SIGNED": "May only contain a positive or negative float value (integer excluded). ", - "INVALID_IBAN": "Must a valid IBAN. ", - "INVALID_INPUT_MATCH": "Confirmation field does not match specified field \":param\". ", - "INVALID_INTEGER": "Must be a positive integer. ", - "INVALID_INTEGER_SIGNED": "Must be a positive or negative integer. ", - "INVALID_IPV4": "Must be a valid IP (IPV4). ", - "INVALID_IPV6": "Must be a valid IP (IPV6). ", - "INVALID_IPV6_HEX": "Must be a valid IP (IPV6 Hex). ", - "INVALID_KEY_CHAR": "Invalid keyboard entry on a field of type \"number\". ", - "INVALID_MAX_CHAR": "May not be greater than :param characters. ", - "INVALID_MAX_NUM": "Needs to be a numeric value, equal to, or lower than :param. ", - "INVALID_MIN_CHAR": "Must be at least :param characters. ", - "INVALID_MIN_NUM": "Needs to be a numeric value, equal to, or higher than :param. ", - "INVALID_NUMERIC": "Must be a positive number. ", - "INVALID_NUMERIC_SIGNED": "Must be a positive or negative number. ", - "INVALID_PATTERN": "Must be following this format: :param. ", - "INVALID_REQUIRED": "Field is required. ", - "INVALID_URL": "Must be a valid URL. ", - "INVALID_TIME": "Must be a valid time format (hh:mm) OR (hh:mm:ss). ", + "INVALID_ALPHA": "May only contain letters. ", + "INVALID_ALPHA_SPACE": "May only contain letters and spaces. ", + "INVALID_ALPHA_NUM": "May only contain letters and numbers. ", + "INVALID_ALPHA_NUM_SPACE": "May only contain letters, numbers and spaces. ", + "INVALID_ALPHA_DASH": "May only contain letters, numbers and dashes. ", + "INVALID_ALPHA_DASH_SPACE": "May only contain letters, numbers, dashes and spaces. ", + "INVALID_BETWEEN_CHAR": "Text must be between :param and :param characters in length. ", + "INVALID_BETWEEN_NUM": "Needs to be a numeric value, between :param and :param. ", + "INVALID_BOOLEAN": "May only contain a true or false value. ", + "INVALID_CREDIT_CARD": "Must be a valid credit card number. ", + "INVALID_DATE_EURO_LONG": "Must be a valid date format (dd-mm-yyyy) OR (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_BETWEEN": "Needs to be a valid date format (dd-mm-yyyy) OR (dd/mm/yyyy) between :param and :param. ", + "INVALID_DATE_EURO_LONG_MAX": "Needs to be a valid date format (dd-mm-yyyy) OR (dd/mm/yyyy), equal to, or lower than :param. ", + "INVALID_DATE_EURO_LONG_MIN": "Needs to be a valid date format (dd-mm-yyyy) OR (dd/mm/yyyy), equal to, or higher than :param. ", + "INVALID_DATE_EURO_SHORT": "Must be a valid date format (dd-mm-yy) OR (dd/mm/yy). ", + "INVALID_DATE_EURO_SHORT_BETWEEN": "Needs to be a valid date format (dd-mm-yy) OR (dd/mm/yy) between :param and :param. ", + "INVALID_DATE_EURO_SHORT_MAX": "Needs to be a valid date format (dd-mm-yy) OR (dd/mm/yy), equal to, or lower than :param. ", + "INVALID_DATE_EURO_SHORT_MIN": "Needs to be a valid date format (dd-mm-yy) OR (dd/mm/yy), equal to, or higher than :param. ", + "INVALID_DATE_ISO": "Must be a valid date format (yyyy-mm-dd). ", + "INVALID_DATE_ISO_BETWEEN": "Needs to be a valid date format (yyyy-mm-dd) between :param and :param. ", + "INVALID_DATE_ISO_MAX": "Needs to be a valid date format (yyyy-mm-dd), equal to, or lower than :param. ", + "INVALID_DATE_ISO_MIN": "Needs to be a valid date format (yyyy-mm-dd), equal to, or higher than :param. ", + "INVALID_DATE_US_LONG": "Must be a valid date format (mm/dd/yyyy) OR (mm-dd-yyyy). ", + "INVALID_DATE_US_LONG_BETWEEN": "Needs to be a valid date format (mm/dd/yyyy) OR (mm-dd-yyyy) between :param and :param. ", + "INVALID_DATE_US_LONG_MAX": "Needs to be a valid date format (mm/dd/yyyy) OR (mm-dd-yyyy), equal to, or lower than :param. ", + "INVALID_DATE_US_LONG_MIN": "Needs to be a valid date format (mm/dd/yyyy) OR (mm-dd-yyyy), equal to, or higher than :param. ", + "INVALID_DATE_US_SHORT": "Must be a valid date format (mm/dd/yy) OR (mm-dd-yy). ", + "INVALID_DATE_US_SHORT_BETWEEN": "Needs to be a valid date format (mm/dd/yy) OR (mm-dd-yy) between :param and :param. ", + "INVALID_DATE_US_SHORT_MAX": "Needs to be a valid date format (mm/dd/yy) OR (mm-dd-yy), equal to, or lower than :param. ", + "INVALID_DATE_US_SHORT_MIN": "Needs to be a valid date format (mm/dd/yy) OR (mm-dd-yy), equal to, or higher than :param. ", + "INVALID_EMAIL": "Must be a valid email address. ", + "INVALID_EXACT_LEN": "Must have a length of exactly :param characters. ", + "INVALID_FLOAT": "May only contain a positive float value (integer excluded). ", + "INVALID_FLOAT_SIGNED": "May only contain a positive or negative float value (integer excluded). ", + "INVALID_IBAN": "Must a valid IBAN. ", + "INVALID_INPUT_MATCH": "Confirmation field does not match specified field \":param\". ", + "INVALID_INTEGER": "Must be a positive integer. ", + "INVALID_INTEGER_SIGNED": "Must be a positive or negative integer. ", + "INVALID_IPV4": "Must be a valid IP (IPV4). ", + "INVALID_IPV6": "Must be a valid IP (IPV6). ", + "INVALID_IPV6_HEX": "Must be a valid IP (IPV6 Hex). ", + "INVALID_KEY_CHAR": "Invalid keyboard entry on a field of type \"number\". ", + "INVALID_MAX_CHAR": "May not be greater than :param characters. ", + "INVALID_MAX_NUM": "Needs to be a numeric value, equal to, or lower than :param. ", + "INVALID_MIN_CHAR": "Must be at least :param characters. ", + "INVALID_MIN_NUM": "Needs to be a numeric value, equal to, or higher than :param. ", + "INVALID_NUMERIC": "Must be a positive number. ", + "INVALID_NUMERIC_SIGNED": "Must be a positive or negative number. ", + "INVALID_PATTERN": "Must be following this format: :param. ", + "INVALID_REQUIRED": "Field is required. ", + "INVALID_URL": "Must be a valid URL. ", + "INVALID_TIME": "Must be a valid time format (hh:mm) OR (hh:mm:ss). ", "AREA1": "TextArea: Alphanumeric + Minimum(15) + Required", @@ -48,15 +63,16 @@ "INPUT7": "IP (IPV4)", "INPUT8": "Credit Card", "INPUT9": "Between(2,6) Characters", - "INPUT10": "Date ISO (yyyy-mm-dd)", - "INPUT11": "Date US (long)", + "INPUT10": "Date ISO (yyyy-mm-dd)", + "INPUT11": "Date US LONG (mm/dd/yyyy)", "INPUT12": "Time (hh:mm OR hh:mm:ss) -- NOT Required", "INPUT13": "AlphaDashSpaces + Required + Minimum(5) Characters -- MUST USE: validation-error-to=\" \"", "INPUT14": "Alphanumeric + Required -- NG-DISABLED", "INPUT15": "Password", "INPUT16": "Password Confirmation", - "INPUT17": "Alphanumeric + Exactly(3) + Required -- debounce(5sec)", + "INPUT17": "Alphanumeric + Exactly(3) + Required -- debounce(5sec)", + "INPUT18": "Date ISO (yyyy-mm-dd) -- minimum condition >= 2001-01-01 ", + "INPUT19": "Date US SHORT (mm/dd/yy) -- between the dates 12/01/99 and 12/31/15", "SAVE": "Save", - "SELECT1": "Required (select) -- NoEVENT default(keyup) -- Directive will validate has EVENT (blur)", - "SELECT2": "Required (select) -- EVENT (blur)" + "SELECT1": "Required (select) -- validation with (blur) EVENT" } \ No newline at end of file diff --git a/locales/validation/fr.json b/locales/validation/fr.json index 2045215..3cdfa54 100644 --- a/locales/validation/fr.json +++ b/locales/validation/fr.json @@ -1,41 +1,56 @@ { - "INVALID_ALPHA": "Ne doit contenir que des lettres. ", - "INVALID_ALPHA_SPACE": "Ne doit contenir que des lettres et espaces. ", - "INVALID_ALPHA_NUM": "Ne doit contenir que des lettres et nombres. ", - "INVALID_ALPHA_NUM_SPACE": "Ne doit contenir que des lettres, nombres et espaces. ", - "INVALID_ALPHA_DASH": "Ne doit contenir que des lettres, nombres et des tirets. ", - "INVALID_ALPHA_DASH_SPACE": "Ne doit contenir que des lettres, nombres, tirets et espaces. ", - "INVALID_BETWEEN_CHAR": "Le texte doit être entre :param et :param caractères de longueur. ", - "INVALID_BETWEEN_NUM": "Doit être une valeur numérique, entre :param et :param. ", - "INVALID_BOOLEAN": "Doit contenir qu'une valeur vraie ou fausse. ", - "INVALID_CREDIT_CARD": "Doit être un numéro de carte de crédit valide. ", - "INVALID_DATE_EURO_LONG": "Doit être un format de date valide (dd-mm-yyyy) OU (dd/mm/yyyy). ", - "INVALID_DATE_EURO_SHORT": "Doit être un format de date valide (dd-mm-yy) OU (dd/mm/yy). ", - "INVALID_DATE_ISO": "Doit être un format de date valide (yyyy-mm-dd). ", - "INVALID_DATE_US_LONG": "Doit être un format de date valide (mm/dd/yyyy) OU (mm-dd-yyyy). ", - "INVALID_DATE_US_SHORT": "Doit être un format de date valide (mm/dd/yy) OU (mm-dd-yy). ", - "INVALID_EMAIL": "Doit être une adresse courriel valide. ", - "INVALID_EXACT_LEN": "Doit être d'une longueur fixe de :param caractères. ", - "INVALID_FLOAT": "Doit être obligatoirement un nombre flottant positif (nombre entier exclu). ", - "INVALID_FLOAT_SIGNED": "Doit être obligatoirement un nombre flottant positif ou négatif (nombre entier exclu). ", - "INVALID_IBAN": "Doit être un IBAN valide. ", - "INVALID_INPUT_MATCH": "Le champs de confirmation ne correspond pas au champs spécifié \":param\". ", - "INVALID_INTEGER": "Doit être un nombre entier positif. ", - "INVALID_INTEGER_SIGNED": "Doit être un nombre entier positif ou négatif. ", - "INVALID_IPV4": "Doit être un IP valide (IPV4). ", - "INVALID_IPV6": "Doit être un IP valide (IPV6). ", - "INVALID_IPV6_HEX": "Doit être un IP valide (IPV6 Hex). ", - "INVALID_KEY_CHAR": "Entrée clavier invalide sur un champs de type \"nombre\". ", - "INVALID_MAX_CHAR": "Doit être plus petit que :param caractères. ", - "INVALID_MAX_NUM": "Doit être une valeur numérique, égale ou inférieure à :param. ", - "INVALID_MIN_CHAR": "Doit avoir au moins :param caractères. ", - "INVALID_MIN_NUM": "Doit être une valeur numérique, égale ou supérieure à :param. ", - "INVALID_NUMERIC": "Doit être un nombre positif. ", - "INVALID_NUMERIC_SIGNED": "Doit être un nombre positif ou négatif. ", - "INVALID_PATTERN": "Doit suivre le format: :param. ", - "INVALID_REQUIRED": "Le champ est requis. ", - "INVALID_URL": "Doit être un URL valide. ", - "INVALID_TIME": "Doit être un format de date valide (hh:mm) OU (hh:mm:ss). ", + "INVALID_ALPHA": "Ne doit contenir que des lettres. ", + "INVALID_ALPHA_SPACE": "Ne doit contenir que des lettres et espaces. ", + "INVALID_ALPHA_NUM": "Ne doit contenir que des lettres et nombres. ", + "INVALID_ALPHA_NUM_SPACE": "Ne doit contenir que des lettres, nombres et espaces. ", + "INVALID_ALPHA_DASH": "Ne doit contenir que des lettres, nombres et des tirets. ", + "INVALID_ALPHA_DASH_SPACE": "Ne doit contenir que des lettres, nombres, tirets et espaces. ", + "INVALID_BETWEEN_CHAR": "Le texte doit être entre :param et :param caractères de longueur. ", + "INVALID_BETWEEN_NUM": "Doit être une valeur numérique, entre :param et :param. ", + "INVALID_BOOLEAN": "Doit contenir qu'une valeur vraie ou fausse. ", + "INVALID_CREDIT_CARD": "Doit être un numéro de carte de crédit valide. ", + "INVALID_DATE_EURO_LONG": "Doit être un format de date valide (dd-mm-yyyy) OU (dd/mm/yyyy). ", + "INVALID_DATE_EURO_LONG_BETWEEN": "Doit être un format de date valide (dd-mm-yyyy) OU (dd/mm/yyyy) entre :param et :param. ", + "INVALID_DATE_EURO_LONG_MAX": "Doit être une date valide (dd-mm-yyyy) OU (dd/mm/yyyy), égale ou inférieure à :param. ", + "INVALID_DATE_EURO_LONG_MIN": "Doit être une date valide (dd-mm-yyyy) OU (dd/mm/yyyy), égale ou supérieure à :param. ", + "INVALID_DATE_EURO_SHORT": "Doit être un format de date valide (dd-mm-yy) OU (dd/mm/yy). ", + "INVALID_DATE_EURO_SHORT_BETWEEN": "Doit être un format de date valide (dd-mm-yy) OU (dd/mm/yy) entre :param et :param. ", + "INVALID_DATE_EURO_SHORT_MAX": "Doit être une date valide (dd-mm-yy) OU (dd/mm/yy), égale ou inférieure à :param. ", + "INVALID_DATE_EURO_SHORT_MIN": "Doit être une date valide (dd-mm-yy) OU (dd/mm/yy), égale ou supérieure à :param. ", + "INVALID_DATE_ISO": "Doit être un format de date valide (yyyy-mm-dd). ", + "INVALID_DATE_ISO_BETWEEN": "Doit être un format de date valide (yyyy-mm-dd) entre :param et :param. ", + "INVALID_DATE_ISO_MAX": "Doit être une date valide (yyyy-mm-dd), égale ou inférieure à :param. ", + "INVALID_DATE_ISO_MIN": "Doit être une date valide (yyyy-mm-dd), égale ou supérieure à :param. ", + "INVALID_DATE_US_LONG": "Doit être un format de date valide (mm/dd/yyyy) OU (mm-dd-yyyy). ", + "INVALID_DATE_US_LONG_BETWEEN": "Doit être un format de date valide (mm/dd/yyyy) OU (mm-dd-yyyy) entre :param et :param. ", + "INVALID_DATE_US_LONG_MAX": "Doit être une date valide (mm/dd/yyyy) OU (mm-dd-yyyy), égale ou inférieure à :param. ", + "INVALID_DATE_US_LONG_MIN": "Doit être une date valide (mm/dd/yyyy) OU (mm-dd-yyyy), égale ou supérieure à :param. ", + "INVALID_DATE_US_SHORT": "Doit être un format de date valide (mm/dd/yy) OU (mm-dd-yy). ", + "INVALID_DATE_US_SHORT_BETWEEN": "Doit être un format de date valide (mm/dd/yy) OU (mm-dd-yy) entre :param et :param. ", + "INVALID_DATE_US_SHORT_MAX": "Doit être une date valide (mm/dd/yy) OU (mm-dd-yy), égale ou inférieure à :param. ", + "INVALID_DATE_US_SHORT_MIN": "Doit être une date valide (mm/dd/yy) OU (mm-dd-yy), égale ou supérieure à :param. ", + "INVALID_EMAIL": "Doit être une adresse courriel valide. ", + "INVALID_EXACT_LEN": "Doit être d'une longueur fixe de :param caractères. ", + "INVALID_FLOAT": "Doit être obligatoirement un nombre flottant positif (nombre entier exclu). ", + "INVALID_FLOAT_SIGNED": "Doit être obligatoirement un nombre flottant positif ou négatif (nombre entier exclu). ", + "INVALID_IBAN": "Doit être un IBAN valide. ", + "INVALID_INPUT_MATCH": "Le champs de confirmation ne correspond pas au champs spécifié \":param\". ", + "INVALID_INTEGER": "Doit être un nombre entier positif. ", + "INVALID_INTEGER_SIGNED": "Doit être un nombre entier positif ou négatif. ", + "INVALID_IPV4": "Doit être un IP valide (IPV4). ", + "INVALID_IPV6": "Doit être un IP valide (IPV6). ", + "INVALID_IPV6_HEX": "Doit être un IP valide (IPV6 Hex). ", + "INVALID_KEY_CHAR": "Entrée clavier invalide sur un champs de type \"nombre\". ", + "INVALID_MAX_CHAR": "Doit être plus petit que :param caractères. ", + "INVALID_MAX_NUM": "Doit être une valeur numérique, égale ou inférieure à :param. ", + "INVALID_MIN_CHAR": "Doit avoir au moins :param caractères. ", + "INVALID_MIN_NUM": "Doit être une valeur numérique, égale ou supérieure à :param. ", + "INVALID_NUMERIC": "Doit être un nombre positif. ", + "INVALID_NUMERIC_SIGNED": "Doit être un nombre positif ou négatif. ", + "INVALID_PATTERN": "Doit suivre le format: :param. ", + "INVALID_REQUIRED": "Le champ est requis. ", + "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", @@ -48,15 +63,16 @@ "INPUT7": "IP (IPV4)", "INPUT8": "Carte de Crédit", "INPUT9": "Entre(2,6) Caractères", - "INPUT10": "Date ISO (yyyy-mm-dd)", - "INPUT11": "Date US (long)", + "INPUT10": "Date ISO (yyyy-mm-dd)", + "INPUT11": "Date US LONG (mm/dd/yyyy)", "INPUT12": "Time (hh:mm OU hh:mm:ss) -- NON Requis", "INPUT13": "AlphaDashSpaces + Requis + Minimum(5) Caractères -- DOIT UTILISER: validation-error-to=\" \"", "INPUT14": "Alphanumérique + Requis -- NG-DISABLED", "INPUT15": "Mot de Passe", "INPUT16": "Mot de Passe (Confirmation)", - "INPUT17": "Alphanumérique + Exactement(3) + Requis -- debounce(5sec)", + "INPUT17": "Alphanumérique + Exactement(3) + Requis -- debounce(5sec)", + "INPUT18": "Date ISO (yyyy-mm-dd ) -- condition minimal >= 2001-01-01 ", + "INPUT19": "Date US COURT (mm/dd/yy) -- entre les dates 12/01/99 et 12/31/15", "SAVE": "Sauvegarder", - "SELECT1": "Requis (select) -- Aucun EVENT défaut(keyup) -- Directive va valider avec EVENT (blur)", - "SELECT2": "Requis (select) -- EVENT (blur)" + "SELECT1": "Requis (select) -- validation avec EVENT (blur)" } \ No newline at end of file diff --git a/readme.md b/readme.md index fb4ff3f..09c2b34 100644 --- a/readme.md +++ b/readme.md @@ -197,12 +197,32 @@ All validators are written as `snake_case` but it's up to the user's taste and c * `alpha_dash_spaces` Alpha-numeric chars + dashes, underscores and spaces (a-z, A-Z, 0-9, _-) * `between_len:min,max` Ensures the length of a string is between a min,max length. * `between_num:min,max` Ensures the numeric value is between a min,max number. +* `between_date_iso:d1,d2` alias of `between_date_iso`. +* `between_date_euro_long:d1,d2` alias of `date_euro_long_between`. +* `between_date_euro_short:d1,d2` alias of `date_euro_short_between`. +* `between_date_us_long:d1,d2` alias of `date_us_long_between`. +* `between_date_us_short:d1,d2` alias of `date_us_short_between`. * `credit_card` Valid credit card number (AMEX, VISA, Mastercard, Diner's Club, Discover, JCB) * `date_iso` Ensure date follows the ISO format (yyyy-mm-dd) +* `date_iso_between:d1,d2` Ensure date follows the ISO format and is between (d1) and (d2) +* `date_iso_max:d` Ensure date follows ISO format and is lower or equal then date (d) +* `date_iso_min:d` Ensure date follows ISO format and is higher or equal then date (d) +* `date_euro_long` Ensure date follows the European long format (dd-mm-yyyy) or (dd/mm/yyyy) +* `date_euro_long_between:d1,d2` Ensure date follows the European long format and is between (d1) and (d2) +* `date_euro_long_max:d` Ensure date follows European long format and is lower or equal then date (d) +* `date_euro_long_min:d` Ensure date follows European long format and is higher or equal then date (d) +* `date_euro_short` Ensure date follows the European short format (dd-mm-yy) or (dd/mm/yy) +* `date_euro_short_between:d1,d2` Ensure date follows the European short format and is between (d1) and (d2) +* `date_euro_short_max:d` Ensure date follows European short format and is lower or equal then date (d) +* `date_euro_short_min:d` Ensure date follows European short format and is higher or equal then date (d) * `date_us_long` Ensure date follows the US long format (mm-dd-yyyy) or (mm/dd/yyyy) +* `date_us_long_between:d1,d2` Ensure date follows the US long format and is between (d1) and (d2) +* `date_us_long_max:d` Ensure date follows US long format and is lower or equal then date (d) +* `date_us_long_min:d` Ensure date follows US long format and is higher or equal then date (d) * `date_us_short` Ensure date follows the US short format (mm-dd-yy) or (mm/dd/yy) -* `date_euro_long` Ensure date follows the Europe long format (dd-mm-yyyy) or (dd/mm/yyyy) -* `date_euro_short` Ensure date follows the Europe short format (dd-mm-yy) or (dd/mm/yy) +* `date_us_short_between:d1,d2` Ensure date follows the US short format and is between (d1) and (d2) +* `date_us_short_max:d` Ensure date follows US short format and is lower or equal then date (d) +* `date_us_short_min:d` Ensure date follows US short format and is higher or equal then date (d) * `email` Checks for a valid email address * `exact_len:n` Ensures that field length precisely matches the specified length (n). * `float` Only a positive floating point value (integer are excluded) @@ -217,6 +237,16 @@ All validators are written as `snake_case` but it's up to the user's taste and c * `ipv6_hex` Check for valid IP (IPv6 Hexadecimal) * `match:n` Match another input field(n), where (n) must be the exact ngModel attribute of input field to compare to. * `match:n,t` Match another input field(n), same as (match:n) but also include (t) for alternative text to be displayed in the error message. +* `max_date_iso` alias of `date_iso_max`. +* `min_date_iso` alias of `date_iso_min`. +* `max_date_euro_long` alias of `date_euro_long_max`. +* `min_date_euro_long` alias of `date_euro_long_min`. +* `max_date_euro_short` alias of `date_euro_short_max`. +* `min_date_euro_short` alias of `date_euro_short_min`. +* `max_date_us_long` alias of `date_us_long_max`. +* `min_date_us_long` alias of `date_us_long_min`. +* `max_date_us_short` alias of `date_us_short_max`. +* `min_date_us_short` alias of `date_us_short_min`. * `max_len:n` Checks field length, no longer than specified length where (n) is length parameter. * `max_num:n` Checks numeric value to be lower or equal than the number (n). * `min_len:n` Checks field length, no shorter than specified length where (n) is length parameter. @@ -273,4 +303,5 @@ License * [1.3.4](https://github.com/ghiscoding/angular-validation/commit/ba30d55ddb8bca44a8032fc8253356450bd4e1d4) `2015-01-06` Removed the necessity of creating a `` for displaying the error message, the directive now handles it by itself. * [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. \ No newline at end of file +* [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]() `2015-03-15` Added between/min/max conditional validators on all Date types (ISO, EURO_LONG, EURO_SHORT, US_LONG, US_SHORT) \ No newline at end of file diff --git a/src/validation-common.js b/src/validation-common.js index bf722b2..83cb3ff 100644 --- a/src/validation-common.js +++ b/src/validation-common.js @@ -172,22 +172,56 @@ angular // loop through all validators (could be multiple) for(var j = 0, jln = self.validators.length; j < jln; j++) { - if(self.validators[j].type === "conditionalNumber") { - // a condition type + if(self.validators[j].type === "conditionalDate") { + // 1- we first need to validate that the Date input is well formed through regex + // run the Regex test through each iteration, if required (\S+) and is null then it's invalid automatically + regex = new RegExp(self.validators[j].pattern, 'i'); + isValid = (self.validators[j].pattern === "\\S+" && (typeof strValue === "undefined" || strValue === null)) ? false : regex.test(strValue); + + // 2- date is valid, then we can do our conditional date check + if(isValid) { + // For Date comparison, we will need to construct a Date Object that follows the ECMA so then it could work in all browser + // Then convert to timestamp & finally we can compare both dates for filtering + var dateType = self.validators[j].dateType; // date type (ISO, EURO, US-SHORT, US-LONG) + var timestampValue = parseDate(strValue, dateType).getTime(); // our input value parsed into a timestamp + + // if 2 params, then it's a between condition + if(self.validators[j].params.length == 2) { + // this is typically a "between" condition, a range of number >= and <= + var timestampParam0 = parseDate(self.validators[j].params[0], dateType).getTime(); + var timestampParam1 = parseDate(self.validators[j].params[1], dateType).getTime(); + var isValid1 = testCondition(self.validators[j].condition[0], timestampValue, timestampParam0); + var isValid2 = testCondition(self.validators[j].condition[1], timestampValue, timestampParam1); + isValid = (isValid1 && isValid2) ? true : false; + }else { + // else, 1 param is a simple conditional date check + var timestampParam = parseDate(self.validators[j].params[0], dateType).getTime(); + isValid = testCondition(self.validators[j].condition, timestampValue, timestampParam); + } + } + } + // it might be a conditional number checking + else if(self.validators[j].type === "conditionalNumber") { + // if 2 params, then it's a between condition if(self.validators[j].params.length == 2) { // this is typically a "between" condition, a range of number >= and <= var isValid1 = testCondition(self.validators[j].condition[0], parseFloat(strValue), parseFloat(self.validators[j].params[0])); var isValid2 = testCondition(self.validators[j].condition[1], parseFloat(strValue), parseFloat(self.validators[j].params[1])); isValid = (isValid1 && isValid2) ? true : false; }else { + // else, 1 param is a simple conditional number check isValid = testCondition(self.validators[j].condition, parseFloat(strValue), parseFloat(self.validators[j].params[0])); } - }else if(self.validators[j].type === "match") { + } + // it might be a match input checking + else if(self.validators[j].type === "match") { // get the element 'value' ngModel to compare to (passed as params[0], via an $eval('ng-model="modelToCompareName"') var otherNgModel = self.validators[j].params[0]; var otherNgModelVal = self.scope.$eval(otherNgModel); isValid = (otherNgModelVal === strValue); - }else { + } + // or finally it might be a regular regex pattern checking + else { // a 'disabled' element should always be valid, there is no need to validate it if(self.elm.prop("disabled")) { isValid = true; @@ -241,6 +275,104 @@ angular return null; } + /** Parse a date from a String and return it as a Date Object to be valid for all browsers following ECMA Specs + * Date type ISO (default), US, UK, Europe, etc... Other format could be added in the switch case + * @var String dateStr: date String + * @var String dateType: date type (ISO, US, etc...) + */ + function parseDate(dateStr, dateType) { + // variables declaration + var dateSubStr = '', dateSeparator = '-', dateSplit = [], timeSplit = [], year = '', month = '', day = ''; + + // Parse using the date type user selected, (separator could be dot, slash or dash) + switch (dateType.toUpperCase()) { + case 'EURO_LONG': + case 'EURO-LONG': // UK, Europe long format is: dd/mm/yyyy hh:mm:ss + dateSubStr = dateStr.substring(0, 10); + dateSeparator = dateStr.substring(2, 3); + dateSplit = splitDateString(dateSubStr, dateSeparator); + day = dateSplit[0]; + month = dateSplit[1]; + year = dateSplit[2]; + timeSplit = (dateStr.length > 8) ? dateStr.substring(9).split(':') : null; + break; + case 'UK': + case 'EURO': + case 'EURO_SHORT': + case 'EURO-SHORT': + case 'EUROPE': // UK, Europe format is: dd/mm/yy hh:mm:ss + dateSubStr = dateStr.substring(0, 8); + dateSeparator = dateStr.substring(2, 3); + dateSplit = splitDateString(dateSubStr, dateSeparator); + day = dateSplit[0]; + month = dateSplit[1]; + year = (parseInt(dateSplit[2]) < 50) ? ('20' + dateSplit[2]) : ('19' + dateSplit[2]); // below 50 we'll consider that as century 2000's, else in century 1900's + timeSplit = (dateStr.length > 8) ? dateStr.substring(9).split(':') : null; + break; + case 'US_LONG': + case 'US-LONG': // US long format is: mm/dd/yyyy hh:mm:ss + dateSubStr = dateStr.substring(0, 10); + dateSeparator = dateStr.substring(2, 3); + dateSplit = splitDateString(dateSubStr, dateSeparator); + month = dateSplit[0]; + day = dateSplit[1]; + year = dateSplit[2]; + timeSplit = (dateStr.length > 8) ? dateStr.substring(9).split(':') : null; + break; + case 'US': + case 'US_SHORT': + case 'US-SHORT': // US short format is: mm/dd/yy hh:mm:ss OR + dateSubStr = dateStr.substring(0, 8); + dateSeparator = dateStr.substring(2, 3); + dateSplit = splitDateString(dateSubStr, dateSeparator); + month = dateSplit[0]; + day = dateSplit[1]; + year = (parseInt(dateSplit[2]) < 50) ? ('20' + dateSplit[2]) : ('19' + dateSplit[2]); // below 50 we'll consider that as century 2000's, else in century 1900's + timeSplit = (dateStr.length > 8) ? dateStr.substring(9).split(':') : null; + break; + case 'ISO': + default: // ISO format is: yyyy-mm-dd hh:mm:ss (separator could be dot, slash or dash: ".", "/", "-") + dateSubStr = dateStr.substring(0, 10); + dateSeparator = dateStr.substring(4, 5); + dateSplit = splitDateString(dateSubStr, dateSeparator); + year = dateSplit[0]; + month = dateSplit[1]; + day = dateSplit[2]; + timeSplit = (dateStr.length > 10) ? dateStr.substring(11).split(':') : null; + break; + } + + // parse the time if it exist else put them at 0 + var hour = (!!timeSplit && timeSplit.length === 3) ? timeSplit[0] : 0; + var min = (!!timeSplit && timeSplit.length === 3) ? timeSplit[1] : 0; + var sec = (!!timeSplit && timeSplit.length === 3) ? timeSplit[2] : 0; + + // Construct a valid Date Object that follows the ECMA Specs + // Note that, in JavaScript, months run from 0 to 11, rather than 1 to 12! + return new Date(year, month - 1, day, hour, min, sec); + } + + /** From a date substring split it and return his array + * @param string dateSubStr + * @param string dateSeparator + * @return array dateSplit + */ + function splitDateString(dateSubStr, dateSeparator) { + var dateSplit = []; + + switch (dateSeparator) { + case '/': + dateSplit = dateSubStr.split('/'); break; + case '.': + dateSplit = dateSubStr.split('.'); break; + case '-': + default: + dateSplit = dateSubStr.split('-'); break; + } + + return dateSplit; + } + /** Test values with condition, I have created a switch case for all possible conditions. * @var String condition: condition to filter with * @var any value1: 1st value to compare, the type could be anything (number, String or even Date) diff --git a/src/validation-rules.js b/src/validation-rules.js index 1aa8a34..43717db 100644 --- a/src/validation-rules.js +++ b/src/validation-rules.js @@ -6,7 +6,7 @@ * @desc: angular-validation rules definition * Each rule objects must have 3 properties {pattern, message, type} * and in some cases you could also define a 4th properties {params} to pass extras, for example: max_len will know his maximum length by this extra {params} - * Rule.type can be {conditionalNumber, match, regex} + * Rule.type can be {conditionalDate, conditionalNumber, match, regex} * * WARNING: Rule patterns are defined as String type so don't forget to escape your characters: \\ */ @@ -115,6 +115,108 @@ angular type: "regex" }; break; + case "dateEuroLong" : + case "date_euro_long" : + validator = { + pattern: "^(0[1-9]|[12][0-9]|3[01])[-/](0[1-9]|1[012])[-/](19|20)\\d\\d$", + message: "INVALID_DATE_EURO_LONG", + type: "regex" + }; + break; + case "dateEuroLongBetween" : + case "date_euro_long_between" : + case "betweenDateEuroLong" : + case "between_date_euro_long" : + var range = ruleParam.split(','); + if (range.length !== 2) { + throw "This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_long:01-01-1990,31-12-2015"; + } + validator = { + condition: [">=","<="], + dateType: "EURO_LONG", + params: [range[0], range[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" : + validator = { + condition: "<=", + dateType: "EURO_LONG", + params: [ruleParam], + 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" : + validator = { + condition: ">=", + dateType: "EURO_LONG", + params: [ruleParam], + 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" : + validator = { + 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 range = ruleParam.split(','); + if (range.length !== 2) { + throw "This validation must include exactly 2 params separated by a comma (,) ex.: between_date_euro_short:01-01-90,31-12-15"; + } + validator = { + condition: [">=","<="], + dateType: "EURO_SHORT", + params: [range[0], range[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" : + validator = { + condition: "<=", + dateType: "EURO_SHORT", + params: [ruleParam], + 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" : + validator = { + condition: ">=", + dateType: "EURO_SHORT", + params: [ruleParam], + 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" : validator = { @@ -122,7 +224,50 @@ angular message: "INVALID_DATE_ISO", type: "regex" }; + break; + case "dateIsoBetween" : + case "date_iso_between" : + case "betweenDateIso" : + case "between_date_iso" : + var range = ruleParam.split(','); + if (range.length !== 2) { + throw "This validation must include exactly 2 params separated by a comma (,) ex.: between_date_iso:1990-01-01,2000-12-31"; + } + validator = { + condition: [">=","<="], + dateType: "ISO", + params: [range[0], range[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" : + validator = { + condition: "<=", + dateType: "ISO", + params: [ruleParam], + 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" : + validator = { + condition: ">=", + dateType: "ISO", + params: [ruleParam], + 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" : validator = { @@ -131,6 +276,49 @@ angular type: "regex" }; break; + case "dateUsLongBetween" : + case "date_us_long_between" : + case "betweenDateUsLong" : + case "between_date_us_long" : + var range = ruleParam.split(','); + if (range.length !== 2) { + throw "This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_long:01/01/1990,12/31/2015"; + } + validator = { + condition: [">=","<="], + dateType: "US_LONG", + params: [range[0], range[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" : + validator = { + condition: "<=", + dateType: "US_LONG", + params: [ruleParam], + 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" : + validator = { + condition: ">=", + dateType: "US_LONG", + params: [ruleParam], + 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" : validator = { @@ -139,22 +327,49 @@ angular type: "regex" }; break; - case "dateEuroLong" : - case "date_euro_long" : + case "dateUsShortBetween" : + case "date_us_short_between" : + case "betweenDateUsShort" : + case "between_date_us_short" : + var range = ruleParam.split(','); + if (range.length !== 2) { + throw "This validation must include exactly 2 params separated by a comma (,) ex.: between_date_us_short:01/01/90,12/31/15"; + } validator = { - 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" + condition: [">=","<="], + dateType: "US_SHORT", + params: [range[0], range[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 "dateEuroShort" : - case "date_euro_short" : + break; + case "dateUsShortMax" : + case "date_us_short_max" : + case "maxDateUsShort" : + case "max_date_us_short" : validator = { - pattern: "^(0[1-9]|[12][0-9]|3[01])[-/](0[1-9]|1[012])[-/]\\d\\d$", - message: "INVALID_DATE_EURO_SHORT", - type: "regex" + condition: "<=", + dateType: "US_SHORT", + params: [ruleParam], + 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" : + validator = { + condition: ">=", + dateType: "US_SHORT", + params: [ruleParam], + 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" : validator = { 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])?$", diff --git a/templates/testingFormDirective.html b/templates/testingFormDirective.html index 1bdda01..8853694 100644 --- a/templates/testingFormDirective.html +++ b/templates/testingFormDirective.html @@ -53,14 +53,6 @@

Directive

-
- - -
@@ -85,7 +77,15 @@

Directive

- + +
+
+ + +
+
+ +
diff --git a/templates/testingFormService.html b/templates/testingFormService.html index 9fb3394..2ab2ff1 100644 --- a/templates/testingFormService.html +++ b/templates/testingFormService.html @@ -54,14 +54,6 @@

Service

-
- - -
@@ -87,6 +79,14 @@

Service

+
+ + +
+
+ + +