#Angular Validation
Version: 1.3.4
Angular Validation made easy! Angular Validation is an angular directive with locales (languages) with a simple approach of defining your validation="" directly within your element to validate (input, textarea, etc) and...that's it!!! The directive will take care of the rest!
The base concept is not new, it comes from the easy form input validation approach of Laravel Framework as well as PHP Gump Validation. They both are built in PHP and use a very simple approach, so why not use the same concept over Angular as well? Well now it is available and with some extras.
For a smoother user experience, I also added validation on inactivity (timer). So validation will not bother the user while he is still typing... but as soon as the user makes a pause for a certain amount of time, then validation comes into play. This feature is only while typing, if user is focusing out of the input (onBlur) it will validate instantly.
Now also supporting AngularJS 1.3.x current code should work with 1.2.x just the same but is no more verified
Angular-Validation requires the element that will use validation to have a name="" attribute, so that it can use this name to associate a <span> for error displaying. For example: <input name="input1" ng-model="input1" validation="validator1" />.
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 <span> for error displaying. For a better understanding, the <span> is now optional, but the name="" attribute becomes mandatory and will throw an error if omitted
Let's start with a simple example and then let's get down to real business.
P.S. For real live sample, see the live demo or download the Github project and run the index.html (no server required, except Chrome which doesn't want to run http outside of webserver) while the actual form with validation is inside templates/testingForm.html for a better separation.
<!-- example 1 -->
<!-- change the typing-limit (timer in ms of inactivity) after which will trigger the validation check -->
<label for="input1">Simple Integer -- typing-limit(5sec)</label>
<input type="text" name="input1" ng-model="form1.input1" typing-limit="5000" validation="integer|required" />
<!-- example 2 -->
<label for="input2">email + min(3) + max(10) + required</label>
<input type="text" name="input2" ng-model="form1.input2" validation="email|min_len:3|max_len:10|required" />
<!-- example 3 -->
<!-- between_num could also be written with 2 conditions of min_num:n|max_num:n ... same goes to between_len -->
<label for="input3">Float only + between(min,max) + required</label>
<input type="number" name="input3" ng-model="form1.input3" validation="numeric|between_num:6,99.9|required" />
<!-- example 4 -->
<!-- input match confirmation (ex.: password confirmation) -->
<!-- match validator can use 1 or 2 params (match:field1 ..OR.. match:field1,Text to Display) -->
<!-- when using 2 params (separated by comma ',') then 2nd param is used as text to display -->
<label for="input4">Password</label>
<input type="password" name="input4" ng-model="form1.input4" validation="alpha|min_len:4|required" />
<label for="input4c">Password Confirmation</label>
<input type="password" name="input4c" ng-model="form1.input4c" validation="match:form1.input4,Password not match|required" />
<!-- example 5 - with Regular Expression (Date Code of YYWW) -->
<label for="input5">Multiple Validations + Custom Regex of Date Code (YYWW)</label>
<input type="text" name="input5" ng-model="form1.input5"
validation="exact_len:4|regex:YYWW:=^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$:regex|required|integer" />
<!-- example 6 - required select option (dropdown) -->
<div class="form-group">
<label for="select1">Select Option Required</label>
<select id="stk_type" name="stk_type" class="form-control" ng-model="form1.select1" validation="required">
<option value="">...</option>
<option value="1">Option #1</option>
<option value="2">Option #2</option>
</select>
</div>
<!-- EXPLANATIONS -->
<!-- <input> need the <validation=""> each validators are separated by a pipe | -->
<input validation="validator1|validator2|..." />
<!-- Example -->
<input type="text" name="input1" />
<!-- The directive will create by itself the following element, with a className of "validation-inputName" to display the error -->
<!-- You could easily apply styling as you see fit, using the className of "validation" and/or "validation text-danger" -->
<span class="validation-input1 validation text-danger">error message here</span>
<!-- EXCEPTIONS: We could also use our own custom <span> or <div> element when needed, for example input groups wrapper, see next step -->Well let's face it, having the <span> 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 <span> or a <div> 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.
<div class="form-group" ng-hide="trsn.isDividend">
<label for="input1">Search Input with BS input-groups</label>
<div class="input-group">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" name="input1" ng-model="form1.input1"
validation="min_len:2|max_len:10|alpha_dash_spaces|required"
validation-error-to="myErrorId" />
<span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>
</div>
<span id="myErrorId" class="validation text-danger"></span>
</div>
<!-- 3 ways of writting it, 2 ways for ID, 1 way for className -->
<!-- with an ID -->
<input name="input1" validation="validator1" validation-error-to="myErrorId" />
<input name="input1" validation="validator1" validation-error-to="#myErrorId" />
<span id="myErrorId" class="validation text-danger"></span>
<!-- or with a className -->
<input name="input1" validation="validator1" validation-error-to=".errorClassName" />
<span class="errorClassName validation text-danger"></span>
<!-- or even better, since this directive use a pattern of className named as "validation-yourInputName" -->
<!-- you could create only the `<span>` and ommit/skip the `validation-error-to=""` attribute within the input -->
<input name="input1" validation="validator1" />
<span class="validation-input1 validation text-danger"></span>From the example displayed, I introduce the custom regular expression, there is no limitation on regex itself and you can even use the pipe " | " without being scared of interfering with the other validation filters BUT you have to follow a specific pattern (a writing pattern that is), and if you don't, well it will fail. Let's explain how it works...
Regex validation is divided in 4 specific parts (Step #1-4).
Let's use the previous Examples #3 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).
-
Start and End the filter with the following
regex: :regexthat tells the directive to extract it. -
Custom error message
YYWW(what do we want to display to user) -
Followed by a separator which basically says, after this will come the regex
:= -
Custom regex pattern
^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$
Final code (no spaces): regex:YYWW:=^(0[9]|1[0-9]|2[0-9]|3[0-9])(5[0-2]|[0-4][0-9])$:regex
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
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 it would add an overhead and I prefer to keep it simple as validation messages often looks the same anyway. If you do want to fully localize, then see the example in Include it in your Project
// define a key, could be on the fly with a button or a menu link
var key = 'fr';
$scope.switchLanguage = function (key) {
$translate.use(key);
};P.S. If you define 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.
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.
NOTE: on an input type="number", the "+" sign is an invalid character (browser limitation) even if you are using a signed validator. If you really wish to use the "+", then change your input to type="text".
alphaOnly alpha characters (including latin) are present (a-z, A-Z)alpha_spacesOnly alpha characters (including latin) and spaces are present (a-z, A-Z)alpha_numOnly alpha-numeric characters (including latin) are present (a-z, A-Z, 0-9)alpha_num_spacesOnly alpha-numeric characters (with latin & spaces) are present (a-z, A-Z, 0-9)alpha_dashOnly alpha-numeric characters + dashes, underscores are present (a-z, A-Z, 0-9, _-)alpha_dash_spacesAlpha-numeric chars + dashes, underscores and spaces (a-z, A-Z, 0-9, _-)between_len:min,maxEnsures the length of a string is between a min,max string length.between_num:min,maxEnsures the numeric value is between a min,max number.credit_cardCheck for valid credit card number (AMEX, VISA, Mastercard, Diner's Club, Discover, JCB)date_isoEnsure date follows the ISO format (yyyy-mm-dd)date_us_longEnsure date follows the US long format (mm-dd-yyyy) or (mm/dd/yyyy)date_us_shortEnsure date follows the US short format (mm-dd-yy) or (mm/dd/yy)date_euro_longEnsure date follows the Europe long format (dd-mm-yyyy) or (dd/mm/yyyy)date_euro_shortEnsure date follows the Europe short format (dd-mm-yy) or (dd/mm/yy)emailChecks for a valid email addressexact_len:nEnsures that field length precisely matches the specified length (n).floatOnly a positive floating point value (integer are excluded)float_signedOnly a floating point value (integer excluded), could be signed (-/+) positive/negative.ibanCheck for a valid IBAN.intOnly positive integer (alias tointeger).integerOnly positive integer.int_signedOnly integer, could be signed (-/+) positive/negative (alias tointeger_signed).integer_signedOnly integer, could be signed (-/+) positive/negative.ipv4Check for valid IP (IPv4)ipv6Check for valid IP (IPv6)ipv6_hexCheck for valid IP (IPv6 Hexadecimal)match:nMatch another input field(n), where (n) must be the exact ngModel attribute of input field to compare to.match:n,tMatch another input field(n), same as (match:n) but also include (t) for alternative text to be displayed.max_len:nChecks field length, no longer than specified length where (n) is length parameter.max_num:nChecks numeric value to be lower or equal than the number (n).min_len:nChecks field length, no shorter than specified length where (n) is length parameter.min_num:nChecks numeric value to be higher or equal than the number (n).numericOnly positive numeric value (float, integer).numeric_signedOnly numeric value (float, integer) can also be signed (-/+).regexEnsure it follows a regular expression pattern... please see Regex sectionrequiredEnsures the specified key value exists and is not emptyurlCheck for valid URL or subdomaintimeEnsure time follows the format of (hh:mm) or (hh:mm:ss)
// include it your app module ( we need both Translate & Validation)
var myApp = angular.module('myApp', ['ngRoute', 'ghiscoding.validation', 'pascalprecht.translate']);
// include validation languages
// if you want full localization add it in the suffix
// For example on Canadian French/English, we could replace the code by `suffix: '-CA.json'`
myApp.config(function ($translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: 'locales/validation/',
suffix: '.json'
});
// load English ('en') table on startup
$translateProvider.preferredLanguage('en');
});- Angular-Translate (https://github.com/PascalPrecht/angular-translate)
- Bootstrap 3.x is optional (http://getbootstrap.com/)
- AngularJS 1.2.x / 1.3.x (https://angularjs.org/)
- Add more validators...
- Add more locale languages... I need your help on that one!!!
- Create an Angular Service that will provide access to attaching validation on the fly from within a controller
- 1.3.0
2014-12-01Added support to AngularJS 1.3 - 1.3.1
2015-01-02Added Input Match/Confirmation Validator, ex: password confirmation. - 1.3.2
2015-01-03Float number validator to also permit dot (.) as first character. Also removed keyboard blocking of invalid character on input type="number" now displays error message. - 1.3.3
2015-01-04Added changelog & updated Bootstrap(3.3.1), AngularJS(1.3.7) to latest versions - 1.3.4
2015-01-06Removed the necessity of creating a<span>for displaying the error message, the directive now handles it by itself. - 1.3.5
2015-01-26Throw an error message when user did not provide aname=""property inside the element to validate. - 1.3.6
2015-02-09Addedng-strict-difor minification, renamed some files and folder lib to/vendors, moved directive into new/srcfolder for better separation.