Reputation: 899
I have a working solution for validating each field on keyup in a form in angularjs. I feel it can be better though. Are there any more clever ways?
The HTML:
<input type="text" placeholder="First Name" ng-keyup="validateFirstName($event) "ng-model="user.firstName"/>
<i ng-class="firstNameValidation" class="icon placeholder-icon padding"></i>
<input type="text" placeholder="Last Name"/>
<i ng-class="lastNameValidation" class="icon placeholder-icon padding"></i>
<input type="email" placeholder="Email"/>
<i ng-class="emailValidation" class="icon placeholder-icon padding"></i>
And in the controller i have:
$scope.user = {}
$scope.firstNameValidation = "ion-arrow-left-a text-danger"
$scope.lastNameValidation = "ion-arrow-left-a text-danger"
$scope.emailValidation = "ion-arrow-left-a text-danger"
$scope.validateFirstName = ($event) ->
if $scope.user.firstName.trim().length > 2
$scope.firstNameValidation = "ion-checkmark-circled text-success"
else
$scope.firstNameValidation = "ion-arrow-left-a text-danger"
...
And so on, a function for each field of the input validation. I feel like there is too much redundancy.
Any ideas?
Upvotes: 0
Views: 336
Reputation: 233
- The AngularJS team provide you with a small set of predefined validators that you can use out of the box and I recommend you to take a look at their documentation at https://docs.angularjs.org/api/ng/directive/input
- There's a great article over at year of moo with a more in-depth view and explanation on how this is done in 1.3
Here's a simple and dirty plunkr to show you the 1.2.x way i action
Given the following template
<form name="myForm">
<!-- Notice my custom validator named max-length -->
<input type="text" name="firstName" ng-model="firstName"
max-length="20"
ng-class="myForm.firstName.$error.maxLength ? 'ion-arrow-left-a text-danger' : 'ion-checkmark-circled text-success'"
/>
</form>
here's how you do it in Angular 1.2.x
angular
.module('App')
.directive('maxLength', function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ngModel) {
var maxLength = parseInt(attr.maxLength);
//For DOM -> model validation
ngModel.$parsers.unshift(function(value) {
var validity = validate(value);
ngModel.$setValidity('maxLength', validity);
return validity ? value : undefined;
});
//For model -> DOM validation
ngModel.$formatters.unshift(function(value) {
var validity = validate(value);
ngModel.$setValidity('maxLength', validity);
return value;
});
function validate(value) {
return value.trim().length < maxLength;
}
}
};
});
and here's how it's done in Angular 1.3.x
angular
.module('App')
.directive('maxLength', function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ngModel) {
var maxLength = parseInt(attr.maxLength);
ngModel.$validators.maxLength(function(value) {
return validate(value, maxLength);
});
function validate(value, maxLength) {
return value.trim().length < maxLength;
}
}
};
});
Now, what I've shown you is one way, and the way the angular team thinks of custom validation according to their documentation but, one size doesn't fit all and there are other ways to do this validation. One such way is to make use of 3rd party modules like the one Marcel-Stör mentioned in his answer.
Best of luck to you on your road to mastering custom validation in angularjs :)
Upvotes: 1
Reputation: 23555
It may be a matter of style or preference but I suggest you give valdr a try. I'm quite convinced it offers the features you're looking for - particularly if redundancy bothers you.
Upvotes: 1