1

I am having a problem when I pass the ID through a directive. I can't obtain the element using jQuery inside the Link function, and the element is using the correct dynamic ID coming as parameter:

The Directive:

(function(angular) {
  var app = angular.module('pi.core');
  app.directive('piSearch', function() {
    return {
      restrict: 'E',
      transclude: true,
      replace: true,
      scope: {  
        idelement: '@'
      },
      link: function(scope, element, attrs, controller, transcludeFn) {
        var idelement = scope.idelement;

        console.log('idElement: ' + idelement);
        console.log($('#' + idelement + ' .typeahead'));
      },
      template: '<div id="{{idelement}}"></div>'
    };
  });
})(angular);

      var myApp = angular.module('piCore', []);

      myApp.directive("piSearch", function() {
        return {
          restrict: 'E',
          transclude: true,
          replace: true,
          scope: {  
            idelement: '@'
          },
          link: function(scope, element, attrs, controller, transcludeFn) {
            var idelement = scope.idelement;
  
  scope.elementSelected = $('#' + idelement + ' .typeahead');
            console.log('idElement: ' + idelement);
            console.log($('#' + idelement + ' .typeahead'));
          },
          template: '<div id="{{idelement}}"></div>'
        };
      });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body ng-app="piCore">
<pi-search></pi-search>
{{$scope.elementSelected}}
</body>

Any hints? Thanks in advance for your help!

Micky
  • 647
  • 1
  • 11
  • 26
  • Your snippet isn't **runnable**. Please update it so it runs and demonstrates the problem (or just use code blocks). More about doing shippets [here](https://meta.stackoverflow.com/questions/358992/ive-been-told-to-do-a-runnable-example-with-stack-snippets-how-do-i-do-tha). – T.J. Crowder Nov 20 '17 at 12:31
  • Separately: I suspect it would be worth reviewing [*“Thinking in AngularJS” if I have a jQuery background?*](https://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background?rq=1) – T.J. Crowder Nov 20 '17 at 12:32
  • T.J. thanks I will carefully read that article after solving this emergency – Micky Nov 20 '17 at 12:53

3 Answers3

1

try to use angular.element("#"+ idelement);

and also make sure this template: '<div id="{{idelement}}"></div>' is not generated multiple times

Ahmer
  • 94
  • 5
  • I am using my directive multiple times in my page, passing the id because I need to assign some styles to a specific element... It looks like angular.element doesn't work (selects the all page and length is not neither present) – Micky Nov 20 '17 at 13:16
  • why you are creating directive for implement styles you can easily handle with ng-class="{'class name':CONDITION}" – Ahmer Nov 20 '17 at 13:31
  • Because it is a directive which handle the twitter typeahead plugin with additional optimizations...something I can't add right now on ng-class, but I will check if I'll be able in the future... – Micky Nov 20 '17 at 17:02
1

I'll refactor your link function, remember angular has their own life cycle, and you need to make sure that your template compiles when your model has a value, wrap your logic in a watch

 app.directive('piSearch', function() {
    return {
      restrict: 'E',
      transclude: true,
      replace: true,
      scope: {  
        idelement: '@'
      },
      link: function(scope, element, attrs, controller, transcludeFn) {
        var idelement = scope.idelement;
        scope.$watch('idelement',function(){
            scope.elementSelected = $('#' + idelement + ' .typeahead');
            console.log('idElement: ' + idelement);
            console.log($('#' + idelement + ' .typeahead'));
         });
      },
      template: '<div id="{{idelement}}"></div>'
    };
  });
Jorge
  • 17,896
  • 19
  • 80
  • 126
  • Thanks Jorge, trying now... but scope (without $) goes to error because scope.watch is not a function, should I move to the controller?? – Micky Nov 20 '17 at 13:14
  • Hi, I made a mistake check the update is 'scope.$watch' and I strongly suggest to keep this logic in the directive `$watch` https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch – Jorge Nov 20 '17 at 13:16
0

One thing you must know regarding dynamic ID's and elements in global:

1) First you must generate your dynamic HTML inside javascript

2) Print it, append or just insert somwhere in the DOM

3) Now to can access to that new element you must use document to read that new element like this:

document.getElementById('new-generic-id');

or

$(document).on('click touchstart select', '#new-generic-id', function(){});

I hope you understand.

Ivijan Stefan Stipić
  • 6,249
  • 6
  • 45
  • 78
  • Thanks Ivijan. 1) am I already doing through the template in my directive right? 2) same as 1 3) in Link (right place?) querying with document.getElementById (variable name) I obtain null .... is there a way, even if as not elegant temporary workaround to do domething? I am using the directive multiple times in one page, so this is why I need to have different id... – Micky Nov 20 '17 at 12:51
  • BTW I am doing document.getElementById after $(document).ready(function(){ – Micky Nov 20 '17 at 12:52