Jordan Jordan - 3 months ago 16
AngularJS Question

Create disabled binding in attribute directive

I'm trying to create a really simple character counter directive that I can just drop an attribute on any

textarea
or
input
and get an easy way to have the
input/textarea
obey angulars
ng-maxlength
and would be able to prevent typing past that point and append a simple span element after the
input/textarea
that would have a character count down.

What I'm now trying to figure out is how I can bind the disabled state of the
input/textarea
to be disabled once the max character count has been reached

angular.module('bidrAdminApp')
.directive('characterCounter', function ($compile) {
return {
restrict: 'A',
scope: {
characterCount: '=ngModel',
maxLength: '=ngMaxlength'
},
link: function postLink(scope, element, attrs) {
console.log(attrs);
var el = '<i>{{maxLength - characterCount.length}}</i>';
el = $compile(el)(scope);
$(element).after(el);
}
};
});


And the template is pretty straight forward so far


Answer

I wouldn't recommend to register any $watcher. In your case a simple event listener would suffice:

angular
  .module('app', [])
  .directive('myMaxCount', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attr) {
      var max = attr.myMaxCount;
      
      element.on('keydown', keydownHandler);
      scope.$on('$destroy', function () {
        element.off('keydown', keydownHandler);
      });      
      
      function keydownHandler (e) {
        if(e.target.value.length + 1 > max) {
          e.preventDefault();
        }
      }
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <input type="text" my-max-count="5"/>
</div>

This is way do not polute your $digest cycle :) Note that you have to deregister the listener in order to prevent memory leaks.

Comments