Angular Form Validations
Ibrahim Muhammad
Twitter: @ibrahimm
http://ibrahimmuhammad.com
https://slides.com/ibrahimm/ng-validation
<input type="number"
ng-model="creditCard.number"
name="number"
min="0" max="9999999999999999"
integer />
<span ng-show="form.size.$error.integer">
The value is not a valid integer!
</span>
<span ng-show="form.size.$error.min || form.size.$error.max">
The value must be in range 0 to 9999999999999999!
</span>
- Validation goes in the views
- Works well in a number of places
The Angular Way
The good and the bad
The Good:
- Easy - angular directives to help
- Customizable view to view
The Bad:
- Can easily be not DRY
- Custom validations are hard to generalize in directives
Error Object
{
"expiryDate": ["Expiry date must be after today"],
"number": false // or missing
}
Moving to a Service
function validate(){
var errors = {};
if (this.expiryDate > today) {
addError(errors, 'name', 'Expiry date must be after today');
}
return errors;
}
- DRYer, if used in multiple views
- We lose the angular provided helpers
Validation helpers
function validateDateGreaterThan(model, attribute, value) {
if (model[attribute]) <= value) {
addError(model, attribute, attribute + ' must be after '+ value);
// error added to model.errors
}
}
validateDateGreaterThan(creditCard, 'expiryDate', Date.now())
More Delarative
var schema = {
'expiryDate': {
'min': new Date("1 Jan 1980"),
'max': Date.now(),
'type': 'date'
}
}
var errors = validate(model, schema);
- possibly use JSON schema with existing validators
Custom Validations (1)
var schema = {
'number': {
'min': function(creditcard) {
var len = creditcard.number.length;
if (creditcard.type === 'visa'){
return (len === 13 || len == 16);
} else { //mastercard
return len === 16;
}
}
}
}
- Use functions or values (inspiration from grunt)
Custom Validations (2)
var schema = {
'number': {
'checksum': function(creditcard) {
var errorMessage = "Checksum is not valid";
return [isChecksumValid(creditcard.number), errorMessage];
}
}
}
More Human
validate(creditcard)
.field('number').type('number')min(0).max(9999999999999999).checksum()
.field('expiryDate').type('date').min(Date(MIN_DATE)).max(Date.Today())
- Use method chaining
Thanks!
Interested in OS library that does this? @ibrahimm
Angular JS Form Validations
By Ibrahim Muhammad
Angular JS Form Validations
Pros and cons of Angular style form validations, how to move validation logic out of the views, and how to develop a more declarative style of validations in services.
- 1,474