title: Angular directive injecting DOM element with click event
body: <h3>Content edited</h3>
  
  <p>The goal is to create a directive that can be attached to a textbox that, when the textbox has focus, an image/button will appear after the textbox and the image/button click event will fire a function contained within the directive.  The goal is for this functionality to be entirely self-contained in the directive so it can be easily deployed in many pages or apps.</p>
  
  <p>The image/button appears after the textbox with no problem but the click event of the button does not fire the function.  I have created a <a href="https://plnkr.co/edit/IE4DjeuhCBsWRCalc5A5?p=preview" rel="nofollow noreferrer">plunkr</a> with the example code.  </p>
  
  <p>In the plunk, line 15 defines a function called 'search,' which does nothing more than fire an alert.  When the textbox has focus, the button appears as expected and line 34 calls the search function successfully, which means the function itself is working. However, the button's click event doesn't fire the search function.</p>
  
  <hr>
  
  <h3>Original post</h3>
  
  <p>I'm trying to recreate some functionality in our apps that is currently being accomplished with jQuery.  The functionality involves attaching a pseudo-class to a textbox which is then picked up by jQuery and an image of a magnifying glass is injected into the DOM immediately after the textbox.  Clicking on the image causes a dialog box to pop open.  </p>
  
  <p>What I've accomplished so far is a simple html page, a simple controller, and a simple directive.  When the textbox has focus, the image appears as expected.  However, the ng-click directive does not fire.  </p>
  
  <p>Here's the html:
          </p>
  
  <pre><code>            &lt;input 
                  id="txtAlias" 
                  type="text" 
                  ng-model="pc.results"
                  user-search  /&gt;
  
  &lt;/div&gt;
  </code></pre>
  
  <p>Here is the controller: </p>
  
  <pre><code>angular
     .module('app')
     .controller('PeopleController', PeopleController);
  
  PeopleController.$inject = ['$http'];
  
  function PeopleController() {
  
     var pc = this;
  
     pc.results = '';
  
     pc.search = function () {
         alert('test');
     };
  }
  </code></pre>
  
  <p>And this is the directive: </p>
  
  <pre><code>angular
      .module('app')
      .directive('userSearch', userSearch);
  
  function userSearch($compile) {
  
  return {
      restrict: 'EAC',
      require: 'ngModel',
      //transclude: true,
      scope: {
          //search : function(callerid){
          //    alert(callerid);
          //}
      },
      template: "The user's alias is: &lt;b&gt;&lt;span ng-bind='pc.results'&gt;&lt;/span&gt;.",
      //controller: UserSearchController,
      link: function (scope, element, attrs) {
          element.bind('focus', function () {
  
              //alert(attrs.id + ' || ' + attrs.userSearch);
  
              var nextElement = element.parent().find('.openuserdialog').length;
  
              if (nextElement == 0) {
                  var magnifyingglass = $compile('&lt;img src="' + homePath + 'Images/zoomHS.png" ' +
                                          'alt="User Search" ' +
                                          'ng-click="pc.search("' + attrs.id + '")" ' +
                                          'class="openuserdialog"&gt;')(scope);
  
                  element.after(magnifyingglass);
              }
  
          });
      }
  
  };
  
  };
  </code></pre>
  
  <p>For the time being, I'd be happy to get an alert to fire by either hitting pc.search in the controller or by search in the isolated scope.  So far, neither has worked.  I'm sure it's something simple that's missing but I can't figure out what.</p>
  
  <hr>
  
  <h3>Solution</h3>
  
  <p>Thanks to a user over at the Google forum for showing me the controllerAs property for directives.  This version now works perfectly:</p>
  
  <pre><code>angular
  .module('app')
  .directive('userSearch', userSearch);
  
  function userSearch($compile){
  
  return {
      controller: function ()
          {
              this.search = function () {
                  alert('Test');
              };
          },
  
      link: function (scope, element, attrs) {
  
          element.bind('focus', function () {
  
              var nextElement = element.parent().find('.openuserdialog').length;
  
              if (nextElement === 0) {
  
                  var btn = '&lt;img src="' + homePath + 'Images/zoomHS.png" ' +
                              'ng-click="userSearch.search()" ' +
                              'class="openuserdialog" /&gt;';
  
                  element.after($compile(btn)(scope));
  
              }
  
          });
      },
      controllerAs: 'userSearch'
  
  };
  
  };
  </code></pre>