Sam
Sam

Reputation: 15310

How can I access an attribute of a sibling directive inside of a form using Angular

I'm trying to make a counter-for directive that would show the amount of characters entered into an arbitrary input.text or textarea inside of the same form in this format {{currentCharCount}}/{{maxCharCount}}

This directive might be used like this:

<form name="form">
  <textarea name="username"></textarea>
  <div counter-for="username"></div>
</form>

Upvotes: 2

Views: 351

Answers (1)

Ilan Frumer
Ilan Frumer

Reputation: 32377

I made a plunker

My approach is to create a directive on the textarea element itself:

<form name="form">
   <textarea name="username"
             ng-model="text" 
             ng-max-length="200"
             counter>

   </textarea>
</form>

Inside the directive require ngModel and use it's controller:

app.directive('counter', function(){
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs,ctrl){
      var max = attrs.ngMaxLength;
      var div = angular.element("<div>0/" + max + "</div>");
      elm.after(div);
      ctrl.$parsers.push(function(value){
        var count = (value || '').length + "/" + attrs.ngMaxLength;
        div.html(count);
        return value;
      });
    }
  }
})

Considerations

  • It's better to avoid populating the scope (with extra $watchers) as much as possible.
  • There are hacky ways of getting a sibling scope but that's bad design and error prone.
  • No scope wants another scope to invade it's territory, and no scope is expecting that.

Upvotes: 1

Related Questions