Shiva Goud A
Shiva Goud A

Reputation: 322

How to create custom directive to listen to input changes

Hi Here I wrote a custom directive. That directive need to call for each time when value changed. Here is my directive. How can I call in ng-change.here is my directive.

app.directive('percentageFormatter', function() {
      return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModelController) {
          ngModelController.$parsers.push(function(data) {
            //convert data from view format to model format
            return data.replace('%','');
          });

          ngModelController.$formatters.push(function(data) {
            //convert data from model format to view format
            return data+'%';
          });
        }
      }
    });

JSP:-

<input type="text"  percentage-formatter ng-model="tea">

Here How to call that directive in ng-change.

Upvotes: 0

Views: 122

Answers (4)

georgeawg
georgeawg

Reputation: 48968

How can I call in ng-change.here is my directive.

Under the hood1 the ng-change directive uses the ngModelController.$viewChangeListeners API. The percentageFormatter directive can do the same:

ngModelController.$viewChangeListeners.push(function myChange() {
     //Do things as if called by ng-change
});

The myChange function is only evaluated when a change in the input value causes a new value to be committed to the model.

It will not be evaluated:

  • if the value returned from the $parsers transformation pipeline has not changed
  • if the input has continued to be invalid since the model will stay null
  • if the model is changed programmatically (from a controller vs user input)

This gives an authentic "ng-change" functionality to the directive without adding additional watchers or event listeners.

Upvotes: 0

Abdullah Al Noman
Abdullah Al Noman

Reputation: 2878

$scope.watch function watches for changes in values . Add this to your directive

 $scope.$watch(function () {
  // do soething 
});

or you can below one use as well .

   element.bind('keypress', function(event) {
      if(event.keyCode === 32) {
        event.preventDefault();
      }
    });

This is how I would create my percentage formater

angular.module('test')
  .directive('percentageFormatter', function() {
    return {
      require: '?ngModel',
      link: function(scope, element, attrs, ngModelCtrl) {
        if(!ngModelCtrl) {
          return;
        }

        ngModelCtrl.$parsers.push(function(val) {
          if (angular.isUndefined(val)) {
            val = '';
          }
          var clean = val.replace("%", '');
          if (val !== clean) {
            ngModelCtrl.$setViewValue(clean);
            ngModelCtrl.$render();
          }
          return clean;
        });

        element.bind('keypress', function(event) {
          if(event.keyCode === 32) {
            event.preventDefault();
          }
        });
      }
    };
  });

Upvotes: 2

digit
digit

Reputation: 4565

Directly call change event in the directive .Try this

app.directive('percentageFormatter', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModelController) {
        element.bind('change', function () {
             ngModelController.$setViewValue(element.val());
             ngModelController.$render();
        });
    }
  }
});

Upvotes: 0

rrd
rrd

Reputation: 5977

My first thought runs to using $watch():

app.directive('percentageFormatter', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModelController) {
      scope.$watch(
        () => ngModelController.$modelValue,
        (newval) => {
          // Do your stuff here - the value has changed!
      }
    );
  }
);

Upvotes: 1

Related Questions