2

I have this directive that prepends an <i> element before each <input> element with add-icon-element attribute. Now what i'm trying to do is to observe validation for each <input> element, so when the user types something in one of them the class of the <i> element that precedes will change to fa-check green-i. I tried to do it by using attrs.$observe to see when the class changes from ng-invalid to ng-valid but it fires only one time when the DOM is structured, it doesn't react to changes in the input element.

What am i doing wrong? is there a way to do it using the input $valid? I saw some answers regarding one input with suggestions to add names to the form and input - but what can I do if I have multiple inputs that I need to validate and not just one?

angular.module('mean.theme')
.directive("addIconElement", function () {
    return {
        restrict: 'EA',
        link: function (scope, inputElement, attrs) {
            var $icon = $('<i class="fa"></i>');
            inputElement.before($icon);
            attrs.$observe('class', function(val){
                if (val.indexOf("ng-valid") >= 0) {
                    inputElement.prev().addClass('fa-check green-i');
                }
            });
        }
    };
});

and this is one of my 'inputs' in the html:

<form role="form" name="createProjectForm" class="form-validation">
    <div class="form-group">
        <label class="control-label text-center center-block" for="project.name">
                Name Your Project
        </label>
        <div class="input-icon right">
            <input type="text" placeholder="type here" name="project.name"
                ng-model="project.name" required="required" class="form-control" add-icon-element/>
        </div>
    </div>
<form>
2
  • how your directive html looks like?? Commented Dec 3, 2015 at 19:24
  • @PankajParkar yes, sorry, i added the html.. Commented Dec 3, 2015 at 20:07

2 Answers 2

1

You don't need create a directive for such case, you could achieve this by using ng-class directive, only change your field name from name="project.name" to name="project_name"

<div class="input-icon right">
    <input type="text" placeholder="type here" name="project.name" 
       ng-class="{'fa-check green-i': createProjectForm.project_name.$valid}"
       ng-model="project.name" required="required" 
       class="form-control"/>
</div>

Update

To make it generic way, you need to require ngModel directive on that element, which will give you access to the ngModelController.

angular.module('mean.theme')
.directive("addIconElement", function () {
    return {
        restrict: 'EA',
        require: 'ngModel', //require to get access to `ngModelController`
        link: function (scope, inputElement, attrs, ngModelCtrl) {
            var $icon = $('<i class="fa"></i>');
            inputElement.before($icon);
            scope.$watch(function(){
               return ngModelCtrl.$valid; //made watch on field validation.
            }, function(val){
                if (val.indexOf("ng-valid") >= 0) {
                    inputElement.prev().addClass('fa-check green-i');
                }
            });
        }
    };
});
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the answer, but i need to apply the class "fa-check green-i" to the <i> tag that was placed before that input. and also, i have multiple inputs, so i need something more generic for all of them instead of addressing each one in particular. any idea..?
perfect answer, thanks a lot! i'm pretty new to angular and was searching a solution for 2 hours... :)
1

I think this will do it for you: https://stackoverflow.com/a/23871934/1636157

angular.module('mean.theme')
.directive("addIconElement", function () {
    return {
        restrict: 'EA',
        require: '^form',
        link: function (scope, inputElement, attrs, ctrl) {
            var $icon = $('<i class="fa"></i>');
            inputElement.before($icon);

            scope.$watch(ctrl.$name + '.' + inputElement.attr('name') + '.$valid', function (valid) {
               if(valid) {
                  inputElement.prev().addClass('fa-check green-i');
               } else {
                  inputElement.prev().removeClass('fa-check green-i');
               }
            }); 
        }
    };
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.