I was wondering, if it is possible, to extend Angular's input directive? I want to attach some listeners to all input fields on a page. I think you can decorate existing modules with $provide.decorate, but I have no idea how to do this with a directive (and more precisely the input directive).
So, can anyone push me in the right direction? Some examples?
EDIT
Here is my directive that I have so far:
angular.module('onFocusBlur').
directive('onFocusBlur', ["$rootScope", function($rootScope) {
  return {
    restrict: "A",
    link: function(scope, elem, attrs) {
        elem.bind('focus',function() {
          scope.$apply(function() {
            $rootScope[attrs.onFocusBlur] = true;
          });
        });
        elem.bind('blur',function() {
          scope.$apply(function() {
            $rootScope[attrs.onFocusBlur] = false;
          });
        });
    }
  };
}]);
In my view, I can add this to an input field like this:
<input type="email" ng-model="email" on-focus-blur="repositionNavBar">
The downside is, that for every input field, I have to attach this listener manually in my code. Therefore, it would be useful, to alter the existing input directive, to include this listeners.
Here's a short gist of how you could decorate the built in Angular input directive, with $provide.decorator as you yourself suggested. 
app.config(function ($provide) {
  // Suffix is "Directive" for decorating directives.
  // $delegate refers to the original directive definition. 
  $provide.decorator('inputDirective', function ($delegate) {
    // When decorating a directive, $delegate is an array containing 
    // all of the directives of the same name. 
    // We're interested in the first in this case.
    var directive = $delegate[0];
    // Store a reference to the original directive linking function. 
    var link = directive.link;
    // Hook into the compile phase of the directive.
    directive.compile = function () {
      // The function returned by compile is your new link function.
      // Or 'postLink', to be exact. 
      return function (scope, el, attrs) {
        // Run the original link function. 
        link.apply(this, arguments);
        // Your new listener function
        function listener (e) {
          console.log(e);
        }
        // Set up your listener(s).
        el.bind('blur', listener);
        el.bind('focus', listener);
      };
    };
    // Return the decorated original ($delegate).
    return $delegate;
  });
});
Benefits of this approach, as I see it:
Here's a jsBin: http://jsbin.com/yafecinu/2/edit
I'd recommend you take a look at this article, that goes in-depth on decorating directives. The article covers extending not just linking phases, but controllers and pre-linking DOM manipulation aswell. A very good read!
See answer to this question. They talk about a couple different options to extend a directive from using $provide to making a directive with the same name.
Also, this link explains a few techniques (under "Extending Directives"): https://github.com/angular/angular.js/wiki/Understanding-Directives
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With