11

I'm trying to create a custom component (directive) which is composed of an <input> box and a [-] and [+] buttons. Currently, the example below only implements the input box.

So, say I have the following HTML for my directive:

<my-input ng-blur="onBlur($event)" ng-focus="onFocus($event)"></my-input>

And for testing purposes, I use this code:

app.run(function ($rootScope) {
  $rootScope.onBlur = function ($event) {
    console.log('onBlur', $event);
  };

  $rootScope.onFocus = function ($event) {
    console.log('onFocus', $event);
  };
});

Now I want to create my custom <my-input> directive which has an <input> box on the template and I need the ng-blur and ng-focus set on <my-input> to respond to blur/focus events on the input box.

I have the following solution almost working: http://codepen.io/anon/pen/KpELmj

1) I have a feeling that this can be achieved in a much better way, I just can't seem to do it. Thoughts?

2) $event seems to be undefined and I can't understand why. Thoughts?

rfgamaral
  • 16,546
  • 57
  • 163
  • 275

2 Answers2

4

Ok figured it out. Doron's answer was a good starting point for research, but now I think I have what you are looking for. The key is you have to use & in the link section in order to get it to execute the expression.

.directive('myInput', function($timeout) {
    return {
        restrict: 'E',
        scope: {
            data: '=',
            blur: '&myBlur' //this is the key line
        },
        template: '<input ng-blur="blur($event)" ng-model="data">'
    }
})

This is how you use it:

<my-input my-blur="runBlurFunc()"></my-input>

If you really want to define the function on the root scope, you can use $scope.$root.onBlur() instead of runBlurFunc()

user3413723
  • 11,147
  • 6
  • 55
  • 64
1

Hope I got your question right, did you try to use the link function?

app.directive('myInput', function () {
  return {
    restrict: 'E',
    scope: {
      ngBlur: '&',
      ngFocus: '&'
    },
    bindToController: true,
    controller: controllerFn,
    controllerAs: 'ctrl',
    link:function(scope){

      scope.onBlur = function(ev){
        console.log(ev);
      }

      scope.onFocus = function(ev){
       console.log(ev);
     }

   },

   template: '[-]<input ng-blur="onBlur($event)" ng-focus="onFocus($event)"></input>[+]'
 }
});
yvesmancera
  • 2,915
  • 5
  • 24
  • 33
Doron Sinai
  • 1,166
  • 3
  • 12
  • 28
  • 1
    I'm afraid you didn't, maybe I didn't explain myself correctly. With your solution your moving the `console.log`s to the directive implementation and I need that outside of that scope. I used the `run` block and `$rootScope` as example but it could also be some other controller. Basically, I want to delegate the `ng-focus` and `ng-blur` events to the directive parent scope. – rfgamaral Aug 11 '15 at 20:57