user1323136
user1323136

Reputation: 899

Is there a better way to validate this angular form?

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

Answers (2)

mengstrom
mengstrom

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

The fun part

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;
                }
            }
        };


});

To conclude

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

Marcel St&#246;r
Marcel St&#246;r

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

Related Questions