0

I have been working with AngularJS for months. Today, I need to create a directive that will help me add a fix header to a table. All the directives I've found were not good enough because of the way they deal with the columns size (I'm still opened for propositions).

We use an "old" function made with jQuery and I am trying to convert it to a directive. The goal is, to clone the table (or the header of the table) and deals with hide/show functions and its position to get a good result.

My problem: the header of my table is dynamic with generated columns:

<table>
      <thead>
             <tr>
                  <th></th> // true th elements, used for styling my table
                  <th></th>
                  <th class='text-center' ng-repeat="thing in things">
                      {{thing.label}}
                  </th>
             </tr>
      </thead>
      <tbody>
          // my tbody
     </tbody>
</table>

I'm trying to get the <th> element in my directive with something like that :

angular.forEach(elem.querySelectorAll('tr:first-child th'), function    (thElem, i) {
        console.log(thElem)
        // do stuff here
    }
});

But I just get the two first <th> which are the "true" elements in my code. All others, generated by the ng-repeat are ignored. Or not injected in my directive.

I've looking around the transclude attribute but I could not find anything that works. Can you help me with some precision?

EDIT : Here is the beginning of my directive:

myApp.directive('fixMe', function ($window) {
     return {
       restrict: 'A',
       link: function (scope, element, attrs) {
          angular.forEach(element.querySelectorAll('th'), function (thElem, i) {
            console.log(thElem);
            var columnWidth = thElem.offsetWidth;
            thElem.style.width = columnWidth + 'px';
        });

       }
    };
})
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Thib
  • 25
  • 5
  • I'm not sure if I understand - you want to take everything inside `` and put it inside a directive? Can't you just put the code in a directive template? – Ozrix Apr 27 '16 at 21:15
  • My goal is to have a directive that will work with any table (no matter the number of rows, columns etc.). Can I do that with a template ? – Thib Apr 28 '16 at 08:20

2 Answers2

0

since your using ng-repeat, you could add a unique id, and then use vanilla js to get the element.

depends on what you want to do, if you want to handle changes on click, you might as well use ng-click on th elements and that way you can get the element by using function as: ng-click="doSomething($event)".

<table>
      <thead>
             <tr>
                  <th></th> // true th elements, used for styling my table
                  <th></th>
                  <th class='text-center' ng-repeat="thing in things track by $index" id="th_{{thing.id}}">
                      {{thing.label}}
                  </th>
             </tr>
      </thead>
      <tbody>
          // my tbody
     </tbody>
</table>

angular.forEach(things, function (thing) {
        var theElm = document.getElementById('th_'+thing.id);
        console.log(thElem)
        // do stuff here
    }
});
fayzaan
  • 265
  • 3
  • 9
  • As I've said in the previous comment, my goal is to have a directive that will work for any table. I can't rely on the scope, don't I ? – Thib Apr 28 '16 at 08:26
  • using ng-repeat does make it dynamic so that it works with any table. ng-repeat just duplicates the element until the end of the array. so if you have 3 items in an array, it'll create 3 tags with thing.label. You can do the same for the body, that way you have dynamic rows too. – fayzaan Apr 28 '16 at 21:57
0

I'm going to take a wild guess here, since I'm still not sure if this is what you want, but in order to get any collection of elements, you could use transclusion:

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

myApp.directive('tableCollector', function() {
    return {
    restrict: "A",
    transclude: true,
    link: function(scope, element, attrs, ctrl, $transclude) {
        $transclude(scope, function(clone){
            ... // do something with the element collection
        });
    }
  }
});

Demo (check out console log, the dynamically included <th> elements are in the tr.scope.cells object)

Ozrix
  • 3,489
  • 2
  • 17
  • 27