angularjs form validation when using directives

David Jones
@david3jones
avatar-davidejones

Angularjs is a great piece of technology and while I’m glad they have any documentation sometimes it falls short of providing enough information. Either that or I’m looking in the wrong places or approaching things the wrong way! Anyway in one of my latest setups i had a form that that had various fields all in a regular angular html file and they all used a ng-class attribute like this

ng-class="{error: myform.city.$error.required || myform.city.$invalid}" required

This would apply the class error to the form field if it was empty or wasn’t a valid entry, this worked great until i got to one of the fields that i had made into a directive. I wanted to just be able to pass the ng-class to it and keep the directive reusable. It seems no matter what i tried i couldn’t get something that worked and applied the classes correctly. Eventually i came up with the following passing ng-class as an attribute on the directive then evaluating the ngclass and setting it to a new variable called ngclassval everytime the ngmodel changed.

<form name="outform"><selectnames ng-model="firstname" name="firstname" ng-class="{error: myform.firstname.$error.required || myform.firstname.$invalid}" required ></selectnames></form>
app.directive("selectnames", function() {
        return {
            restrict: 'E',
            require:"ngModel",
            scope: {
                ngModel: '=',
                ngClass: "@"
            },
            controller: function($scope, $element) {
                $scope.names = ['David', 'Adam', 'Michael', 'Alison', 'Valdimar', 'Jenni'];
            },
            link: function(scope, element, attrs, ctrls) {
    		scope.$watch('ngModel', function(value) {
    			ctrls.$setViewValue(value);
    			scope.ngclassval = scope.$parent.$eval(attrs.ngClass);
    		});
            },
            template:'<div><select ng-options="name for name in names" ng-model="ngModel" ng-class="ngclassval" required></select></div>',
            replace:true
        }
});

This seemed to work pretty well, then just a few days ago i discovered I can actually create nested forms to deal with the validation and can do something like this which is much easier.

<form name="outform"><selectnames ng-model="firstname" name="firstname" required ></selectnames></form>
app.directive("selectnames", function() {
        return {
            restrict: 'E',
            require:"ngModel",
            scope: {
                ngModel: '='
            },
            controller: function($scope, $element) {
                $scope.names = ['David', 'Adam', 'Michael', 'Alison', 'Valdimar', 'Jenni'];
            },
            link: function(scope, element, attrs, ctrls) {
    		
            },
            template:'<ng-form name="innerform"><div><select ng-options="name for name in names" ng-model="ngModel" name="firstname" ng-class="{error: innerform.firstname.$error.required || innerform.firstname.$invalid}" required></select></div></ng-form>',
            replace:true
        }
});

Comments

  • avatar-bhumi
    # Bhumi
    Thanks for sharing. It solved my issue.

Comments are currently closed